mirror of https://github.com/requarks/wiki
parent
6ce29bdb77
commit
e1ebaf5b31
@ -1,118 +0,0 @@
|
||||
const _ = require('lodash')
|
||||
const dotize = require('dotize')
|
||||
const i18nMW = require('i18next-express-middleware')
|
||||
const i18next = require('i18next')
|
||||
const Promise = require('bluebird')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const yaml = require('js-yaml')
|
||||
|
||||
/* global WIKI */
|
||||
|
||||
module.exports = {
|
||||
engine: null,
|
||||
namespaces: [],
|
||||
init() {
|
||||
this.namespaces = WIKI.data.localeNamespaces
|
||||
this.engine = i18next
|
||||
this.engine.init({
|
||||
load: 'languageOnly',
|
||||
ns: this.namespaces,
|
||||
defaultNS: 'common',
|
||||
saveMissing: false,
|
||||
lng: WIKI.config.lang.code,
|
||||
fallbackLng: 'en'
|
||||
})
|
||||
|
||||
// Load current language + namespaces
|
||||
this.refreshNamespaces(true)
|
||||
|
||||
return this
|
||||
},
|
||||
/**
|
||||
* Attach i18n middleware for Express
|
||||
*
|
||||
* @param {Object} app Express Instance
|
||||
*/
|
||||
attachMiddleware (app) {
|
||||
app.use(i18nMW.handle(this.engine))
|
||||
},
|
||||
/**
|
||||
* Get all entries for a specific locale and namespace
|
||||
*
|
||||
* @param {String} locale Locale code
|
||||
* @param {String} namespace Namespace
|
||||
*/
|
||||
async getByNamespace(locale, namespace) {
|
||||
if (this.engine.hasResourceBundle(locale, namespace)) {
|
||||
let data = this.engine.getResourceBundle(locale, namespace)
|
||||
return _.map(dotize.convert(data), (value, key) => {
|
||||
return {
|
||||
key,
|
||||
value
|
||||
}
|
||||
})
|
||||
} else {
|
||||
throw new Error('Invalid locale or namespace')
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Load entries from the DB for a single locale
|
||||
*
|
||||
* @param {String} locale Locale code
|
||||
* @param {*} opts Additional options
|
||||
*/
|
||||
async loadLocale(locale, opts = { silent: false }) {
|
||||
const res = await WIKI.models.locales.query().findOne('code', locale)
|
||||
if (res) {
|
||||
if (_.isPlainObject(res.strings)) {
|
||||
_.forOwn(res.strings, (data, ns) => {
|
||||
this.namespaces.push(ns)
|
||||
this.engine.addResourceBundle(locale, ns, data, true, true)
|
||||
})
|
||||
}
|
||||
} else if (!opts.silent) {
|
||||
throw new Error('No such locale in local store.')
|
||||
}
|
||||
|
||||
// -> Load dev locale files if present
|
||||
if (WIKI.IS_DEBUG) {
|
||||
try {
|
||||
const devEntriesRaw = await fs.readFile(path.join(WIKI.SERVERPATH, `locales/${locale}.yml`), 'utf8')
|
||||
if (devEntriesRaw) {
|
||||
const devEntries = yaml.safeLoad(devEntriesRaw)
|
||||
_.forOwn(devEntries, (data, ns) => {
|
||||
this.namespaces.push(ns)
|
||||
this.engine.addResourceBundle(locale, ns, data, true, true)
|
||||
})
|
||||
WIKI.logger.info(`Loaded dev locales from ${locale}.yml`)
|
||||
}
|
||||
} catch (err) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Reload all namespaces for all active locales from the DB
|
||||
*
|
||||
* @param {Boolean} silent No error on fail
|
||||
*/
|
||||
async refreshNamespaces (silent = false) {
|
||||
await this.loadLocale(WIKI.config.lang.code, { silent })
|
||||
if (WIKI.config.lang.namespacing) {
|
||||
for (let ns of WIKI.config.lang.namespaces) {
|
||||
await this.loadLocale(ns, { silent })
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Set the active locale
|
||||
*
|
||||
* @param {String} locale Locale code
|
||||
*/
|
||||
async setCurrentLocale(locale) {
|
||||
await Promise.fromCallback(cb => {
|
||||
return this.engine.changeLanguage(locale, cb)
|
||||
})
|
||||
}
|
||||
}
|
@ -1,28 +1,60 @@
|
||||
const PgBoss = require('pg-boss')
|
||||
const { DynamicThreadPool } = require('poolifier')
|
||||
const os = require('node:os')
|
||||
|
||||
/* global WIKI */
|
||||
|
||||
module.exports = {
|
||||
pool: null,
|
||||
scheduler: null,
|
||||
jobs: [],
|
||||
init () {
|
||||
async init () {
|
||||
WIKI.logger.info('Initializing Scheduler...')
|
||||
this.scheduler = new PgBoss({
|
||||
...WIKI.models.knex.client.connectionSettings,
|
||||
db: {
|
||||
close: () => Promise.resolve('ok'),
|
||||
executeSql: async (text, values) => {
|
||||
try {
|
||||
const resource = await WIKI.models.knex.client.pool.acquire().promise
|
||||
const res = await resource.query(text, values)
|
||||
WIKI.models.knex.client.pool.release(resource)
|
||||
return res
|
||||
} catch (err) {
|
||||
WIKI.logger.error('Failed to acquire DB connection during scheduler query execution.')
|
||||
WIKI.logger.error(err)
|
||||
}
|
||||
}
|
||||
},
|
||||
// ...WIKI.models.knex.client.connectionSettings,
|
||||
application_name: 'Wiki.js Scheduler',
|
||||
schema: WIKI.config.db.schemas.scheduler,
|
||||
uuid: 'v4'
|
||||
})
|
||||
|
||||
const maxWorkers = WIKI.config.workers === 'auto' ? os.cpus().length : WIKI.config.workers
|
||||
WIKI.logger.info(`Initializing Worker Pool (Max ${maxWorkers})...`)
|
||||
this.pool = new DynamicThreadPool(1, maxWorkers, './server/worker.js', {
|
||||
errorHandler: (err) => WIKI.logger.warn(err),
|
||||
exitHandler: () => WIKI.logger.debug('A worker has gone offline.'),
|
||||
onlineHandler: () => WIKI.logger.debug('New worker is online.')
|
||||
})
|
||||
return this
|
||||
},
|
||||
async start () {
|
||||
WIKI.logger.info('Starting Scheduler...')
|
||||
await this.scheduler.start()
|
||||
this.scheduler.work('*', async job => {
|
||||
return this.pool.execute({
|
||||
id: job.id,
|
||||
name: job.name,
|
||||
data: job.data
|
||||
})
|
||||
})
|
||||
WIKI.logger.info('Scheduler: [ STARTED ]')
|
||||
},
|
||||
async stop () {
|
||||
WIKI.logger.info('Stopping Scheduler...')
|
||||
await this.scheduler.stop()
|
||||
await this.pool.destroy()
|
||||
WIKI.logger.info('Scheduler: [ STOPPED ]')
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
const { ThreadWorker } = require('poolifier')
|
||||
|
||||
module.exports = new ThreadWorker(async (job) => {
|
||||
return { ok: true }
|
||||
}, { async: true })
|
Loading…
Reference in new issue