Merge pull request #12448 from sblausten/fact-retriever-async

Make FactRetrieverRegistry async so we can use db backed implementation
This commit is contained in:
Patrik Oldsberg
2022-07-06 14:19:45 +02:00
committed by GitHub
5 changed files with 42 additions and 32 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-tech-insights-backend': minor
---
**BREAKING**: Update FactRetrieverRegistry interface to be async so that db backed implementations can be passed through to the FactRetrieverEngine.
If you have existing custom `FactRetrieverRegistry` implementations, you'll need to remove the `retrievers` member and make all the methods async.
+5 -7
View File
@@ -55,17 +55,15 @@ export type FactRetrieverRegistrationOptions = {
// @public (undocumented)
export interface FactRetrieverRegistry {
// (undocumented)
get(retrieverReference: string): FactRetrieverRegistration;
get(retrieverReference: string): Promise<FactRetrieverRegistration>;
// (undocumented)
getSchemas(): FactSchema[];
getSchemas(): Promise<FactSchema[]>;
// (undocumented)
listRegistrations(): FactRetrieverRegistration[];
listRegistrations(): Promise<FactRetrieverRegistration[]>;
// (undocumented)
listRetrievers(): FactRetriever[];
listRetrievers(): Promise<FactRetriever[]>;
// (undocumented)
register(registration: FactRetrieverRegistration): void;
// (undocumented)
readonly retrievers: Map<string, FactRetrieverRegistration>;
register(registration: FactRetrieverRegistration): Promise<void>;
}
// @public
@@ -206,9 +206,7 @@ describe('FactRetrieverEngine', () => {
{ ...testFactRetriever, handler },
);
await engine.schedule();
const job: FactRetrieverRegistration = engine.getJobRegistration(
testFactRetriever.id,
);
const job = await engine.getJobRegistration(testFactRetriever.id);
expect(job.cadence!!).toEqual(defaultCadence);
await engine.triggerJob(job.factRetriever.id);
@@ -66,11 +66,8 @@ export class FactRetrieverEngine {
defaultTimeout,
} = options;
await Promise.all(
factRetrieverRegistry
.listRetrievers()
.map(it => repository.insertFactSchema(it)),
);
const retrievers = await factRetrieverRegistry.listRetrievers();
await Promise.all(retrievers.map(it => repository.insertFactSchema(it)));
return new FactRetrieverEngine(
repository,
@@ -84,7 +81,7 @@ export class FactRetrieverEngine {
}
async schedule() {
const registrations = this.factRetrieverRegistry.listRegistrations();
const registrations = await this.factRetrieverRegistry.listRegistrations();
const newRegs: string[] = [];
await Promise.all(
@@ -115,7 +112,7 @@ export class FactRetrieverEngine {
);
}
getJobRegistration(ref: string): FactRetrieverRegistration {
getJobRegistration(ref: string): Promise<FactRetrieverRegistration> {
return this.factRetrieverRegistry.get(ref);
}
@@ -26,24 +26,29 @@ import { ConflictError, NotFoundError } from '@backstage/errors';
*
*/
export interface FactRetrieverRegistry {
readonly retrievers: Map<string, FactRetrieverRegistration>;
register(registration: FactRetrieverRegistration): void;
get(retrieverReference: string): FactRetrieverRegistration;
listRetrievers(): FactRetriever[];
listRegistrations(): FactRetrieverRegistration[];
getSchemas(): FactSchema[];
register(registration: FactRetrieverRegistration): Promise<void>;
get(retrieverReference: string): Promise<FactRetrieverRegistration>;
listRetrievers(): Promise<FactRetriever[]>;
listRegistrations(): Promise<FactRetrieverRegistration[]>;
getSchemas(): Promise<FactSchema[]>;
}
/**
* A basic in memory fact retriever registry.
*
* You can replace this with a persistance based version using the FactRetrieverRegistry interface.
*
*/
export class DefaultFactRetrieverRegistry implements FactRetrieverRegistry {
readonly retrievers = new Map<string, FactRetrieverRegistration>();
private readonly retrievers = new Map<string, FactRetrieverRegistration>();
constructor(retrievers: FactRetrieverRegistration[]) {
retrievers.forEach(it => {
this.register(it);
retrievers.forEach(r => {
this.registerSync(r);
});
}
register(registration: FactRetrieverRegistration) {
registerSync(registration: FactRetrieverRegistration) {
if (this.retrievers.has(registration.factRetriever.id)) {
throw new ConflictError(
`Tech insight fact retriever with identifier '${registration.factRetriever.id}' has already been registered`,
@@ -52,7 +57,11 @@ export class DefaultFactRetrieverRegistry implements FactRetrieverRegistry {
this.retrievers.set(registration.factRetriever.id, registration);
}
get(retrieverReference: string): FactRetrieverRegistration {
async register(registration: FactRetrieverRegistration) {
this.registerSync(registration);
}
async get(retrieverReference: string): Promise<FactRetrieverRegistration> {
const registration = this.retrievers.get(retrieverReference);
if (!registration) {
throw new NotFoundError(
@@ -62,15 +71,16 @@ export class DefaultFactRetrieverRegistry implements FactRetrieverRegistry {
return registration;
}
listRetrievers(): FactRetriever[] {
async listRetrievers(): Promise<FactRetriever[]> {
return [...this.retrievers.values()].map(it => it.factRetriever);
}
listRegistrations(): FactRetrieverRegistration[] {
async listRegistrations(): Promise<FactRetrieverRegistration[]> {
return [...this.retrievers.values()];
}
getSchemas(): FactSchema[] {
return this.listRetrievers().map(it => it.schema);
async getSchemas(): Promise<FactSchema[]> {
const retrievers = await this.listRetrievers();
return retrievers.map(it => it.schema);
}
}