From e6d23a9701e2e504b2f852c5969dbd8429fec5ce Mon Sep 17 00:00:00 2001 From: "girish@cloudron.io" Date: Tue, 9 Feb 2016 11:41:59 -0800 Subject: [PATCH] stop previous task explicitly there is a race: 1. task is running 2. new task is created overwriting the installationState 3. new task kills the old task of step 1. this results in installationState getting overwritten by 'error' because of the sigkill 4. new task that is launched loses the installationState that was step in 2. --- src/apps.js | 12 +++++++----- src/apptask.js | 2 +- src/routes/test/apps-test.js | 4 ++-- src/taskmanager.js | 2 ++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/apps.js b/src/apps.js index 46f6f8735..34168b9f0 100644 --- a/src/apps.js +++ b/src/apps.js @@ -578,13 +578,15 @@ function uninstall(appId, callback) { debug('Will uninstall app with id:%s', appId); - appdb.setInstallationCommand(appId, appdb.ISTATE_PENDING_UNINSTALL, function (error) { - if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such app')); - if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error)); + taskmanager.stopAppTask(appId, function () { + appdb.setInstallationCommand(appId, appdb.ISTATE_PENDING_UNINSTALL, function (error) { + if (error && error.reason === DatabaseError.NOT_FOUND) return callback(new AppsError(AppsError.NOT_FOUND, 'No such app')); + if (error) return callback(new AppsError(AppsError.INTERNAL_ERROR, error)); - taskmanager.restartAppTask(appId); // since uninstall is allowed from any state, kill current task + taskmanager.startAppTask(appId); // since uninstall is allowed from any state, kill current task - callback(null); + callback(null); + }); }); } diff --git a/src/apptask.js b/src/apptask.js index 9176434db..502ca7c40 100644 --- a/src/apptask.js +++ b/src/apptask.js @@ -763,7 +763,7 @@ function startTask(appId, callback) { case appdb.ISTATE_PENDING_INSTALL: return install(app, callback); case appdb.ISTATE_PENDING_FORCE_UPDATE: return update(app, callback); case appdb.ISTATE_ERROR: - debugApp(app, 'Apptask launched with error states.'); + debugApp(app, 'Internal error. apptask launched with error status.'); return callback(null); default: debugApp(app, 'apptask launched with invalid command'); diff --git a/src/routes/test/apps-test.js b/src/routes/test/apps-test.js index c07f84c7a..502b1f5ec 100644 --- a/src/routes/test/apps-test.js +++ b/src/routes/test/apps-test.js @@ -1489,8 +1489,8 @@ describe('Apps', function () { .query({ access_token: token }) .end(function (err, res) { if (res.statusCode === 404) return done(null); - if (++count > 20) return done(new Error('Timedout')); - setTimeout(checkUninstallStatus, 400); + if (++count > 50) return done(new Error('Timedout')); + setTimeout(checkUninstallStatus, 1000); }); } diff --git a/src/taskmanager.js b/src/taskmanager.js index 84df098aa..c0c8eb1aa 100644 --- a/src/taskmanager.js +++ b/src/taskmanager.js @@ -4,6 +4,8 @@ exports = module.exports = { initialize: initialize, uninitialize: uninitialize, + stopAppTask: stopAppTask, + startAppTask: startAppTask, restartAppTask: restartAppTask, stopPendingTasks: stopPendingTasks,