mirror of
https://github.com/NuSkooler/enigma-bbs.git
synced 2025-07-25 03:58:17 +02:00
Initial version of hot-reload of config, menus, and prompts
* Themes use ES6 Map vs object{} * Re-write and re-enable config cache using sane * Events sent for config, prompt, or menu changes * Event sent for theme changes * Theme (or parent menu/prompt) changes cause re-merge and updates to connected clients
This commit is contained in:
parent
1870db7d38
commit
4aab8224ed
8 changed files with 275 additions and 242 deletions
|
@ -1,85 +1,70 @@
|
|||
/* jslint node: true */
|
||||
'use strict';
|
||||
|
||||
var Config = require('./config.js').config;
|
||||
var Log = require('./logger.js').log;
|
||||
// deps
|
||||
const paths = require('path');
|
||||
const fs = require('graceful-fs');
|
||||
const hjson = require('hjson');
|
||||
const sane = require('sane');
|
||||
|
||||
var paths = require('path');
|
||||
var fs = require('graceful-fs');
|
||||
var events = require('events');
|
||||
var util = require('util');
|
||||
var assert = require('assert');
|
||||
var hjson = require('hjson');
|
||||
var _ = require('lodash');
|
||||
module.exports = new class ConfigCache
|
||||
{
|
||||
constructor() {
|
||||
this.cache = new Map(); // path->parsed config
|
||||
}
|
||||
|
||||
function ConfigCache() {
|
||||
events.EventEmitter.call(this);
|
||||
getConfigWithOptions(options, cb) {
|
||||
const cached = this.cache.has(options.filePath);
|
||||
|
||||
var self = this;
|
||||
this.cache = {}; // filePath -> HJSON
|
||||
//this.gaze = new Gaze();
|
||||
if(options.forceReCache || !cached) {
|
||||
this.recacheConfigFromFile(options.filePath, (err, config) => {
|
||||
if(!err && !cached) {
|
||||
const watcher = sane(
|
||||
paths.dirname(options.filePath),
|
||||
{
|
||||
glob : `**/${paths.basename(options.filePath)}`
|
||||
}
|
||||
);
|
||||
|
||||
this.reCacheConfigFromFile = function(filePath, cb) {
|
||||
fs.readFile(filePath, { encoding : 'utf-8' }, function fileRead(err, data) {
|
||||
try {
|
||||
self.cache[filePath] = hjson.parse(data);
|
||||
cb(null, self.cache[filePath]);
|
||||
} catch(e) {
|
||||
Log.error( { filePath : filePath, error : e.toString() }, 'Failed recaching');
|
||||
cb(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
watcher.on('change', (fileName, fileRoot) => {
|
||||
require('./logger.js').log.info( { fileName, fileRoot }, 'Configuration file changed; re-caching');
|
||||
|
||||
/*
|
||||
this.gaze.on('error', function gazeErr(err) {
|
||||
this.recacheConfigFromFile(paths.join(fileRoot, fileName), err => {
|
||||
if(!err) {
|
||||
if(options.callback) {
|
||||
options.callback( { fileName, fileRoot } );
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return cb(err, config, true);
|
||||
});
|
||||
} else {
|
||||
return cb(null, this.cache.get(options.filePath), false);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
getConfig(filePath, cb) {
|
||||
return this.getConfigWithOptions( { filePath }, cb);
|
||||
}
|
||||
|
||||
this.gaze.on('changed', function fileChanged(filePath) {
|
||||
assert(filePath in self.cache);
|
||||
|
||||
Log.info( { path : filePath }, 'Configuration file changed; re-caching');
|
||||
|
||||
self.reCacheConfigFromFile(filePath, function reCached(err) {
|
||||
recacheConfigFromFile(path, cb) {
|
||||
fs.readFile(path, { encoding : 'utf-8' }, (err, data) => {
|
||||
if(err) {
|
||||
Log.error( { error : err.message, path : filePath } , 'Failed re-caching configuration');
|
||||
} else {
|
||||
self.emit('recached', filePath);
|
||||
return cb(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
util.inherits(ConfigCache, events.EventEmitter);
|
||||
|
||||
ConfigCache.prototype.getConfigWithOptions = function(options, cb) {
|
||||
assert(_.isString(options.filePath));
|
||||
|
||||
// var self = this;
|
||||
var isCached = (options.filePath in this.cache);
|
||||
|
||||
if(options.forceReCache || !isCached) {
|
||||
this.reCacheConfigFromFile(options.filePath, function fileCached(err, config) {
|
||||
if(!err && !isCached) {
|
||||
//self.gaze.add(options.filePath);
|
||||
let parsed;
|
||||
try {
|
||||
parsed = hjson.parse(data);
|
||||
this.cache.set(path, parsed);
|
||||
} catch(e) {
|
||||
require('./logger.js').log.error( { filePath : path, error : e.message }, 'Failed to re-cache' );
|
||||
return cb(e);
|
||||
}
|
||||
cb(err, config, true);
|
||||
|
||||
return cb(null, parsed);
|
||||
});
|
||||
} else {
|
||||
cb(null, this.cache[options.filePath], false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
ConfigCache.prototype.getConfig = function(filePath, cb) {
|
||||
this.getConfigWithOptions( { filePath : filePath }, cb);
|
||||
};
|
||||
|
||||
ConfigCache.prototype.getModConfig = function(fileName, cb) {
|
||||
this.getConfig(paths.join(Config.paths.mods, fileName), cb);
|
||||
};
|
||||
|
||||
module.exports = exports = new ConfigCache();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue