@@ -41,6 +41,7 @@ import {
|
||||
import { DateTime, Duration } from 'luxon';
|
||||
import { TaskRecovery, TaskSpec } from '@backstage/plugin-scaffolder-common';
|
||||
import { trimEventsTillLastRecovery } from './taskRecoveryHelper';
|
||||
import { intervalFromNowTill } from './dbUtil';
|
||||
|
||||
const migrationsDir = resolvePackagePath(
|
||||
'@backstage/plugin-scaffolder-backend',
|
||||
@@ -294,18 +295,7 @@ export class DatabaseTaskStore implements TaskStore {
|
||||
tasks: { taskId: string; recovery?: TaskRecovery }[];
|
||||
}> {
|
||||
const { timeoutS } = options;
|
||||
let heartbeatInterval = this.db.raw(`? - interval '${timeoutS} seconds'`, [
|
||||
this.db.fn.now(),
|
||||
]);
|
||||
if (this.db.client.config.client.includes('mysql')) {
|
||||
heartbeatInterval = this.db.raw(
|
||||
`date_sub(now(), interval ${timeoutS} second)`,
|
||||
);
|
||||
} else if (this.db.client.config.client.includes('sqlite3')) {
|
||||
heartbeatInterval = this.db.raw(`datetime('now', ?)`, [
|
||||
`-${timeoutS} seconds`,
|
||||
]);
|
||||
}
|
||||
const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);
|
||||
const rawRows = await this.db<RawDbTaskRow>('tasks')
|
||||
.where('status', 'processing')
|
||||
.andWhere('last_heartbeat_at', '<=', heartbeatInterval);
|
||||
@@ -498,19 +488,7 @@ export class DatabaseTaskStore implements TaskStore {
|
||||
const timeoutS = Duration.fromObject(options.timeout).as('seconds');
|
||||
|
||||
await this.db.transaction(async tx => {
|
||||
let heartbeatInterval = this.db.raw(
|
||||
`? - interval '${timeoutS} seconds'`,
|
||||
[this.db.fn.now()],
|
||||
);
|
||||
if (this.db.client.config.client.includes('mysql')) {
|
||||
heartbeatInterval = this.db.raw(
|
||||
`date_sub(now(), interval ${timeoutS} second)`,
|
||||
);
|
||||
} else if (this.db.client.config.client.includes('sqlite3')) {
|
||||
heartbeatInterval = this.db.raw(`datetime('now', ?)`, [
|
||||
`-${timeoutS} seconds`,
|
||||
]);
|
||||
}
|
||||
const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);
|
||||
|
||||
const result = await tx<RawDbTaskRow>('tasks')
|
||||
.where('status', 'processing')
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2024 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 knexFactory, { Knex } from 'knex';
|
||||
import { intervalFromNowTill } from './dbUtil';
|
||||
|
||||
class KnexBuilder {
|
||||
public build(client: string): Knex {
|
||||
return knexFactory({ client, useNullAsDefault: true });
|
||||
}
|
||||
}
|
||||
|
||||
describe('util', () => {
|
||||
describe('intervalFromNowTill', () => {
|
||||
const databases = [
|
||||
{ client: 'sqlite3', expected: "datetime('now', '-5 seconds')" },
|
||||
{ client: 'mysql', expected: 'date_sub(now(), interval 5 second)' },
|
||||
{ client: 'pg', expected: "CURRENT_TIMESTAMP - interval '5 seconds'" },
|
||||
];
|
||||
|
||||
it.each(databases)('for client $client', ({ client, expected }) => {
|
||||
const knex = new KnexBuilder().build(client);
|
||||
const result = intervalFromNowTill(5, knex);
|
||||
|
||||
expect(result.toString()).toBe(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2024 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 { Knex } from 'knex';
|
||||
|
||||
export const intervalFromNowTill = (timeoutS: number, knex: Knex) => {
|
||||
let heartbeatInterval = knex.raw(`? - interval '${timeoutS} seconds'`, [
|
||||
knex.fn.now(),
|
||||
]);
|
||||
if (knex.client.config.client.includes('mysql')) {
|
||||
heartbeatInterval = knex.raw(
|
||||
`date_sub(now(), interval ${timeoutS} second)`,
|
||||
);
|
||||
} else if (knex.client.config.client.includes('sqlite3')) {
|
||||
heartbeatInterval = knex.raw(`datetime('now', ?)`, [
|
||||
`-${timeoutS} seconds`,
|
||||
]);
|
||||
}
|
||||
return heartbeatInterval;
|
||||
};
|
||||
Reference in New Issue
Block a user