diff --git a/lib/api.js b/lib/api.js index b66dcb4de..bbfefa4b8 100644 --- a/lib/api.js +++ b/lib/api.js @@ -13,6 +13,7 @@ module.exports.create = function (config) { config.store = _store; })); }).nThen(function (w) { + // XXX embed this in historyKeeper require("../storage/tasks").create(config, w(function (e, tasks) { if (e) { throw e; @@ -20,8 +21,8 @@ module.exports.create = function (config) { config.tasks = tasks; if (config.disableIntegratedTasks) { return; } - // XXX support stopping this interval - setInterval(function () { + config.intervals = config.intervals || {}; + config.intervals.taskExpiration = setInterval(function () { tasks.runAll(function (err) { if (err) { // either TASK_CONCURRENCY or an error with tasks.list diff --git a/lib/commands/admin-rpc.js b/lib/commands/admin-rpc.js index 763bfb517..e3f0c6c58 100644 --- a/lib/commands/admin-rpc.js +++ b/lib/commands/admin-rpc.js @@ -15,11 +15,20 @@ var getActiveSessions = function (Env, Server, cb) { }; var shutdown = function (Env, Server, cb) { - return void cb('E_NOT_IMPLEMENTED'); - //clearInterval(Env.sessionExpirationInterval); - // XXX set a flag to prevent incoming database writes - // XXX disconnect all users and reject new connections - // XXX wait until all pending writes are complete + if (true) { + return void cb('E_NOT_IMPLEMENTED'); + } + + // disconnect all users and reject new connections + Server.shutdown(); + + // stop all intervals that may be running + Object.keys(Env.intervals).forEach(function (name) { + clearInterval(Env.intervals[name]); + }); + + // set a flag to prevent incoming database writes + // wait until all pending writes are complete // then process.exit(0); // and allow system functionality to restart the server }; diff --git a/lib/historyKeeper.js b/lib/historyKeeper.js index d5202876d..a1c09f9aa 100644 --- a/lib/historyKeeper.js +++ b/lib/historyKeeper.js @@ -359,7 +359,6 @@ module.exports.create = function (cfg, cb) { // close the channel store.closeChannel(channel, function () { - // XXX make sure that clients actually disconnect when we broadcast an error Server.channelBroadcast(channel, { error: 'EEXPIRED', channel: channel diff --git a/lib/rpc.js b/lib/rpc.js index eaa4efbbf..0df97efe3 100644 --- a/lib/rpc.js +++ b/lib/rpc.js @@ -378,6 +378,7 @@ RPC.create = function (config, cb) { var Env = { historyKeeper: config.historyKeeper, + intervals: config.intervals || {}, defaultStorageLimit: config.defaultStorageLimit, maxUploadSize: config.maxUploadSize || (20 * 1024 * 1024), Sessions: {}, @@ -388,7 +389,6 @@ RPC.create = function (config, cb) { evPinnedPadsReady: mkEvent(true), limits: {}, admins: [], - sessionExpirationInterval: undefined, Log: Log, WARN: WARN, flushCache: config.flushCache, @@ -427,7 +427,7 @@ RPC.create = function (config, cb) { }; Quota.applyCustomLimits(Env); updateLimitDaily(); - setInterval(updateLimitDaily, 24*3600*1000); + Env.intervals.dailyLimitUpdate = setInterval(updateLimitDaily, 24*3600*1000); Pinning.loadChannelPins(Env); @@ -458,8 +458,7 @@ RPC.create = function (config, cb) { } }); // expire old sessions once per minute - // XXX allow for graceful shutdown - Env.sessionExpirationInterval = setInterval(function () { + Env.intervals.sessionExpirationInterval = setInterval(function () { Core.expireSessions(Sessions); }, Core.SESSION_EXPIRATION_TIME); });