diff --git a/migrations/20250617133955-tasks-add-pending.js b/migrations/20250617133955-tasks-add-pending.js new file mode 100644 index 000000000..0838b632f --- /dev/null +++ b/migrations/20250617133955-tasks-add-pending.js @@ -0,0 +1,10 @@ +'use strict'; + +exports.up = async function (db) { + await db.runSql('ALTER TABLE tasks ADD COLUMN pending BOOLEAN DEFAULT true'); + await db.runSql('UPDATE tasks SET pending=?', [ false ]); +}; + +exports.down = async function (db) { + await db.runSql('ALTER TABLE tasks DROP COLUMN pending'); +}; diff --git a/src/tasks.js b/src/tasks.js index 25681077c..71a3422ca 100644 --- a/src/tasks.js +++ b/src/tasks.js @@ -61,7 +61,7 @@ let gTasks = {}; // indexed by task id const START_TASK_CMD = path.join(__dirname, 'scripts/starttask.sh'); const STOP_TASK_CMD = path.join(__dirname, 'scripts/stoptask.sh'); -const TASKS_FIELDS = [ 'id', 'type', 'argsJson', 'percent', 'message', 'errorJson', 'creationTime', 'resultJson', 'ts' ]; +const TASKS_FIELDS = [ 'id', 'type', 'argsJson', 'percent', 'pending', 'message', 'errorJson', 'creationTime', 'resultJson', 'ts' ]; function postProcess(task) { assert.strictEqual(typeof task, 'object'); @@ -84,13 +84,8 @@ function postProcess(task) { function updateStatus(result) { assert.strictEqual(typeof result, 'object'); - // running means actively running - // pending means not actively running - // active mean task is 'done' or not. at this point, clients can stop polling this task. - // the apptaskmanager sets percent=1 when queued. just a hack to figure non-started but scheduled tasks - result.running = !!gTasks[result.id]; - result.active = result.running || result.percent === 1; - result.pending = !gTasks[result.id] && result.active; + result.running = !!gTasks[result.id]; // running means actively running + result.active = result.running || !!result.pending; // active mean task is 'done' or not. at this point, clients can stop polling this task. // we rely on 'percent' to determine success. maybe this can become a db field result.success = result.percent === 100 && !result.error; @@ -157,7 +152,7 @@ async function add(type, args) { assert.strictEqual(typeof type, 'string'); assert(Array.isArray(args)); - const result = await database.query('INSERT INTO tasks (type, argsJson, percent, message) VALUES (?, ?, ?, ?)', [ type, JSON.stringify(args), 0, 'Queued' ]); + const result = await database.query('INSERT INTO tasks (type, argsJson, percent, message, pending) VALUES (?, ?, ?, ?, ?)', [ type, JSON.stringify(args), 0, 'Queued', true ]); return String(result.insertId); } @@ -221,6 +216,8 @@ function startTask(id, options, onTaskFinished) { if (error) debug(`startTask: error stopping task: ${error.message}`); }, options.timeout); } + + update(id, { pending: false }); // fixme: make async } async function stopTask(id) { @@ -288,7 +285,7 @@ async function getLogs(task, options) { // removes all fields that are strictly private and should never be returned by API calls function removePrivateFields(task) { - return _.pick(task, ['id', 'type', 'percent', 'message', 'error', 'active', 'pending', 'creationTime', 'result', 'ts', 'success']); + return _.pick(task, ['id', 'type', 'percent', 'message', 'error', 'running', 'active', 'creationTime', 'result', 'ts', 'success']); } async function del(id) { diff --git a/src/taskworker.js b/src/taskworker.js index 982f15263..2ee434f01 100755 --- a/src/taskworker.js +++ b/src/taskworker.js @@ -33,8 +33,8 @@ const TASKS = { // indexed by task type syncDyndns: dyndns.sync, updateDiskUsage: system.updateDiskUsage, - _identity: async (arg, progressCallback) => { progressCallback({}); return arg; }, - _error: async (arg, progressCallback) => { progressCallback({}); throw new Error(`Failed for arg: ${arg}`); }, + _identity: async (arg, progressCallback) => { progressCallback({ percent: 20 }); return arg; }, + _error: async (arg, progressCallback) => { progressCallback({ percent: 20 }); throw new Error(`Failed for arg: ${arg}`); }, _crash: (arg) => { throw new Error(`Crashing for arg: ${arg}`); }, // the test looks for this debug string in the log file _sleep: async (arg) => setTimeout(process.exit, arg) };