Skip to content

Commit

Permalink
Merge pull request #3 from SSTIA/master
Browse files Browse the repository at this point in the history
merge upstream
  • Loading branch information
arsdragonfly authored Jan 25, 2018
2 parents ed7d219 + 7fcab32 commit 7f77449
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 38 deletions.
3 changes: 3 additions & 0 deletions services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,6 @@ handlers:
- webServer
- webSocket
- logger

system:
path: system
10 changes: 8 additions & 2 deletions src/handlers/manage.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ export default class Handler {
@web.get('/test_match')
async testMatch(req, res) {
const u1 = await DI.models.User.getHighestPriorityAsync();
if (u1 === null) return;
if (u1 === null) {
res.send('No user with priority > 0 found.');
return;
}
const u2 = await DI.models.User.getBestOpponentAsync(u1, u1.match.streak >=
0);
if (u2 === null) return;
if (u2 === null) {
res.send(`No opponent of ${u1._id} found.`);
return;
}
await DI.models.Match.createMatchAsync(u1, u2);
//console.log(u1, u2);
res.send({
Expand Down
3 changes: 3 additions & 0 deletions src/handlers/submission.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export default class Handler {
SUBMISSIONS_PER_PAGE
);
await DI.models.User.populate(sdocs, 'user');
await DI.models.Rating.populate(sdocs, 'endRating');
res.render('submission_all', {
page_title: 'All Submissions',
sdocs,
Expand All @@ -179,6 +180,7 @@ export default class Handler {
SUBMISSIONS_PER_PAGE
);
await DI.models.User.populate(sdocs, 'user');
await DI.models.Rating.populate(sdocs, 'endRating');
res.render('submission_my', {
page_title: 'My Submissions',
sdocs,
Expand All @@ -201,6 +203,7 @@ export default class Handler {
SUBMISSIONS_PER_PAGE
);
await DI.models.User.populate(sdocs, 'user');
await DI.models.Rating.populate(sdocs, 'endRating');
res.render('submission_all', {
page_title: 'User Submissions',
udoc,
Expand Down
23 changes: 23 additions & 0 deletions src/models/match.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,14 @@ export default function() {
MatchSchema.statics.ROUND_STATUS_TEXT = MatchSchema.statics.STATUS_TEXT;

MatchSchema.pre('save', function(next) {
if (!DI.system.initialized) next();
this.__lastIsNew = this.isNew;
this.__lastModifiedPaths = this.modifiedPaths();
next();
});

MatchSchema.post('save', function() {
if (!DI.system.initialized) return;
const mdoc = this.toObject();
Promise.all([
(async () => {
Expand Down Expand Up @@ -233,6 +235,7 @@ export default function() {
u1Black,
u2Black: !u1Black,
openingId: String(openingId),
usedTime: 0,
});
}
}
Expand Down Expand Up @@ -575,6 +578,26 @@ export default function() {
}).sort({_id: -1}).exec();
};

MatchSchema.statics.getExceptionMatchAsync = async function() {
return Match.getActiveMatchesAsync();
};

MatchSchema.methods.resetExceptionAsync = async function() {
this.status = Match.STATUS_SYSTEM_ERROR;
_.forEach(this.rounds, rdoc => {
if (rdoc.status === Match.STATUS_PENDING ||
rdoc.status === Match.STATUS_RUNNING) {
rdoc.status = Match.STATUS_SYSTEM_ERROR;
rdoc.summary = JSON.stringify({
exitCausedBy: 'System error',
usedTime: 0,
});
}
});
await this.save();
// create a new match of same players here.
};

/**
* Update status of all matches
*/
Expand Down
10 changes: 10 additions & 0 deletions src/models/rating.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,16 @@ export default function() {
await this.save();
};

RatingSchema.statics.getExceptionRatingAsync = async function() {
return await Rating.find({
status: Rating.STATUS_PENDING,
}).exec();
};

RatingSchema.methods.resetExceptionAsync = async function () {
await this.setErrorAsync();
};

//RatingSchema.index({ userName_std: 1 }, { unique: true });

Rating = mongoose.model('Rating', RatingSchema);
Expand Down
58 changes: 52 additions & 6 deletions src/models/submission.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import _ from 'lodash';
import aigle from 'aigle';
import fsp from 'fs-promise';
import uuid from 'uuid';
import moment from 'moment';
Expand All @@ -25,6 +26,9 @@ export default () => {
startRating: {type: mongoose.Schema.Types.ObjectId, ref: 'Rating'},
endRating: {type: mongoose.Schema.Types.ObjectId, ref: 'Rating'},
matchLogCleared: Boolean,
win: Number,
lose: Number,
draw: Number,
}, {
timestamps: true,
toObject: {virtuals: true},
Expand Down Expand Up @@ -59,12 +63,14 @@ export default () => {
};

SubmissionSchema.pre('save', function(next) {
if (!DI.system.initialized) next();
this.__lastIsNew = this.isNew;
this.__lastModifiedPaths = this.modifiedPaths();
next();
});

SubmissionSchema.post('save', function() {
if (!DI.system.initialized) return;
const sdoc = this.toObject();
Promise.all([
(async () => {
Expand All @@ -85,6 +91,14 @@ export default () => {
]);
});

const compileTaskQueue = [];

DI.eventBus.on('system.started', async () => {
aigle.forEach(compileTaskQueue, async data => {
await Submission.publishCompileTaskAsync(data);
});
});

/**
* Update the submission status one by one when match status is updated
*/
Expand Down Expand Up @@ -164,11 +178,20 @@ export default () => {
};

SubmissionSchema.methods.resetExceptionAsync = async function() {


if (this.status === Submission.STATUS_RUNNING) {
// reset state to effective
this.status = Submission.STATUS_EFFECTIVE;
// reset state
const mdoc = await DI.models.Match.getMatchObjectByIdAsync(
_.last(this.matches));
if (!DI.models.Match.isFinishStatus(mdoc.status)) {
throw new Error(
`Match ${mdoc._id} status unexpected in Submission ${this._id}`);
}
const sdoc = await Submission.getLastSubmissionByUserAsync(this.user);
if (sdoc.equals(this)) {
this.status = Submission.STATUS_EFFECTIVE;
} else {
this.status = Submission.STATUS_INACTIVE;
}
await this.save();
} else if (this.status === Submission.STATUS_PENDING ||
this.status === Submission.STATUS_COMPILING) {
Expand Down Expand Up @@ -314,12 +337,25 @@ export default () => {
sdoc.text = '';
sdoc.taskToken = uuid.v4();
await sdoc.save();
await DI.mq.publish('compile', {
const mqData = {
sdocid: String(sdoc._id),
token: sdoc.taskToken,
};
if (DI.system.initialized) {
await Submission.publishCompileTaskAsync(mqData);
} else {
compileTaskQueue.push(mqData);
}
return sdoc;
};

SubmissionSchema.statics.publishCompileTaskAsync = async function(
{sdocid, token}) {
await DI.mq.publish('compile', {
sdocid,
token,
limits: DI.config.compile.limits,
});
return sdoc;
};

/**
Expand Down Expand Up @@ -583,11 +619,21 @@ export default () => {
const mdoc = await DI.models.Match.getMatchObjectByIdAsync(
_.last(this.matches));
if (DI.models.Match.isFinishStatus(mdoc.status)) {
const relativeStatus = DI.models.Match.getRelativeStatus(
mdoc.status, mdoc.u1 === this.user);
if (relativeStatus === DI.models.Match.RELATIVE_STATUS_WIN) {
this.win++;
} else if (relativeStatus === DI.models.Match.RELATIVE_STATUS_LOSE) {
this.lose++;
} else if (relativeStatus === DI.models.Match.STATUS_DRAW) {
this.draw++;
}
await Submission.incrUsedSubmissionQuotaAsync(this.user, mdoc.usedTime);
const sdoc = await Submission.getLastSubmissionByUserAsync(this.user);
// if the submission isn't last effective submission, set it to inactive
if (sdoc.equals(this)) {
this.status = Submission.STATUS_EFFECTIVE;
await DI.models.User.setMatchPriorityInitialAsync(this.user);
} else {
this.status = Submission.STATUS_INACTIVE;
}
Expand Down
25 changes: 21 additions & 4 deletions src/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,27 +428,44 @@ export default () => {
};

UserSchema.statics.getHighestPriorityAsync = async function() {
return await this.findOne({
return await User.findOne({
'match.priority': {$gt: 0},
}).sort({'match.priority': -1}).exec();
};

UserSchema.statics.getBestOpponentAsync = async function (u1, higher) {
UserSchema.statics.getBestOpponentAsync = async function(u1, higher) {
if (higher) {
return await this.findOne({
return await User.findOne({
'match.priority': {$gt: 0},
'_id': {$ne: u1._id},
//'rating.score': {$gte: u1.rating.score},
}).sort({'rating.score': 1}).exec();
} else {
return await this.findOne({
return await User.findOne({
'match.priority': {$gt: 0},
'_id': {$ne: u1._id},
//'rating.score': {$lte: u1.rating.score},
}).sort({'rating.score': -1}).exec();
}
};

UserSchema.statics.getExceptionUserAsync = async function() {
return await User.find({
'match.priority': {$lte: 0},
'submission': {$ne: null},
}).exec();
};

UserSchema.methods.resetExceptionAsync = async function() {
const sdoc = await DI.models.Submission.getLastSubmissionByUserAsync(this._id);
if (sdoc) {
this.match.priority = Math.abs(this.match.streak * this.match.change) + 1;
} else {
this.match.priority = 0;
}
await this.save();
};

UserSchema.index({userName_std: 1}, {unique: true});

User = mongoose.model('User', UserSchema);
Expand Down
10 changes: 7 additions & 3 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ process.env.SUPPRESS_NO_CONFIG_WARNING = true;

global.DI = application.DI;

application.start().
then(() => DI.eventBus.emitAsyncWithProfiling('system.started')).
catch(e => console.log(e.stack));
try {
await application.start();
await DI.system.init();
DI.eventBus.emitAsyncWithProfiling('system.started');
} catch (e) {
console.log(e.stack);
}

})();
2 changes: 1 addition & 1 deletion src/services/mongodb.connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default async (logger) => {

const db = await new Promise((resolve, reject) => {
logger.debug(`MongoDB: Connection Url = ${DI.config.db}`);
mongoose.connect(DI.config.db, {useMongoClient: true});
mongoose.connect(DI.config.db);
const db = mongoose.connection;
db.on('error', () => {
reject(new Error(`unable to connect to database at ${DI.config.db}`));
Expand Down
66 changes: 49 additions & 17 deletions src/services/system.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,67 @@
import _ from 'lodash';
import aigle from 'aigle';

export default async () => {

const system = {
initialized: false,
init: async () => {
system.initialized = false;
await DI.model.sys.setAsync('readonly', true);

const sdocs = await DI.models.getExceptionSubmissionAsync();
_.forEach(sdocs, sdoc => {

});

system.initialized = true;
await DI.model.sys.setAsync('readonly', false);
},
const initModel = async function(name) {
const model = DI.models[name];
if (!model) {
throw new Error(`Model ${name} doesn't exist!`);
}
const func = model[`getException${name}Async`];
if (!func) {
throw new Error(`Model ${name} doesn't have getException function!`);
}
const docs = await func();
await aigle.forEach(docs, async doc => {
DI.logger.info(`Fixing ${name} Object ${doc._id}`);
await doc.resetExceptionAsync();
});
};

let readyExit = false;
process.on('SIGINT', async () => {
const onExit = async function () {
DI.logger.info('Server received SIGINT, exiting');
if (!readyExit) {
readyExit = true;
await DI.model.sys.setAsync('readonly', true);
await DI.models.Sys.setAsync('readonly', true);
await DI.models.Sys.setAsync('lock_submission', true);
await DI.models.Sys.setAsync('lock_submission_reason', 'System rebooting');
setInterval(async () => {
// waiting for all process ending
process.exit(0);
}, 1000);
}
});
};

const system = {
initialized: false,
init: async () => {
DI.logger.info('Initialization started');
system.initialized = false;
await DI.models.Sys.setAsync('readonly', true);
await DI.models.Sys.setAsync('lock_submission', true);
await DI.models.Sys.setAsync('lock_submission_reason', 'System initializing');

try {
await initModel('Rating');
await initModel('Match');
await initModel('Submission');
await initModel('User');
} catch (e) {
DI.logger.error(e.stack);
DI.logger.info('Initialization failed!');
process.exit(-1);
}

await DI.models.Sys.setAsync('lock_submission', false);
await DI.models.Sys.setAsync('readonly', false);
system.initialized = true;
DI.logger.info('Initialization succeeded');

process.on('SIGINT', onExit);
},
};

return system;
};
Expand Down
Loading

0 comments on commit 7f77449

Please sign in to comment.