diff --git a/server/core/kernel.js b/server/core/kernel.js index a5688936..0b1c8850 100644 --- a/server/core/kernel.js +++ b/server/core/kernel.js @@ -1,4 +1,5 @@ const _ = require('lodash') +const EventEmitter = require('events') /* global WIKI */ @@ -23,6 +24,8 @@ module.exports = { await WIKI.models.onReady await WIKI.configSvc.loadFromDb() await WIKI.queue.clean() + WIKI.events = new EventEmitter() + WIKI.redisSub = require('./redis').subscribe() } catch (err) { WIKI.logger.error(err) process.exit(1) diff --git a/server/core/localization.js b/server/core/localization.js index 8f3ef9c5..53525d7b 100644 --- a/server/core/localization.js +++ b/server/core/localization.js @@ -33,6 +33,15 @@ module.exports = { // Load current language + namespaces this.refreshNamespaces(true) + // Listen for localization events + WIKI.events.on('localization', (action) => { + switch (action) { + case 'reload': + this.refreshNamespaces() + break + } + }) + return this }, attachMiddleware (app) { diff --git a/server/core/queue.js b/server/core/queue.js index 8f0189b7..6b76ef55 100644 --- a/server/core/queue.js +++ b/server/core/queue.js @@ -36,6 +36,11 @@ module.exports = { } }) }, + async quit() { + for (const queueName in this.job) { + await this.job[queueName].close() + } + }, async clean() { return Promise.each(_.keys(WIKI.data.jobs), queueName => { return new Promise((resolve, reject) => { diff --git a/server/core/redis.js b/server/core/redis.js index 06594b18..f90a58cc 100644 --- a/server/core/redis.js +++ b/server/core/redis.js @@ -19,5 +19,19 @@ module.exports = { WIKI.logger.error('Invalid Redis configuration!') process.exit(1) } + }, + subscribe() { + let red = this.init() + red.on('message', (channel, msg) => { + WIKI.events.emit(channel, msg) + }) + red.subscribe('localization', (err, count) => { + if (err) { + WIKI.logger.error(err) + process.exit(1) + } + WIKI.logger.info('Redis Subscriber connection: [ OK ]') + }) + return red } } diff --git a/server/graph/index.js b/server/graph/index.js index 6c2d9d83..349b64d7 100644 --- a/server/graph/index.js +++ b/server/graph/index.js @@ -4,8 +4,8 @@ const fs = require('fs') const path = require('path') const autoload = require('auto-load') const PubSub = require('graphql-subscriptions').PubSub -const util = require('util') -const winston = require('winston') +const { LEVEL, MESSAGE } = require('triple-beam') +const Transport = require('winston-transport') /* global WIKI */ @@ -37,20 +37,24 @@ let schemaDirectives = autoload(path.join(WIKI.SERVERPATH, 'graph/directives')) // Live Trail Logger (admin) -let LiveTrailLogger = winston.transports.LiveTrailLogger = function (options) { - this.name = 'livetrailLogger' - this.level = 'debug' -} -util.inherits(LiveTrailLogger, winston.Transport) -LiveTrailLogger.prototype.log = function (level, msg, meta, callback) { - WIKI.GQLEmitter.publish('livetrail', { - loggingLiveTrail: { - timestamp: new Date(), - level, - output: msg - } - }) - callback(null, true) +class LiveTrailLogger extends Transport { + constructor(opts) { + super(opts) + + this.name = 'liveTrailLogger' + this.level = 'debug' + } + + log (info, callback = () => {}) { + WIKI.GQLEmitter.publish('livetrail', { + loggingLiveTrail: { + timestamp: new Date(), + level: info[LEVEL], + output: info[MESSAGE] + } + }) + callback(null, true) + } } WIKI.logger.add(new LiveTrailLogger({})) diff --git a/server/jobs/fetch-graph-locale.js b/server/jobs/fetch-graph-locale.js index f37a666c..d1665962 100644 --- a/server/jobs/fetch-graph-locale.js +++ b/server/jobs/fetch-graph-locale.js @@ -51,6 +51,8 @@ module.exports = async (job) => { throw new Error('Failed to fetch cached locales list! Restart server to resolve this issue.') } + await WIKI.redis.publish('localization', 'reload') + WIKI.logger.info(`Fetching locale ${job.data.locale} from Graph endpoint: [ COMPLETED ]`) } catch (err) { WIKI.logger.error(`Fetching locale ${job.data.locale} from Graph endpoint: [ FAILED ]`) diff --git a/server/jobs/render-page.js b/server/jobs/render-page.js index ad35ee45..b26f8a0e 100644 --- a/server/jobs/render-page.js +++ b/server/jobs/render-page.js @@ -29,16 +29,25 @@ module.exports = async (job) => { $('h1,h2,h3,h4,h5,h6').each((idx, el) => { const depth = _.toSafeInteger(el.name.substring(1)) - (isStrict ? 1 : 2) + let leafPathError = false + const leafPath = _.reduce(_.times(depth), (curPath, curIdx) => { if (_.has(toc, curPath)) { const lastLeafIdx = _.get(toc, curPath).length - 1 - curPath = `${curPath}[${lastLeafIdx}].children` + if (lastLeafIdx >= 0) { + curPath = `${curPath}[${lastLeafIdx}].children` + } else { + leafPathError = true + } } return curPath }, 'root') + if (leafPathError) { return } + const leafSlug = $('.toc-anchor', el).first().attr('href') $('.toc-anchor', el).remove() + _.get(toc, leafPath).push({ title: _.trim($(el).text()), anchor: leafSlug, diff --git a/server/jobs/sync-graph-locales.js b/server/jobs/sync-graph-locales.js index 74bab995..422c207f 100644 --- a/server/jobs/sync-graph-locales.js +++ b/server/jobs/sync-graph-locales.js @@ -68,6 +68,8 @@ module.exports = async (job) => { }).where('code', WIKI.config.lang.code) } + await WIKI.redis.publish('localization', 'reload') + WIKI.logger.info('Syncing locales with Graph endpoint: [ COMPLETED ]') } catch (err) { WIKI.logger.error('Syncing locales with Graph endpoint: [ FAILED ]') diff --git a/server/setup.js b/server/setup.js index 01da3084..81e3de70 100644 --- a/server/setup.js +++ b/server/setup.js @@ -133,7 +133,7 @@ module.exports = () => { nativeName: 'English' }) - // Create default locale + // Create default groups WIKI.logger.info('Creating default groups...') const adminGroup = await WIKI.models.groups.query().insert({ diff --git a/wiki.js b/wiki.js index f949b5fe..53a60902 100644 --- a/wiki.js +++ b/wiki.js @@ -121,6 +121,9 @@ const init = { await global.WIKI.models.knex.destroy() console.warn(chalk.yellow('--- Closing Redis connections...')) await global.WIKI.redis.quit() + await global.WIKI.redisSub.quit() + console.warn(chalk.yellow('--- Closing Queue connections...')) + await global.WIKI.queue.quit() console.warn(chalk.yellow('--- Closing Server connections...')) global.WIKI.server.destroy(() => { global.WIKI = {}