backend-app-api: rename dependency tree produces -> provides
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user