Skip to content

Commit

Permalink
catalog-backend: read all relations at once
Browse files Browse the repository at this point in the history
  • Loading branch information
freben committed Dec 6, 2020
1 parent b6aa734 commit 047c018
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-pillows-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---

Batch the fetching of relations
75 changes: 52 additions & 23 deletions plugins/catalog-backend/src/database/CommonDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ export class CommonDatabase implements Database {
.select('entities.*')
.orderBy('full_name', 'asc');

return Promise.all(rows.map(row => this.toEntityResponse(tx, row)));
return this.toEntityResponses(tx, rows);
}

async entityByName(
Expand All @@ -290,7 +290,7 @@ export class CommonDatabase implements Database {
return undefined;
}

return this.toEntityResponse(tx, rows[0]);
return this.toEntityResponses(tx, rows).then(r => r[0]);
}

async entityByUid(
Expand All @@ -307,7 +307,7 @@ export class CommonDatabase implements Database {
return undefined;
}

return this.toEntityResponse(tx, rows[0]);
return this.toEntityResponses(tx, rows).then(r => r[0]);
}

async removeEntityByUid(txOpaque: Transaction, uid: string): Promise<void> {
Expand Down Expand Up @@ -494,31 +494,60 @@ export class CommonDatabase implements Database {
};
}

private async toEntityResponse(
private async toEntityResponses(
tx: Knex.Transaction<any, any>,
row: DbEntitiesRow,
): Promise<DbEntityResponse> {
const entity = JSON.parse(row.data) as Entity;
entity.metadata.uid = row.id;
entity.metadata.etag = row.etag;
entity.metadata.generation = Number(row.generation); // cast due to sqlite

rows: DbEntitiesRow[],
): Promise<DbEntityResponse[]> {
// TODO(Rugvip): This is here because it's simple for now, but we likely
// need to refactor this to be more efficient or introduce pagination.
const relations = await tx<DbEntitiesRelationsRow>('entities_relations')
.where({ source_full_name: row.full_name })
.orderBy(['type', 'target_full_name'])
.select();
const relations = await this.getRelationsPerFullName(
tx,
rows.map(r => r.full_name),
);

entity.relations = deduplicateRelations(relations).map(r => ({
target: parseEntityName(r.target_full_name),
type: r.type,
}));
const result = new Array<DbEntityResponse>();
for (const row of rows) {
const entity = JSON.parse(row.data) as Entity;
entity.metadata.uid = row.id;
entity.metadata.etag = row.etag;
entity.metadata.generation = Number(row.generation); // cast due to sqlite

entity.relations = (relations[row.full_name] ?? []).map(r => ({
target: parseEntityName(r.target_full_name),
type: r.type,
}));

result.push({
locationId: row.location_id || undefined,
entity,
});
}

return {
locationId: row.location_id || undefined,
entity,
};
return result;
}

// Returns a mapping from e.g. component:default/foo to the relations whose
// source_full_name matches that.
private async getRelationsPerFullName(
tx: Knex.Transaction<any, any>,
sourceFullNames: string[],
): Promise<Record<string, DbEntitiesRelationsRow[]>> {
const batches = lodash.chunk(lodash.uniq(sourceFullNames), 500);

const relations = new Array<DbEntitiesRelationsRow>();
for (const batch of batches) {
relations.push(
...(await tx<DbEntitiesRelationsRow>('entities_relations')
.whereIn('source_full_name', batch)
.orderBy(['type', 'target_full_name'])
.select()),
);
}

return lodash.groupBy(
deduplicateRelations(relations),
r => r.source_full_name,
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class HigherOrderOperations implements HigherOrderOperation {
// Write
if (!previousLocation && !dryRun) {
// TODO: We do not include location operations in the dryRun. We might perform
// this operation as a seperate dry run.
// this operation as a separate dry run.
await this.locationsCatalog.addLocation(location);
}
if (readerOutput.entities.length === 0) {
Expand Down

0 comments on commit 047c018

Please sign in to comment.