Skip to content

Commit ec85ecc

Browse files
committed
finish implementing new leader protocol
1 parent d0486e3 commit ec85ecc

File tree

2 files changed

+48
-22
lines changed

2 files changed

+48
-22
lines changed

packages/ember-auto-import/ts/auto-import.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,17 @@ import { AddonInstance, AppInstance, findTopmostAddon } from './ember-cli-models
1111

1212
const debugTree = buildDebugCallback('ember-auto-import');
1313

14-
export default class AutoImport {
14+
// This interface must be stable across all versions of ember-auto-import that
15+
// speak the same leader-election protocol. So don't change this unless you know
16+
// what you're doing.
17+
export interface AutoImportSharedAPI {
18+
isPrimary(addonInstance: AddonInstance): boolean;
19+
analyze(tree: Node, addon: AddonInstance): Node;
20+
included(addonInstance: AddonInstance): void;
21+
updateFastBootManifest(manifest: { vendorFiles: string[] }): void;
22+
}
23+
24+
export default class AutoImport implements AutoImportSharedAPI {
1525
private primaryPackage: AddonInstance;
1626
private packages: Set<Package> = new Set();
1727
private env: 'development' | 'test' | 'production';
@@ -24,7 +34,7 @@ export default class AutoImport {
2434
LeaderChooser.for(addon).register(addon, () => new AutoImport(addon));
2535
}
2636

27-
static lookup(addon: AddonInstance): AutoImport {
37+
static lookup(addon: AddonInstance): AutoImportSharedAPI {
2838
return LeaderChooser.for(addon).leader;
2939
}
3040

@@ -58,7 +68,7 @@ export default class AutoImport {
5868
return analyzer;
5969
}
6070

61-
makeBundler(allAppTree: Node) {
71+
private makeBundler(allAppTree: Node) {
6272
// The Splitter takes the set of imports from the Analyzer and
6373
// decides which ones to include in which bundles
6474
let splitter = new Splitter({

packages/ember-auto-import/ts/leader.ts

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { gt } from "semver";
22
import type AutoImport from "./auto-import";
3-
import { Project, AddonInstance } from './ember-cli-models';
3+
import { Project, AddonInstance } from "./ember-cli-models";
4+
import { Node } from "broccoli-node-api";
45

56
const protocolV1 = "__ember_auto_import_protocol_v1__";
67
const protocolV2 = "__ember_auto_import_protocol_v2__";
@@ -49,33 +50,48 @@ export class LeaderChooser {
4950
this.locked = this.tentative.create();
5051
let v1 = g[protocolV1];
5152
if (v1?.isV1Placeholder) {
52-
g[protocolV1] = this.locked;
53+
v1.leader = this.locked;
5354
}
5455
}
5556
return this.locked;
5657
}
5758
}
5859

60+
class V1Placeholder {
61+
isV1Placeholder = true;
62+
leader: AutoImport | undefined;
63+
64+
// we never want v1-speaking copies of ember-auto-import to consider
65+
// themselves primary, so if they're asking here, the answer is no.
66+
isPrimary() {
67+
return false;
68+
}
69+
70+
// this is the only method that is called after isPrimary returns false. So we
71+
// need to implement this one and don't need to implement the other public API
72+
// of AutoImport.
73+
analyze(tree: Node, addon: AddonInstance) {
74+
if (!this.leader) {
75+
throw new Error(
76+
`bug: expected some protcol v2 copy of ember-auto-import to take charge before any v1 copy started trying to analyze trees`
77+
);
78+
}
79+
return this.leader.analyze(tree, addon);
80+
}
81+
}
82+
5983
// at module load time, preempt all earlier versions of ember-auto-import that
60-
// don't use our v2 protocol for deciding which copy is in charge. This ensures
61-
// that the v2 protocol will pick which version is in charge (and it can't pick
62-
// a v1-speaking copy).
84+
// don't use our v2 leadership protocol. This ensures that the v2 protocol will
85+
// pick which version is in charge (and v1-speaking copies won't be eligible).
6386
(function v1ProtocolCompat() {
6487
let v1 = g[protocolV1];
65-
if (v1 && !v1.isV1Placeholder) {
66-
throw new Error(
67-
`bug: an old version of ember-auto-import has already taken over. This is unexpected.`
68-
);
69-
}
70-
g[protocolV1] = {
71-
isV1Placeholder: true,
72-
analyze() {
88+
if (v1) {
89+
if (!v1.isV1Placeholder) {
7390
throw new Error(
74-
`bug: expected some copy of ember-auto-import to take charge before anybody started trying to analyze trees`
91+
`bug: an old version of ember-auto-import has already taken over. This is unexpected.`
7592
);
76-
},
77-
isPrimary() {
78-
return false;
79-
},
80-
};
93+
}
94+
} else {
95+
g[protocolV1] = new V1Placeholder;
96+
}
8197
})();

0 commit comments

Comments
 (0)