review updates

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2022-03-22 16:21:37 +01:00
parent 9053686daa
commit c1cfe0db30
8 changed files with 65 additions and 50 deletions
+14 -1
View File
@@ -2,4 +2,17 @@
'@backstage/plugin-tech-insights-backend': minor
---
Updates tech-insights to use backend-tasks as the Fact Retriever scheduler.
This backend now uses the `@backstage/backend-tasks` package facilities for scheduling fact retrievers.
**BREAKING**: The `buildTechInsightsContext` function now takes an additional field in its options argument: `scheduler`. This is an instance of `PluginTaskScheduler`, which can be found in your backend initialization code's `env`.
```diff
const builder = buildTechInsightsContext({
logger: env.logger,
config: env.config,
database: env.database,
discovery: env.discovery,
+ scheduler: env.scheduler,
factRetrievers: [ /* ... */ ],
});
```
@@ -41,11 +41,9 @@ export class PluginTaskSchedulerImpl implements PluginTaskScheduler {
// check if task exists
const rows = await knex<DbTasksRow>(DB_TASKS_TABLE)
.count({ count: '*' })
.select(knex.raw(1))
.where('id', '=', id);
// validate the task exists
if (rows[0].count !== 1) {
if (rows.length !== 1) {
throw new NotFoundError(`Task ${id} does not exist`);
}
@@ -56,7 +54,7 @@ export class PluginTaskSchedulerImpl implements PluginTaskScheduler {
next_run_start_at: knex.fn.now(),
});
if (updatedRows < 1) {
throw new ConflictError(`task ${id} is currently running`);
throw new ConflictError(`Task ${id} is currently running`);
}
}
+1
View File
@@ -35,6 +35,7 @@ export default async function createPlugin(
config: env.config,
database: env.database,
discovery: env.discovery,
scheduler: env.scheduler,
factRetrievers: [], // Fact retrievers registrations you want tech insights to use
});
+3 -5
View File
@@ -27,11 +27,9 @@ export const buildTechInsightsContext: <
) => Promise<TechInsightsContext<CheckType, CheckResultType>>;
// @public
export function createFactRetrieverRegistration({
cadence,
factRetriever,
lifecycle,
}: FactRetrieverRegistrationOptions): FactRetrieverRegistration;
export function createFactRetrieverRegistration(
options: FactRetrieverRegistrationOptions,
): FactRetrieverRegistration;
// @public
export function createRouter<
@@ -194,7 +194,7 @@ describe('FactRetrieverEngine', () => {
}
engine = await createEngine(databaseId, insertCallback, () => {});
engine.schedule();
await engine.schedule();
const job: FactRetrieverRegistration = engine.getJobRegistration(
testFactRetriever.id,
);
@@ -39,7 +39,7 @@ function duration(startTimestamp: [number, number]): string {
}
export class FactRetrieverEngine {
constructor(
private constructor(
private readonly repository: TechInsightsStore,
private readonly factRetrieverRegistry: FactRetrieverRegistry,
private readonly factRetrieverContext: FactRetrieverContext,
@@ -49,14 +49,7 @@ export class FactRetrieverEngine {
private readonly defaultTimeout?: Duration,
) {}
static async create({
repository,
factRetrieverRegistry,
factRetrieverContext,
scheduler,
defaultCadence,
defaultTimeout,
}: {
static async create(options: {
repository: TechInsightsStore;
factRetrieverRegistry: FactRetrieverRegistry;
factRetrieverContext: FactRetrieverContext;
@@ -64,6 +57,15 @@ export class FactRetrieverEngine {
defaultCadence?: string;
defaultTimeout?: Duration;
}) {
const {
repository,
factRetrieverRegistry,
factRetrieverContext,
scheduler,
defaultCadence,
defaultTimeout,
} = options;
await Promise.all(
factRetrieverRegistry
.listRetrievers()
@@ -81,31 +83,35 @@ export class FactRetrieverEngine {
);
}
schedule() {
async schedule() {
const registrations = this.factRetrieverRegistry.listRegistrations();
const newRegs: string[] = [];
registrations.forEach(async registration => {
const { factRetriever, cadence, lifecycle, timeout } = registration;
const cronExpression =
cadence || this.defaultCadence || randomDailyCron();
const timeLimit =
timeout || this.defaultTimeout || Duration.fromObject({ minutes: 5 });
try {
await this.scheduler.scheduleTask({
id: factRetriever.id,
frequency: { cron: cronExpression },
fn: this.createFactRetrieverHandler(factRetriever, lifecycle),
timeout: timeLimit,
});
} catch (e) {
throw new Error(
`Failed to schedule fact retriever ${factRetriever.id}, ${e}`,
);
}
newRegs.push(factRetriever.id);
});
await Promise.all(
registrations.map(async registration => {
const { factRetriever, cadence, lifecycle, timeout } = registration;
const cronExpression =
cadence || this.defaultCadence || randomDailyCron();
const timeLimit =
timeout || this.defaultTimeout || Duration.fromObject({ minutes: 5 });
try {
await this.scheduler.scheduleTask({
id: factRetriever.id,
frequency: { cron: cronExpression },
fn: this.createFactRetrieverHandler(factRetriever, lifecycle),
timeout: timeLimit,
});
newRegs.push(factRetriever.id);
} catch (e) {
this.logger.warn(
`Failed to schedule fact retriever ${factRetriever.id}, ${e}`,
);
}
}),
);
this.logger.info(
`Scheduled ${newRegs.length} fact retrievers to Fact Retriever Engine through Backend Tasks`,
`Scheduled ${newRegs.length}/${registrations.length} fact retrievers into the tech-insights engine`,
);
}
@@ -114,7 +120,7 @@ export class FactRetrieverEngine {
}
async triggerJob(ref: string): Promise<void> {
return this.scheduler.triggerTask(ref);
await this.scheduler.triggerTask(ref);
}
private createFactRetrieverHandler(
@@ -61,11 +61,10 @@ export type FactRetrieverRegistrationOptions = {
* \{ maxItems: 7 \} -- This fact retriever will leave 7 newest items in the database when it is run
*
*/
export function createFactRetrieverRegistration({
cadence,
factRetriever,
lifecycle,
}: FactRetrieverRegistrationOptions): FactRetrieverRegistration {
export function createFactRetrieverRegistration(
options: FactRetrieverRegistrationOptions,
): FactRetrieverRegistration {
const { cadence, factRetriever, lifecycle } = options;
return {
cadence,
factRetriever,
@@ -124,7 +124,7 @@ export const buildTechInsightsContext = async <
},
});
factRetrieverEngine.schedule();
await factRetrieverEngine.schedule();
if (factCheckerFactory) {
const factChecker = factCheckerFactory.construct(