Skip to content

Commit dbc126b

Browse files
committed
Add support of saving note revision and improve app start and stop procedure to ensure data integrity
1 parent 56b4739 commit dbc126b

7 files changed

Lines changed: 366 additions & 24 deletions

File tree

app.js

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -484,16 +484,26 @@ function startListen() {
484484
if (config.usessl) {
485485
server.listen(config.port, function () {
486486
logger.info('HTTPS Server listening at port %d', config.port);
487+
config.maintenance = false;
487488
});
488489
} else {
489490
server.listen(config.port, function () {
490491
logger.info('HTTP Server listening at port %d', config.port);
492+
config.maintenance = false;
491493
});
492494
}
493495
}
494496

495497
// sync db then start listen
496-
models.sequelize.sync().then(startListen);
498+
models.sequelize.sync().then(function () {
499+
// check if realtime is ready
500+
if (realtime.isReady()) {
501+
models.Revision.checkAllNotesRevision(function (err, notes) {
502+
if (err) return new Error(err);
503+
if (notes.length <= 0) return startListen();
504+
});
505+
}
506+
});
497507

498508
// log uncaught exception
499509
process.on('uncaughtException', function (err) {
@@ -510,21 +520,18 @@ process.on('SIGINT', function () {
510520
Object.keys(io.sockets.sockets).forEach(function (key) {
511521
var socket = io.sockets.sockets[key];
512522
// notify client server going into maintenance status
513-
socket.emit('maintenance', config.version);
523+
socket.emit('maintenance');
514524
socket.disconnect(true);
515525
});
516526
var checkCleanTimer = setInterval(function () {
517-
var usersCount = Object.keys(realtime.users).length;
518-
var notesCount = Object.keys(realtime.notes).length;
519-
// check if all users and notes array are empty
520-
if (usersCount == 0 && notesCount == 0) {
521-
// close db connection
522-
models.sequelize.close();
523-
clearInterval(checkCleanTimer);
524-
// wait for a while before exit
525-
setTimeout(function () {
526-
process.exit(0);
527-
}, 100);
527+
if (realtime.isReady()) {
528+
models.Revision.checkAllNotesRevision(function (err, notes) {
529+
if (err) return new Error(err);
530+
if (notes.length <= 0) {
531+
clearInterval(checkCleanTimer);
532+
return process.exit(0);
533+
}
534+
});
528535
}
529536
}, 100);
530537
});

lib/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ function getserverurl() {
7878
}
7979

8080
var version = '0.4.2';
81-
var maintenance = config.maintenance || false;
81+
var maintenance = true;
8282
var cwd = path.join(__dirname, '..');
8383

8484
module.exports = {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
module.exports = {
4+
up: function (queryInterface, Sequelize) {
5+
queryInterface.addColumn('Notes', 'savedAt', Sequelize.DATE);
6+
queryInterface.createTable('Revisions', {
7+
id: Sequelize.UUID,
8+
noteId: Sequelize.UUID,
9+
patch: Sequelize.TEXT,
10+
lastContent: Sequelize.TEXT,
11+
content: Sequelize.TEXT,
12+
length: Sequelize.INTEGER,
13+
createdAt: Sequelize.DATE,
14+
updatedAt: Sequelize.DATE
15+
});
16+
return;
17+
},
18+
19+
down: function (queryInterface, Sequelize) {
20+
queryInterface.dropTable('Revisions');
21+
queryInterface.removeColumn('Notes', 'savedAt');
22+
return;
23+
}
24+
};

lib/models/note.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ module.exports = function (sequelize, DataTypes) {
5252
},
5353
lastchangeAt: {
5454
type: DataTypes.DATE
55+
},
56+
savedAt: {
57+
type: DataTypes.DATE
5558
}
5659
}, {
5760
classMethods: {
@@ -66,6 +69,10 @@ module.exports = function (sequelize, DataTypes) {
6669
as: "lastchangeuser",
6770
constraints: false
6871
});
72+
Note.hasMany(models.Revision, {
73+
foreignKey: "noteId",
74+
constraints: false
75+
});
6976
},
7077
checkFileExist: function (filePath) {
7178
try {
@@ -100,11 +107,15 @@ module.exports = function (sequelize, DataTypes) {
100107
var dbModifiedTime = moment(note.lastchangeAt || note.createdAt);
101108
if (fsModifiedTime.isAfter(dbModifiedTime)) {
102109
var body = fs.readFileSync(filePath, 'utf8');
103-
note.title = LZString.compressToBase64(Note.parseNoteTitle(body));
104-
note.content = LZString.compressToBase64(body);
105-
note.lastchangeAt = fsModifiedTime;
106-
note.save().then(function (note) {
107-
return callback(null, note.id);
110+
note.update({
111+
title: LZString.compressToBase64(Note.parseNoteTitle(body)),
112+
content: LZString.compressToBase64(body),
113+
lastchangeAt: fsModifiedTime
114+
}).then(function (note) {
115+
sequelize.models.Revision.saveNoteRevision(note, function (err, revision) {
116+
if (err) return _callback(err, null);
117+
return callback(null, note.id);
118+
});
108119
}).catch(function (err) {
109120
return _callback(err, null);
110121
});
@@ -224,6 +235,11 @@ module.exports = function (sequelize, DataTypes) {
224235
}
225236
}
226237
return callback(null, note);
238+
},
239+
afterCreate: function (note, options, callback) {
240+
sequelize.models.Revision.saveNoteRevision(note, function (err, revision) {
241+
callback(err, note);
242+
});
227243
}
228244
}
229245
});

0 commit comments

Comments
 (0)