Merge pull request #19793 from wss-ycabrera/PBI_900245_task_worker_fix
Fix bug 19792: Backstage does not immediately apply new schedules for scheduled items
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/backend-tasks': patch
|
||||
---
|
||||
|
||||
When starting a task that existed before, with a faster schedule than it
|
||||
previously had, the task will now correctly obey the faster schedule
|
||||
immediately. Before this fix, the new schedule was only obeyed after the next
|
||||
pending (according to the old schedule) run had completed.
|
||||
@@ -330,6 +330,48 @@ describe('TaskWorker', () => {
|
||||
const before = fn1.mock.calls.length;
|
||||
await promise2;
|
||||
expect(fn1.mock.calls.length).toBeGreaterThan(before);
|
||||
|
||||
await knex.destroy();
|
||||
},
|
||||
);
|
||||
|
||||
it.each(databases.eachSupportedId())(
|
||||
'next_run_start_at is always the min between schedule changes, %p',
|
||||
async databaseId => {
|
||||
const knex = await databases.init(databaseId);
|
||||
await migrateBackendTasks(knex);
|
||||
|
||||
const fn = jest.fn(
|
||||
async () => new Promise<void>(resolve => setTimeout(resolve, 50)),
|
||||
);
|
||||
const settings: TaskSettingsV2 = {
|
||||
version: 2,
|
||||
cadence: '*/15 * * * *',
|
||||
initialDelayDuration: 'PT2M',
|
||||
timeoutAfterDuration: 'PT1M',
|
||||
};
|
||||
|
||||
const worker = new TaskWorker('task99', fn, knex, logger);
|
||||
await worker.persistTask(settings);
|
||||
const row1 = (await knex<DbTasksRow>(DB_TASKS_TABLE))[0];
|
||||
|
||||
const settings2 = {
|
||||
...settings,
|
||||
cadence: '*/2 * * * *',
|
||||
initialDelayDuration: 'PT1M',
|
||||
};
|
||||
await worker.persistTask(settings2);
|
||||
const row2 = (await knex<DbTasksRow>(DB_TASKS_TABLE))[0];
|
||||
|
||||
expect(row2.next_run_start_at).not.toStrictEqual(row1.next_run_start_at);
|
||||
|
||||
const settings3 = { ...settings };
|
||||
await worker.persistTask(settings3);
|
||||
const row3 = (await knex<DbTasksRow>(DB_TASKS_TABLE))[0];
|
||||
|
||||
expect(row3.next_run_start_at).toStrictEqual(row2.next_run_start_at);
|
||||
|
||||
await knex.destroy();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -192,14 +192,36 @@ export class TaskWorker {
|
||||
|
||||
// It's OK if the task already exists; if it does, just replace its
|
||||
// settings with the new value and start the loop as usual.
|
||||
const settingsJson = JSON.stringify(settings);
|
||||
await this.knex<DbTasksRow>(DB_TASKS_TABLE)
|
||||
.insert({
|
||||
id: this.taskId,
|
||||
settings_json: JSON.stringify(settings),
|
||||
settings_json: settingsJson,
|
||||
next_run_start_at: startAt,
|
||||
})
|
||||
.onConflict('id')
|
||||
.merge(['settings_json']);
|
||||
.merge(
|
||||
this.knex.client.config.client.includes('mysql')
|
||||
? {
|
||||
settings_json: settingsJson,
|
||||
next_run_start_at: this.knex.raw(
|
||||
`CASE WHEN ?? < ?? THEN ?? ELSE ?? END`,
|
||||
[startAt, 'next_run_start_at', startAt, 'next_run_start_at'],
|
||||
),
|
||||
}
|
||||
: {
|
||||
settings_json: this.knex.ref('excluded.settings_json'),
|
||||
next_run_start_at: this.knex.raw(
|
||||
`CASE WHEN ?? < ?? THEN ?? ELSE ?? END`,
|
||||
[
|
||||
'excluded.next_run_start_at',
|
||||
`${DB_TASKS_TABLE}.next_run_start_at`,
|
||||
'excluded.next_run_start_at',
|
||||
`${DB_TASKS_TABLE}.next_run_start_at`,
|
||||
],
|
||||
),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user