diff --git a/src/cloudron.js b/src/cloudron.js index 831e8aed7..4987c1a89 100644 --- a/src/cloudron.js +++ b/src/cloudron.js @@ -59,6 +59,7 @@ var apps = require('./apps.js'), subdomains = require('./subdomains.js'), superagent = require('superagent'), sysinfo = require('./sysinfo.js'), + taskmanager = require('./taskmanager.js'), tokendb = require('./tokendb.js'), updateChecker = require('./updatechecker.js'), user = require('./user.js'), @@ -135,7 +136,10 @@ function initialize(callback) { function uninitialize(callback) { assert.strictEqual(typeof callback, 'function'); + platform.events.removeListener(platform.EVENT_READY, onPlatformReady); + async.series([ + taskmanager.pauseTasks, mailer.stop, platform.uninitialize ], callback); @@ -144,6 +148,10 @@ function uninitialize(callback) { function onConfigured(callback) { callback = callback || NOOP_CALLBACK; + debug('onConfigured'); + + platform.events.on(platform.EVENT_READY, onPlatformReady); + async.series([ certificates.ensureFallbackCertificate, platform.initialize, // requires fallback certs in mail container @@ -153,6 +161,16 @@ function onConfigured(callback) { ], callback); } +function onPlatformReady(callback) { + callback = callback || NOOP_CALLBACK; + + debug('onPlatformReady'); + + async.series([ + taskmanager.resumeTasks + ], callback); +} + function getConfigStateSync() { return gConfigState; } diff --git a/src/server.js b/src/server.js index 89b38277a..f553b02d5 100644 --- a/src/server.js +++ b/src/server.js @@ -267,7 +267,6 @@ function start(callback) { database.initialize, cloudron.initialize, // keep this here because it reads activation state that others depend on cloudron.configureAdmin, // keep this before cron to block heartbeats until cert is ready - taskmanager.initialize, cron.initialize, gHttpServer.listen.bind(gHttpServer, config.get('port'), '127.0.0.1'), gSysadminHttpServer.listen.bind(gSysadminHttpServer, config.get('sysadminPort'), '127.0.0.1'), @@ -281,11 +280,10 @@ function stop(callback) { if (!gHttpServer) return callback(null); async.series([ - auth.uninitialize, cloudron.uninitialize, - taskmanager.uninitialize, cron.uninitialize, database.uninitialize, + auth.uninitialize, gHttpServer.close.bind(gHttpServer), gSysadminHttpServer.close.bind(gSysadminHttpServer) ], function (error) { diff --git a/src/taskmanager.js b/src/taskmanager.js index 2074aae59..98ffc9abe 100644 --- a/src/taskmanager.js +++ b/src/taskmanager.js @@ -1,8 +1,8 @@ 'use strict'; exports = module.exports = { - initialize: initialize, - uninitialize: uninitialize, + resumeTasks: resumeTasks, + pauseTasks: pauseTasks, stopAppTask: stopAppTask, startAppTask: startAppTask, @@ -16,7 +16,6 @@ var appdb = require('./appdb.js'), assert = require('assert'), async = require('async'), child_process = require('child_process'), - cloudron = require('./cloudron.js'), debug = require('debug')('box:taskmanager'), locker = require('./locker.js'), platform = require('./platform.js'), @@ -30,28 +29,35 @@ var gPendingTasks = [ ]; var TASK_CONCURRENCY = 3; var NOOP_CALLBACK = function (error) { if (error) console.error(error); }; -function initialize(callback) { - assert.strictEqual(typeof callback, 'function'); +// resume app tasks when platform is ready or after a crash +function resumeTasks(callback) { + callback = callback || NOOP_CALLBACK; + + debug('resuming tasks'); locker.on('unlocked', startNextTask); - if (platform.isReadySync()) { - platformReady(); - } else { - platform.events.on(platform.EVENT_READY, platformReady); - } + appdb.getAll(function (error, apps) { + if (error) return callback(error); - callback(); + apps.forEach(function (app) { + if (app.installationState === appdb.ISTATE_INSTALLED && app.runState === appdb.RSTATE_RUNNING) return; + + if (app.installationState === appdb.ISTATE_ERROR) return; + + debug('Creating process for %s (%s) with state %s', app.location, app.id, app.installationState); + restartAppTask(app.id, NOOP_CALLBACK); // restart because the auto-installer could have queued up tasks already + }); + + callback(null); + }); } -function uninitialize(callback) { +function pauseTasks(callback) { assert.strictEqual(typeof callback, 'function'); gPendingTasks = [ ]; // clear this first, otherwise stopAppTask will resume them - cloudron.events.removeListener(cloudron.EVENT_CONFIGURED, resumeTasks); - platform.events.removeListener(platform.EVENT_READY, platformReady); - locker.removeListener('unlocked', startNextTask); async.eachSeries(Object.keys(gActiveTasks), stopAppTask, callback); @@ -76,38 +82,6 @@ function waitForPendingTasks(callback) { checkTasks(); } -function platformReady() { - if (cloudron.getConfigStateSync().configured) { - debug('platformReady: configured, resuming tasks'); // cloudron-setup script relies on this log message - resumeTasks(); - } else { - debug('platformReady: not configured yet. waiting for configured event'); - cloudron.events.on(cloudron.EVENT_CONFIGURED, resumeTasks); - } -} - -// resume app tasks when platform is ready or after a crash -function resumeTasks(callback) { - callback = callback || NOOP_CALLBACK; - - debug('resuming tasks'); - - appdb.getAll(function (error, apps) { - if (error) return callback(error); - - apps.forEach(function (app) { - if (app.installationState === appdb.ISTATE_INSTALLED && app.runState === appdb.RSTATE_RUNNING) return; - - if (app.installationState === appdb.ISTATE_ERROR) return; - - debug('Creating process for %s (%s) with state %s', app.location, app.id, app.installationState); - restartAppTask(app.id, NOOP_CALLBACK); // restart because the auto-installer could have queued up tasks already - }); - - callback(null); - }); -} - function startNextTask() { if (gPendingTasks.length === 0) return;