mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-19 01:35:18 -04:00
Added Types and reformating code
Signed-off-by: Yannick Bungers <git@innay.de> Signed-off-by: David Mehren <dmehren1@gmail.com>
This commit is contained in:
parent
84e021a0b0
commit
de09524658
1 changed files with 95 additions and 75 deletions
|
@ -1,9 +1,9 @@
|
||||||
import { BelongsTo, Column, DataType, ForeignKey, IsUUID, Model, PrimaryKey, Table } from 'sequelize-typescript'
|
import { BelongsTo, Column, DataType, ForeignKey, IsUUID, Model, PrimaryKey, Table } from 'sequelize-typescript'
|
||||||
import {ChildProcess} from "child_process";
|
import { ChildProcess } from 'child_process'
|
||||||
import { Note } from './note'
|
import { Note } from './note'
|
||||||
import {Utils} from "../utils";
|
import { Utils } from '../utils'
|
||||||
|
|
||||||
import Sequelize from "sequelize";
|
import Sequelize from 'sequelize'
|
||||||
import async = require('async');
|
import async = require('async');
|
||||||
import moment = require('moment');
|
import moment = require('moment');
|
||||||
import childProcess = require('child_process');
|
import childProcess = require('child_process');
|
||||||
|
@ -12,19 +12,25 @@ import path = require('path');
|
||||||
// core
|
// core
|
||||||
import logger = require('../logger');
|
import logger = require('../logger');
|
||||||
|
|
||||||
const Op = Sequelize.Op;
|
const Op = Sequelize.Op
|
||||||
|
|
||||||
let dmpWorker: ChildProcess | null = createDmpWorker();
|
const dmpCallbackCache = {}
|
||||||
const dmpCallbackCache = {};
|
|
||||||
|
|
||||||
function createDmpWorker() {
|
class Data {
|
||||||
const worker = childProcess.fork(path.resolve(__dirname, '../workers/dmpWorker.js'), ['ignore']);
|
msg;
|
||||||
logger.debug('dmp worker process started')
|
cacheKey;
|
||||||
worker.on('message', function (data: any) {
|
error;
|
||||||
if (!data || !data.msg || !data.cacheKey) {
|
result;
|
||||||
return logger.error('dmp worker error: not enough data on message')
|
|
||||||
}
|
}
|
||||||
const cacheKey = data.cacheKey;
|
|
||||||
|
function createDmpWorker (): ChildProcess {
|
||||||
|
const worker = childProcess.fork(path.resolve(__dirname, '../workers/dmpWorker.js'), ['ignore'])
|
||||||
|
logger.debug('dmp worker process started')
|
||||||
|
worker.on('message', function (data: Data) {
|
||||||
|
if (!data || !data.msg || !data.cacheKey) {
|
||||||
|
logger.error('dmp worker error: not enough data on message')
|
||||||
|
}
|
||||||
|
const cacheKey = data.cacheKey
|
||||||
switch (data.msg) {
|
switch (data.msg) {
|
||||||
case 'error':
|
case 'error':
|
||||||
dmpCallbackCache[cacheKey](data.error, null)
|
dmpCallbackCache[cacheKey](data.error, null)
|
||||||
|
@ -36,15 +42,18 @@ function createDmpWorker() {
|
||||||
delete dmpCallbackCache[cacheKey]
|
delete dmpCallbackCache[cacheKey]
|
||||||
})
|
})
|
||||||
worker.on('close', function (code) {
|
worker.on('close', function (code) {
|
||||||
dmpWorker = null;
|
|
||||||
logger.debug(`dmp worker process exited with code ${code}`)
|
logger.debug(`dmp worker process exited with code ${code}`)
|
||||||
})
|
})
|
||||||
return worker
|
return worker
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendDmpWorker(data, callback) {
|
let dmpWorker: ChildProcess = createDmpWorker()
|
||||||
if (!dmpWorker) dmpWorker = createDmpWorker()
|
|
||||||
const cacheKey = Date.now() + '_' + shortId.generate();
|
function sendDmpWorker (data, callback): void {
|
||||||
|
if (!dmpWorker?.connected) {
|
||||||
|
dmpWorker = createDmpWorker()
|
||||||
|
}
|
||||||
|
const cacheKey = Date.now() + '_' + shortId.generate()
|
||||||
dmpCallbackCache[cacheKey] = callback
|
dmpCallbackCache[cacheKey] = callback
|
||||||
data = Object.assign(data, {
|
data = Object.assign(data, {
|
||||||
cacheKey: cacheKey
|
cacheKey: cacheKey
|
||||||
|
@ -105,14 +114,18 @@ export class Revision extends Model<Revision> {
|
||||||
@BelongsTo(() => Note, { foreignKey: 'noteId', constraints: false, onDelete: 'CASCADE', hooks: true })
|
@BelongsTo(() => Note, { foreignKey: 'noteId', constraints: false, onDelete: 'CASCADE', hooks: true })
|
||||||
note: Note;
|
note: Note;
|
||||||
|
|
||||||
getNoteRevisions(note, callback) {
|
getNoteRevisions (note: Note, callback): void {
|
||||||
Revision.findAll({
|
Revision.findAll({
|
||||||
where: {
|
where: {
|
||||||
noteId: note.id
|
noteId: note.id
|
||||||
},
|
},
|
||||||
order: [['createdAt', 'DESC']]
|
order: [['createdAt', 'DESC']]
|
||||||
}).then(function (revisions) {
|
}).then(function (revisions) {
|
||||||
const data: any[] = [];
|
class RevisionDataActions { // TODO: Fix Type in actions.ts
|
||||||
|
time;
|
||||||
|
length
|
||||||
|
}
|
||||||
|
const data: RevisionDataActions[] = []
|
||||||
revisions.forEach(function (revision) {
|
revisions.forEach(function (revision) {
|
||||||
data.push({
|
data.push({
|
||||||
time: moment(revision.createdAt).valueOf(),
|
time: moment(revision.createdAt).valueOf(),
|
||||||
|
@ -125,7 +138,7 @@ export class Revision extends Model<Revision> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getPatchedNoteRevisionByTime(note, time, callback) {
|
getPatchedNoteRevisionByTime (note: Note, time, errorCallback): void {
|
||||||
// find all revisions to prepare for all possible calculation
|
// find all revisions to prepare for all possible calculation
|
||||||
Revision.findAll({
|
Revision.findAll({
|
||||||
where: {
|
where: {
|
||||||
|
@ -133,7 +146,9 @@ export class Revision extends Model<Revision> {
|
||||||
},
|
},
|
||||||
order: [['createdAt', 'DESC']]
|
order: [['createdAt', 'DESC']]
|
||||||
}).then(function (revisions) {
|
}).then(function (revisions) {
|
||||||
if (revisions.length <= 0) return callback(null, null)
|
if (revisions.length <= 0) {
|
||||||
|
errorCallback(null, null)
|
||||||
|
}
|
||||||
// measure target revision position
|
// measure target revision position
|
||||||
Revision.count({
|
Revision.count({
|
||||||
where: {
|
where: {
|
||||||
|
@ -141,34 +156,38 @@ export class Revision extends Model<Revision> {
|
||||||
createdAt: {
|
createdAt: {
|
||||||
[Op.gte]: time
|
[Op.gte]: time
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}).then(function (count) {
|
}).then(function (count) {
|
||||||
if (count <= 0) return callback(null, null)
|
if (count <= 0) {
|
||||||
|
errorCallback(null, null)
|
||||||
|
}
|
||||||
sendDmpWorker({
|
sendDmpWorker({
|
||||||
msg: 'get revision',
|
msg: 'get revision',
|
||||||
revisions: revisions,
|
revisions: revisions,
|
||||||
count: count
|
count: count
|
||||||
}, callback)
|
}, errorCallback)
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
errorCallback(err, null)
|
||||||
})
|
})
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
errorCallback(err, null)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static checkAllNotesRevision(callback) {
|
static checkAllNotesRevision (callback): void {
|
||||||
Revision.saveAllNotesRevision(function (err, notes) {
|
Revision.saveAllNotesRevision(function (err, notes: Note[]) {
|
||||||
if (err) return callback(err, null)
|
if (err) {
|
||||||
|
callback(err, null)
|
||||||
|
}
|
||||||
if (!notes || notes.length <= 0) {
|
if (!notes || notes.length <= 0) {
|
||||||
return callback(null, notes)
|
callback(null, notes)
|
||||||
} else {
|
} else {
|
||||||
Revision.checkAllNotesRevision(callback)
|
Revision.checkAllNotesRevision(callback)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static saveAllNotesRevision(callback) {
|
static saveAllNotesRevision (callback): void {
|
||||||
Note.findAll({
|
Note.findAll({
|
||||||
// query all notes that need to save for revision
|
// query all notes that need to save for revision
|
||||||
where: {
|
where: {
|
||||||
|
@ -195,13 +214,15 @@ export class Revision extends Model<Revision> {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}).then(function (notes: Note[]) {
|
}).then(function (notes: Note[]) {
|
||||||
if (notes.length <= 0) return callback(null, notes)
|
if (notes.length <= 0) {
|
||||||
const savedNotes: Note[] = [];
|
callback(null, notes)
|
||||||
|
}
|
||||||
|
const savedNotes: Note[] = []
|
||||||
async.each(notes, function (note: Note, _callback) {
|
async.each(notes, function (note: Note, _callback) {
|
||||||
// revision saving policy: note not been modified for 5 mins or not save for 10 mins
|
// revision saving policy: note not been modified for 5 mins or not save for 10 mins
|
||||||
if (note.lastchangeAt && note.savedAt) {
|
if (note.lastchangeAt && note.savedAt) {
|
||||||
const lastchangeAt = moment(note.lastchangeAt);
|
const lastchangeAt = moment(note.lastchangeAt)
|
||||||
const savedAt = moment(note.savedAt);
|
const savedAt = moment(note.savedAt)
|
||||||
if (moment().isAfter(lastchangeAt.add(5, 'minutes'))) {
|
if (moment().isAfter(lastchangeAt.add(5, 'minutes'))) {
|
||||||
savedNotes.push(note)
|
savedNotes.push(note)
|
||||||
Revision.saveNoteRevision(note, _callback)
|
Revision.saveNoteRevision(note, _callback)
|
||||||
|
@ -209,7 +230,7 @@ export class Revision extends Model<Revision> {
|
||||||
savedNotes.push(note)
|
savedNotes.push(note)
|
||||||
Revision.saveNoteRevision(note, _callback)
|
Revision.saveNoteRevision(note, _callback)
|
||||||
} else {
|
} else {
|
||||||
return _callback(null, null)
|
_callback(null, null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
savedNotes.push(note)
|
savedNotes.push(note)
|
||||||
|
@ -217,59 +238,61 @@ export class Revision extends Model<Revision> {
|
||||||
}
|
}
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err, null)
|
callback(err, null)
|
||||||
}
|
}
|
||||||
// return null when no notes need saving at this moment but have delayed tasks to be done
|
// return null when no notes need saving at this moment but have delayed tasks to be done
|
||||||
const result = ((savedNotes.length === 0) && (notes.length > 0)) ? null : savedNotes;
|
const result = ((savedNotes.length === 0) && (notes.length > 0)) ? null : savedNotes
|
||||||
return callback(null, result)
|
callback(null, result)
|
||||||
})
|
})
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
callback(err, null)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static saveNoteRevision(note : Note, callback) {
|
static saveNoteRevision (note: Note, callback): void {
|
||||||
Revision.findAll({
|
Revision.findAll({
|
||||||
where: {
|
where: {
|
||||||
noteId: note.id
|
noteId: note.id
|
||||||
},
|
},
|
||||||
order: [['createdAt', 'DESC']]
|
order: [['createdAt', 'DESC']]
|
||||||
}).then(function (revisions) {
|
}).then(function (revisions: Revision[]) {
|
||||||
if (revisions.length <= 0) {
|
if (revisions.length <= 0) {
|
||||||
// if no revision available
|
// if no revision available
|
||||||
let noteContent = note.content;
|
let noteContent = note.content
|
||||||
if (noteContent.length === 0) {
|
if (noteContent.length === 0) {
|
||||||
noteContent = '';
|
noteContent = ''
|
||||||
}
|
}
|
||||||
Revision.create({
|
Revision.create({
|
||||||
noteId: note.id,
|
noteId: note.id,
|
||||||
lastContent: noteContent,
|
lastContent: noteContent,
|
||||||
length: noteContent.length,
|
length: noteContent.length,
|
||||||
authorship: note.authorship
|
authorship: note.authorship
|
||||||
}).then(function (revision) {
|
}).then(function (revision: Revision) {
|
||||||
Revision.finishSaveNoteRevision(note, revision, callback)
|
Revision.finishSaveNoteRevision(note, revision, callback)
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
callback(err, null)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const latestRevision = revisions[0];
|
const latestRevision = revisions[0]
|
||||||
const lastContent = latestRevision.content || latestRevision.lastContent;
|
const lastContent = latestRevision.content || latestRevision.lastContent
|
||||||
const content = note.content;
|
const content = note.content
|
||||||
sendDmpWorker({
|
sendDmpWorker({
|
||||||
msg: 'create patch',
|
msg: 'create patch',
|
||||||
lastDoc: lastContent,
|
lastDoc: lastContent,
|
||||||
currDoc: content
|
currDoc: content
|
||||||
}, function (err, patch) {
|
}, function (err, patch) {
|
||||||
if (err) logger.error('save note revision error', err)
|
if (err) {
|
||||||
|
logger.error('save note revision error', err)
|
||||||
|
}
|
||||||
if (!patch) {
|
if (!patch) {
|
||||||
// if patch is empty (means no difference) then just update the latest revision updated time
|
// if patch is empty (means no difference) then just update the latest revision updated time
|
||||||
latestRevision.changed('updatedAt', true)
|
latestRevision.changed('updatedAt', true)
|
||||||
latestRevision.update({
|
latestRevision.update({
|
||||||
updatedAt: Date.now()
|
updatedAt: Date.now()
|
||||||
}).then(function (revision) {
|
}).then(function (revision: Revision) {
|
||||||
Revision.finishSaveNoteRevision(note, revision, callback)
|
Revision.finishSaveNoteRevision(note, revision, callback)
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
callback(err, null)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Revision.create({
|
Revision.create({
|
||||||
|
@ -278,36 +301,33 @@ export class Revision extends Model<Revision> {
|
||||||
content: note.content,
|
content: note.content,
|
||||||
length: note.content.length,
|
length: note.content.length,
|
||||||
authorship: note.authorship
|
authorship: note.authorship
|
||||||
}).then(function (revision) {
|
}).then(function (revision: Revision) {
|
||||||
// clear last revision content to reduce db size
|
// clear last revision content to reduce db size
|
||||||
latestRevision.update({
|
latestRevision.update({
|
||||||
content: null
|
content: null
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
Revision.finishSaveNoteRevision(note, revision, callback)
|
Revision.finishSaveNoteRevision(note, revision, callback)
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
callback(err, null)
|
||||||
})
|
})
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
callback(err, null)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
callback(err, null)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static finishSaveNoteRevision(note, revision, callback) {
|
static finishSaveNoteRevision (note: Note, revision: Revision, callback): void {
|
||||||
note.update({
|
note.update({
|
||||||
savedAt: revision.updatedAt
|
savedAt: revision.updatedAt
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
return callback(null, revision)
|
callback(null, revision)
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
return callback(err, null)
|
callback(err, null)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue