backend-app-api: rename dependency tree produces -> provides

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-08-11 14:34:17 +02:00
parent 6ed4759db1
commit a292c9d6d9
3 changed files with 47 additions and 52 deletions
@@ -38,8 +38,8 @@ describe('DependencyTree', () => {
expect(
DependencyTree.fromMap({
1: { produces: ['a'] },
2: { consumes: ['a'], produces: ['b', 'c'] },
1: { provides: ['a'] },
2: { consumes: ['a'], provides: ['b', 'c'] },
3: { consumes: ['b'] },
4: { consumes: ['c'] },
}).detectCircularDependency(),
@@ -47,23 +47,23 @@ describe('DependencyTree', () => {
expect(
DependencyTree.fromMap({
1: { produces: ['a'], consumes: ['a'] },
1: { provides: ['a'], consumes: ['a'] },
}).detectCircularDependency(),
).toEqual(['1', '1']);
expect(
DependencyTree.fromMap({
1: { produces: ['a'], consumes: ['b'] },
2: { produces: ['b'], consumes: ['a'] },
1: { provides: ['a'], consumes: ['b'] },
2: { provides: ['b'], consumes: ['a'] },
}).detectCircularDependency(),
).toEqual(['1', '2', '1']);
expect(
DependencyTree.fromMap({
1: { produces: ['a'] },
2: { produces: ['b'], consumes: ['a', 'e'] },
3: { produces: ['c'], consumes: ['b'] },
4: { produces: ['d', 'e'], consumes: ['c', 'a'] },
1: { provides: ['a'] },
2: { provides: ['b'], consumes: ['a', 'e'] },
3: { provides: ['c'], consumes: ['b'] },
4: { provides: ['d', 'e'], consumes: ['c', 'a'] },
}).detectCircularDependency(),
).toEqual(['2', '3', '4', '2']);
});
@@ -80,8 +80,8 @@ describe('DependencyTree', () => {
expect(
DependencyTree.fromMap({
1: { produces: ['a'] },
2: { consumes: ['a'], produces: ['b', 'c'] },
1: { provides: ['a'] },
2: { consumes: ['a'], provides: ['b', 'c'] },
3: { consumes: ['b'] },
4: { consumes: ['c'] },
}).findUnsatisfiedDeps(),
@@ -95,17 +95,17 @@ describe('DependencyTree', () => {
expect(
DependencyTree.fromMap({
1: { produces: ['a'], consumes: ['b'] },
2: { produces: ['b'], consumes: ['a', 'd', 'e'] },
1: { provides: ['a'], consumes: ['b'] },
2: { provides: ['b'], consumes: ['a', 'd', 'e'] },
}).findUnsatisfiedDeps(),
).toEqual([{ value: '2', unsatisfied: ['d', 'e'] }]);
expect(
DependencyTree.fromMap({
1: { produces: ['a'] },
2: { produces: ['b'], consumes: ['a', 'd', 'e'] },
3: { produces: [], consumes: ['b'] },
4: { produces: [], consumes: ['c', 'a'] },
1: { provides: ['a'] },
2: { provides: ['b'], consumes: ['a', 'd', 'e'] },
3: { provides: [], consumes: ['b'] },
4: { provides: [], consumes: ['c', 'a'] },
}).findUnsatisfiedDeps(),
).toEqual([
{ value: '2', unsatisfied: ['d', 'e'] },
@@ -125,8 +125,8 @@ describe('DependencyTree', () => {
await expect(
DependencyTree.fromMap({
1: { produces: ['a'] },
2: { consumes: ['a'], produces: ['b', 'c'] },
1: { provides: ['a'] },
2: { consumes: ['a'], provides: ['b', 'c'] },
3: { consumes: ['b'] },
4: { consumes: ['c'] },
}).parallelTopologicalTraversal(async id => id),
@@ -135,17 +135,17 @@ describe('DependencyTree', () => {
await expect(
DependencyTree.fromMap({
1: { consumes: ['c'] },
2: { produces: ['c'], consumes: ['b'] },
3: { produces: ['b'], consumes: ['a'] },
4: { produces: ['a'] },
2: { provides: ['c'], consumes: ['b'] },
3: { provides: ['b'], consumes: ['a'] },
4: { provides: ['a'] },
}).parallelTopologicalTraversal(async id => id),
).resolves.toEqual(['4', '3', '2', '1']);
await expect(
DependencyTree.fromMap({
1: { produces: ['a'] },
2: { produces: ['b'], consumes: ['a'] },
3: { produces: ['c'], consumes: ['a'] },
1: { provides: ['a'] },
2: { provides: ['b'], consumes: ['a'] },
3: { provides: ['c'], consumes: ['a'] },
4: { consumes: ['b'] },
5: { consumes: ['c'] },
}).parallelTopologicalTraversal(async id => id),
@@ -154,9 +154,9 @@ describe('DependencyTree', () => {
// Same as above, but with 2 being delayed
await expect(
DependencyTree.fromMap({
1: { produces: ['a'] },
2: { produces: ['b'], consumes: ['a'] },
3: { produces: ['c'], consumes: ['a'] },
1: { provides: ['a'] },
2: { provides: ['b'], consumes: ['a'] },
3: { provides: ['c'], consumes: ['a'] },
4: { consumes: ['b'] },
5: { consumes: ['c'] },
}).parallelTopologicalTraversal(async id => {
@@ -170,20 +170,20 @@ describe('DependencyTree', () => {
await expect(
DependencyTree.fromMap({
1: { produces: ['a'], consumes: ['a'] },
1: { provides: ['a'], consumes: ['a'] },
}).parallelTopologicalTraversal(async id => id),
).rejects.toThrow('Circular dependency detected');
await expect(
DependencyTree.fromMap({
1: { produces: ['a'], consumes: ['b'] },
2: { produces: ['b'], consumes: ['a'] },
1: { provides: ['a'], consumes: ['b'] },
2: { provides: ['b'], consumes: ['a'] },
}).parallelTopologicalTraversal(async id => id),
).rejects.toThrow('Circular dependency detected');
await expect(
DependencyTree.fromMap({
1: { produces: ['a'] },
2: { produces: ['c'], consumes: ['a', 'b'] },
3: { produces: ['b'], consumes: ['a', 'c'] },
1: { provides: ['a'] },
2: { provides: ['c'], consumes: ['a', 'b'] },
3: { provides: ['b'], consumes: ['a', 'c'] },
}).parallelTopologicalTraversal(async id => id),
).rejects.toThrow('Circular dependency detected');
});
@@ -17,7 +17,7 @@
interface NodeInput<T> {
value: T;
consumes?: Iterable<string>;
produces?: Iterable<string>;
provides?: Iterable<string>;
}
/** @internal */
@@ -26,14 +26,14 @@ class Node<T> {
return new Node<T>(
input.value,
input.consumes ? new Set(input.consumes) : new Set(),
input.produces ? new Set(input.produces) : new Set(),
input.provides ? new Set(input.provides) : new Set(),
);
}
private constructor(
readonly value: T,
readonly consumes: Set<string>,
readonly produces: Set<string>,
readonly provides: Set<string>,
) {}
}
@@ -62,20 +62,15 @@ export class DependencyTree<T> {
}
#nodes: Array<Node<T>>;
#allProduced: Set<string>;
#allConsumed: Set<string>;
#allProvided: Set<string>;
private constructor(nodes: Array<Node<T>>) {
this.#nodes = nodes;
this.#allProduced = new Set();
this.#allConsumed = new Set();
this.#allProvided = new Set();
for (const node of this.#nodes.values()) {
for (const produced of node.produces) {
this.#allProduced.add(produced);
}
for (const consumed of node.consumes) {
this.#allConsumed.add(consumed);
for (const produced of node.provides) {
this.#allProvided.add(produced);
}
}
}
@@ -84,7 +79,7 @@ export class DependencyTree<T> {
const unsatisfiedDependencies = [];
for (const node of this.#nodes.values()) {
const unsatisfied = Array.from(node.consumes).filter(
id => !this.#allProduced.has(id),
id => !this.#allProvided.has(id),
);
if (unsatisfied.length > 0) {
unsatisfiedDependencies.push({ value: node.value, unsatisfied });
@@ -107,7 +102,7 @@ export class DependencyTree<T> {
continue;
}
visited.add(node);
for (const produced of node.produces) {
for (const produced of node.provides) {
const consumerNodes = this.#nodes.filter(other =>
other.consumes.has(produced),
);
@@ -128,7 +123,7 @@ export class DependencyTree<T> {
async parallelTopologicalTraversal<TResult>(
fn: (value: T) => Promise<TResult>,
): Promise<TResult[]> {
const allProduced = this.#allProduced;
const allProvided = this.#allProvided;
const producedSoFar = new Set<string>();
const waiting = new Set(this.#nodes.values());
const visited = new Set<Node<T>>();
@@ -143,7 +138,7 @@ export class DependencyTree<T> {
for (const node of waiting) {
let ready = true;
for (const consumed of node.consumes) {
if (allProduced.has(consumed) && !producedSoFar.has(consumed)) {
if (allProvided.has(consumed) && !producedSoFar.has(consumed)) {
ready = false;
continue;
}
@@ -173,7 +168,7 @@ export class DependencyTree<T> {
const result = await fn(node.value);
results.push(result);
node.produces.forEach(produced => producedSoFar.add(produced));
node.provides.forEach(produced => producedSoFar.add(produced));
inFlight -= 1;
await processMoreNodes();
}
@@ -220,7 +220,7 @@ export class BackendInitializer {
// If a modules provides extension point A we want it to be initialized AFTER all modules
// that depend on extension point A, so that they can provide their extensions.
consumes: Array.from(moduleInit.provides).map(p => p.id),
produces: Array.from(moduleInit.consumes).map(c => c.id),
provides: Array.from(moduleInit.consumes).map(c => c.id),
})),
);
const circular = tree.detectCircularDependency();