From f0685193efa9f22a84207eb60dc1f9f509643059 Mon Sep 17 00:00:00 2001 From: Ana Luiza Ramalho dos Santos Date: Mon, 2 Jan 2023 18:08:34 -0300 Subject: [PATCH 1/4] fix: add conditional to database different postgres Signed-off-by: Ana Luiza Ramalho dos Santos --- .changeset/rare-buses-swim.md | 5 +++ .../src/tasks/PluginTaskSchedulerJanitor.ts | 32 ++++++++++++++----- 2 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 .changeset/rare-buses-swim.md diff --git a/.changeset/rare-buses-swim.md b/.changeset/rare-buses-swim.md new file mode 100644 index 0000000000..4e4c11e792 --- /dev/null +++ b/.changeset/rare-buses-swim.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-tasks': minor +--- + +Added the adapted query to mysql and sqlite3 databases to not returning warning on logs diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts index 81b0345c2c..4482f2e2bb 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts @@ -53,15 +53,31 @@ export class PluginTaskSchedulerJanitor { private async runOnce() { const dbNull = this.knex.raw('null'); + let tasks = []; + const configClient = this.knex.client.config.client; - const tasks = await this.knex(DB_TASKS_TABLE) - .where('current_run_expires_at', '<', this.knex.fn.now()) - .update({ - current_run_ticket: dbNull, - current_run_started_at: dbNull, - current_run_expires_at: dbNull, - }) - .returning(['id']); + if (configClient.includes('sqlite3') || configClient.includes('mysql')) { + const now = await this.knex.select(this.knex.fn.now()); + tasks = await this.knex(DB_TASKS_TABLE) + .select('*') + .where('current_run_expires_at', '<', now); + await this.knex(DB_TASKS_TABLE) + .where('current_run_expires_at', '<', now) + .update({ + current_run_ticket: dbNull, + current_run_started_at: dbNull, + current_run_expires_at: dbNull, + }); + } else { + tasks = await this.knex(DB_TASKS_TABLE) + .where('current_run_expires_at', '<', this.knex.fn.now()) + .update({ + current_run_ticket: dbNull, + current_run_started_at: dbNull, + current_run_expires_at: dbNull, + }) + .returning(['id']); + } // In rare cases, knex drivers may ignore "returning", and return the number // of rows changed instead From 3e28855c0267fc28ad4dca3466285cee1d22049f Mon Sep 17 00:00:00 2001 From: Ana Luiza Ramalho dos Santos Date: Mon, 16 Jan 2023 13:57:39 -0300 Subject: [PATCH 2/4] fix: specify type of let Signed-off-by: Ana Luiza Ramalho dos Santos --- .../backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts index 4482f2e2bb..0d8ea79d13 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts @@ -53,13 +53,13 @@ export class PluginTaskSchedulerJanitor { private async runOnce() { const dbNull = this.knex.raw('null'); - let tasks = []; + let tasks: Array<{ id: string }>; const configClient = this.knex.client.config.client; if (configClient.includes('sqlite3') || configClient.includes('mysql')) { const now = await this.knex.select(this.knex.fn.now()); tasks = await this.knex(DB_TASKS_TABLE) - .select('*') + .select('id') .where('current_run_expires_at', '<', now); await this.knex(DB_TASKS_TABLE) .where('current_run_expires_at', '<', now) From 3b630ee2cda5850783072e65fac7471f6d0a6f25 Mon Sep 17 00:00:00 2001 From: Ana Luiza Ramalho dos Santos Date: Tue, 14 Feb 2023 10:21:22 -0300 Subject: [PATCH 3/4] test: add test from PluginTaskSchedulerJanitor Signed-off-by: Ana Luiza Ramalho dos Santos --- .changeset/rare-buses-swim.md | 2 +- .../tasks/PluginTaskSchedulerJanitor.test.ts | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts diff --git a/.changeset/rare-buses-swim.md b/.changeset/rare-buses-swim.md index 4e4c11e792..4626343ca3 100644 --- a/.changeset/rare-buses-swim.md +++ b/.changeset/rare-buses-swim.md @@ -1,5 +1,5 @@ --- -'@backstage/backend-tasks': minor +'@backstage/backend-tasks': patch --- Added the adapted query to mysql and sqlite3 databases to not returning warning on logs diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts new file mode 100644 index 0000000000..f981bf59fe --- /dev/null +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts @@ -0,0 +1,92 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { TestDatabases } from '@backstage/backend-test-utils'; +import { Knex } from 'knex'; +import { Duration } from 'luxon'; +import waitForExpect from 'wait-for-expect'; +import { migrateBackendTasks } from '../database/migrateBackendTasks'; +import { DbTasksRow, DB_TASKS_TABLE } from '../database/tables'; +import { PluginTaskSchedulerJanitor } from './PluginTaskSchedulerJanitor'; + +const insertTask = async (knex: Knex, task: DbTasksRow) => { + return knex(DB_TASKS_TABLE) + .insert(task) + .onConflict('id') + .merge(['settings_json']); +}; + +const getTask = async (knex: Knex): Promise => { + return (await knex(DB_TASKS_TABLE))[0]; +}; + +describe('PluginTaskSchedulerJanitor', () => { + const logger = getVoidLogger(); + const databases = TestDatabases.create({ + ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + }); + + jest.setTimeout(300_000); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it.each(databases.eachSupportedId())( + 'Should update date if current_run_expires_at expires , %p', + async databaseId => { + const knex = await databases.init(databaseId); + await migrateBackendTasks(knex); + + const dateYesterday = new Date( + new Date().setDate(new Date().getDate() - 1), + ); + + await insertTask(knex, { + id: 'task1', + settings_json: '', + next_run_start_at: new Date('2023-03-01 00:00:00'), + current_run_ticket: 'ticket', + current_run_started_at: dateYesterday, + current_run_expires_at: dateYesterday, + }); + + const worker = new PluginTaskSchedulerJanitor({ + knex, + waitBetweenRuns: Duration.fromObject({ minutes: 1 }), + logger, + }); + + const abortController = new AbortController(); + + await worker.start(abortController.signal); + + const row1 = await getTask(knex); + + await waitForExpect(async () => { + expect(row1).toEqual( + expect.objectContaining({ + id: 'task1', + current_run_ticket: null, + current_run_started_at: null, + current_run_expires_at: null, + }), + ); + }); + }, + ); +}); From b69c41bfaf9f46555f6f0e350c6e692be96be6ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 16 Feb 2023 14:57:19 +0100 Subject: [PATCH 4/4] fixup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .../tasks/PluginTaskSchedulerJanitor.test.ts | 22 +++++++++++-------- .../src/tasks/PluginTaskSchedulerJanitor.ts | 10 +++++---- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts index f981bf59fe..5b5d592b7b 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.test.ts @@ -37,17 +37,22 @@ const getTask = async (knex: Knex): Promise => { describe('PluginTaskSchedulerJanitor', () => { const logger = getVoidLogger(); const databases = TestDatabases.create({ - ids: ['MYSQL_8', 'POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], + ids: [ + /* 'MYSQL_8' not supported yet */ + 'POSTGRES_13', + 'POSTGRES_9', + 'SQLITE_3', + ], }); - jest.setTimeout(300_000); + jest.setTimeout(60_000); beforeEach(() => { jest.resetAllMocks(); }); it.each(databases.eachSupportedId())( - 'Should update date if current_run_expires_at expires , %p', + 'Should update date if current_run_expires_at expires, %p', async databaseId => { const knex = await databases.init(databaseId); await migrateBackendTasks(knex); @@ -66,19 +71,16 @@ describe('PluginTaskSchedulerJanitor', () => { }); const worker = new PluginTaskSchedulerJanitor({ + waitBetweenRuns: Duration.fromObject({ milliseconds: 20 }), knex, - waitBetweenRuns: Duration.fromObject({ minutes: 1 }), logger, }); const abortController = new AbortController(); - - await worker.start(abortController.signal); - - const row1 = await getTask(knex); + worker.start(abortController.signal); await waitForExpect(async () => { - expect(row1).toEqual( + await expect(getTask(knex)).resolves.toEqual( expect.objectContaining({ id: 'task1', current_run_ticket: null, @@ -87,6 +89,8 @@ describe('PluginTaskSchedulerJanitor', () => { }), ); }); + + abortController.abort(); }, ); }); diff --git a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts index 0d8ea79d13..f69b7d9b88 100644 --- a/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts +++ b/packages/backend-tasks/src/tasks/PluginTaskSchedulerJanitor.ts @@ -53,16 +53,18 @@ export class PluginTaskSchedulerJanitor { private async runOnce() { const dbNull = this.knex.raw('null'); - let tasks: Array<{ id: string }>; const configClient = this.knex.client.config.client; + let tasks: Array<{ id: string }>; if (configClient.includes('sqlite3') || configClient.includes('mysql')) { - const now = await this.knex.select(this.knex.fn.now()); tasks = await this.knex(DB_TASKS_TABLE) .select('id') - .where('current_run_expires_at', '<', now); + .where('current_run_expires_at', '<', this.knex.fn.now()); await this.knex(DB_TASKS_TABLE) - .where('current_run_expires_at', '<', now) + .whereIn( + 'id', + tasks.map(t => t.id), + ) .update({ current_run_ticket: dbNull, current_run_started_at: dbNull,