解离sandbox模块,完善迁移工具

This commit is contained in:
masnn committed 2020-05-16 14:03:53 +08:00
1 parent 42cbd020d5
commit 2d2b2930f0
6 files changed
+106 -77

No files matched your search

+20
View File
@@ -195,6 +195,25 @@ async function service() {
} }
} }
async function script() {
for (const i of active) {
if (i.script && !i.fail) {
try {
console.time(`Script init: ${i.id}`);
const exports = {};
const module = { exports }; // eslint-disable-line no-unused-vars
eval(i.script);
console.timeEnd(`Script init: ${i.id}`);
} catch (e) {
i.fail = true;
fail.push(i.id);
console.error(`Script Load Fail: ${i.id}`);
console.error(e);
}
}
}
}
async function install() { async function install() {
const setup = require('./service/setup'); const setup = require('./service/setup');
await setup.setup(); await setup.setup();
@@ -279,6 +298,7 @@ async function load() {
for (const i in global.Hydro.service) { for (const i in global.Hydro.service) {
if (global.Hydro.service[i].postInit) await global.Hydro.service[i].postInit(); if (global.Hydro.service[i].postInit) await global.Hydro.service[i].postInit();
} }
await script();
await server.start(); await server.start();
} }
+10 -1
View File
@@ -8,6 +8,7 @@ const db = require('../service/db.js');
const coll = db.collection('discussion'); const coll = db.collection('discussion');
const collReply = db.collection('discussion.reply'); const collReply = db.collection('discussion.reply');
const collStatus = db.collection('discussion.status'); const collStatus = db.collection('discussion.status');
const collNode = db.collection('discussion.node');
async function add(parentType, parentId, owner, title, content, ip = null, highlight = false) { async function add(parentType, parentId, owner, title, content, ip = null, highlight = false) {
const res = await coll.insertOne({ const res = await coll.insertOne({
@@ -132,6 +133,10 @@ function getStatus(did, uid) {
return collStatus.findOne({ did, uid }); return collStatus.findOne({ did, uid });
} }
function getNode(_id) {
return collNode.findOne({ _id });
}
async function getVnode(ddoc, handler) { async function getVnode(ddoc, handler) {
if (ddoc.parentType === 'problem') { if (ddoc.parentType === 'problem') {
const pdoc = await problem.getById(ddoc.parentId); const pdoc = await problem.getById(ddoc.parentId);
@@ -141,7 +146,11 @@ async function getVnode(ddoc, handler) {
} if (ddoc.parentType === 'contest') { } if (ddoc.parentType === 'contest') {
const tdoc = await contest.get(ddoc.parentId); const tdoc = await contest.get(ddoc.parentId);
return { ...tdoc, parentType: ddoc.parentType, parentId: ddoc.parentId }; return { ...tdoc, parentType: ddoc.parentType, parentId: ddoc.parentId };
} return null; } if (ddoc.parentType === 'node') {
const ndoc = await getNode(ddoc.parentId);
return { ...ndoc, parentType: ddoc.parentType, parentId: ddoc.parentId };
}
return null;
} }
async function getListVnodes(ddocs, handler) { async function getListVnodes(ddocs, handler) {
+76 -33
View File
@@ -1,7 +1,16 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
const { mongodb, bson } = global.Hydro.nodeModules; const { mongodb } = global.Hydro.nodeModules;
const dst = global.Hydro.service.db; const dst = global.Hydro.service.db;
const { problem } = global.Hydro.model.problem; const { problem } = global.Hydro.model;
const map = {};
const pid = (id) => {
if (map[id.toString()]) return map[id.toString()];
if (id.generationTime) return id;
id = id.toString();
return id;
};
const tasks = { const tasks = {
user: async (docs) => docs.map((doc) => ({ user: async (docs) => docs.map((doc) => ({
@@ -26,27 +35,39 @@ const tasks = {
gender: doc.gender, gender: doc.gender,
qq: doc.qq, qq: doc.qq,
})), })),
problem: async (docs) => docs.map((doc) => ({ problem: async (docs) => {
_id: doc._id, const problems = [];
pid: doc.pname || doc.doc_id.toString() || new bson.ObjectID(), for (const doc of docs) {
title: doc.title, if (doc.pname) map[doc.doc_id.toString()] = doc.pname;
content: doc.content, problems.push({
owner: doc.owner_uid, _id: doc._id,
data: doc.data, pid: doc.pname || pid(doc.doc_id),
category: doc.category, title: doc.title,
tag: doc.tag, content: doc.content,
nSubmit: doc.num_submit, owner: doc.owner_uid,
nAccept: doc.num_accept, data: doc.data,
})), category: doc.category,
tag: doc.tag,
nSubmit: doc.num_submit,
nAccept: doc.num_accept,
hidden: doc.hidden || false,
});
}
return problems;
},
'problem.status': async (docs) => { 'problem.status': async (docs) => {
const problems = []; const problems = [];
for (const doc of docs) { for (const doc of docs) {
problems.push({ try {
pid: await problem.get(doc.pid), problems.push({
rid: doc.rid, pid: await problem.get(pid(doc.doc_id)),
uid: doc.uid, rid: doc.rid,
status: doc.status, uid: doc.uid,
}); status: doc.status,
});
} catch (e) {
// Ignore
}
} }
return problems; return problems;
}, },
@@ -58,7 +79,7 @@ const tasks = {
content: r.content, content: r.content,
_id: r._id, _id: r._id,
})); }));
const pdoc = await problem.get(doc.parent_doc_id.toString()); const pdoc = await problem.get(pid(doc.parent_doc_id));
solutions.push({ solutions.push({
_id: doc._id, _id: doc._id,
owner: doc.owner_uid, owner: doc.owner_uid,
@@ -102,12 +123,16 @@ const tasks = {
parentId: doc.parent_doc_id, parentId: doc.parent_doc_id,
})), })),
contest: async (docs) => { contest: async (docs) => {
const RULES = ['oi', 'acm', 'homework']; const RULES = {
2: 'oi',
3: 'acm',
11: 'homework',
};
const contests = []; const contests = [];
for (const doc of docs) { for (const doc of docs) {
const pids = []; const pids = [];
for (const pid of doc.pids) { for (const p of doc.pids) {
const pdoc = await problem.get(pid.toString()); const pdoc = await problem.get(pid(p));
pids.push(pdoc._id); pids.push(pdoc._id);
} }
contests.push({ contests.push({
@@ -130,8 +155,8 @@ const tasks = {
const dag = []; const dag = [];
for (const t of doc.dag) { for (const t of doc.dag) {
const pids = []; const pids = [];
for (const pid of t.pids) { for (const p of t.pids) {
const pdoc = await problem.get(pid.toString()); const pdoc = await problem.get(pid(p));
pids.push(pdoc._id); pids.push(pdoc._id);
} }
dag.push({ dag.push({
@@ -153,6 +178,8 @@ const tasks = {
} }
return trainings; return trainings;
}, },
'fs.files': async (docs) => docs,
'fs.chunks': async (docs) => docs,
}; };
const cursor = { const cursor = {
@@ -164,6 +191,8 @@ const cursor = {
'discussion.reply': (s) => s.collection('document').find({ doc_type: 22 }), 'discussion.reply': (s) => s.collection('document').find({ doc_type: 22 }),
contest: (s) => s.collection('document').find({ doc_type: 30 }), contest: (s) => s.collection('document').find({ doc_type: 30 }),
training: (s) => s.collection('document').find({ doc_type: 40 }), training: (s) => s.collection('document').find({ doc_type: 40 }),
'fs.files': (s) => s.collection('fs.files').find(),
'fs.chunks': (s) => s.collection('fs.chunks').find(),
}; };
async function task(name, src, report) { async function task(name, src, report) {
@@ -172,8 +201,9 @@ async function task(name, src, report) {
const total = Math.floor(count / 50); const total = Math.floor(count / 50);
for (let i = 0; i <= total; i++) { for (let i = 0; i <= total; i++) {
const docs = await cursor[name](src).skip(i * 50).limit(50).toArray(); const docs = await cursor[name](src).skip(i * 50).limit(50).toArray();
await dst.collection(name).insertMany(await tasks[name](docs)); const t = await tasks[name](docs);
await report({ progress: Math.round(100 * (i / total)) }); if (t.length) await dst.collection(name).insertMany(t);
await report({ progress: Math.round(100 * ((i + 1) / (total + 1))) });
} }
} }
@@ -188,14 +218,27 @@ async function migrateVijos({
}); });
const src = Database.db(name); const src = Database.db(name);
await report({ progress: 0, message: 'Database connected.' }); await report({ progress: 0, message: 'Database connected.' });
await dst.collection('system').insertOne({ await dst.collection('system').updateOne(
_id: 'user', { _id: 'user' },
value: (await src.collection('system').findOne({ _id: 'user_counter' })).value, {
}); $set: {
value: (await src.collection('system').findOne({ _id: 'user_counter' })).value,
},
},
{ upsert: true },
);
await report({ progress: 1, message: 'Collection:system done.' }); await report({ progress: 1, message: 'Collection:system done.' });
await dst.collection('user').deleteMany({ _id: { $nin: [0, 1] } });
const d = [
'problem', 'problem.status', 'solution', 'discussion',
'discussion.reply', 'contest', 'training', 'fs.files', 'fs.chunks',
];
for (const i of d) {
await dst.collection(i).deleteMany();
}
const t = [ const t = [
'user', 'problem', 'problem.status', 'solution', 'discussion', 'user', 'problem', 'problem.status', 'solution', 'discussion',
'discussion.reply', 'contest', 'training', 'discussion.reply', 'contest', 'training', 'fs.files', 'fs.chunks',
]; ];
for (const i of t) await task(i, src, report); for (const i of t) await task(i, src, report);
} }
-11
View File
@@ -1,11 +0,0 @@
const fs = require('fs');
const path = require('path');
exports.prebuild = async function prebuild() {
if (!fs.existsSync(path.resolve(__dirname, 'file', 'executorserver'))) {
if (!fs.existsSync(path.resolve(__dirname, 'file'))) {
fs.mkdirSync(path.resolve(__dirname, 'file'));
}
// TODO download executorserver
}
};
-8
View File
@@ -1,8 +0,0 @@
{
"name": "sandbox-linux",
"version": "1.0.0",
"os": [
"linux"
],
"description": "Sandbox service for linux"
}
-24
View File
@@ -1,24 +0,0 @@
const os = require('os');
const path = require('path');
const child = require('child_process');
const p = child.spawn(path.resolve(os.tmpdir(), 'hydro', 'sandbox-linux-amd64', 'executorserver'), ['-silent']);
if (!p.stdout) throw new Error('Cannot start executorserver');
else {
p.stdout.on('data', (data) => {
const s = data.toString();
console.log(s.substr(0, s.length - 1));
});
p.stderr.on('data', (data) => {
const s = data.toString();
console.log(s.substr(0, s.length - 1));
});
}
p.on('error', (error) => console.error(error));
async function stop() {
p.emit('exit');
}
module.exports = { stop };