@atlaspack/core 2.12.1-canary.3425 → 2.12.1-canary.3426
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/RequestTracker.js +32 -5
- package/package.json +16 -16
- package/src/RequestTracker.js +29 -4
- package/test/RequestTracker.test.js +45 -1
package/lib/RequestTracker.js
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.RequestGraph = void 0;
|
|
7
|
+
exports.cleanUpOrphans = cleanUpOrphans;
|
|
8
|
+
exports.default = void 0;
|
|
7
9
|
exports.getWatcherOptions = getWatcherOptions;
|
|
8
10
|
exports.readAndDeserializeRequestGraph = readAndDeserializeRequestGraph;
|
|
9
11
|
exports.requestTypes = exports.requestGraphEdgeTypes = void 0;
|
|
@@ -21,6 +23,13 @@ function _path2() {
|
|
|
21
23
|
};
|
|
22
24
|
return data;
|
|
23
25
|
}
|
|
26
|
+
function _featureFlags() {
|
|
27
|
+
const data = require("@atlaspack/feature-flags");
|
|
28
|
+
_featureFlags = function () {
|
|
29
|
+
return data;
|
|
30
|
+
};
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
24
33
|
function _graph() {
|
|
25
34
|
const data = require("@atlaspack/graph");
|
|
26
35
|
_graph = function () {
|
|
@@ -204,7 +213,7 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
204
213
|
this.removeCachedRequestChunkForNode(nodeId);
|
|
205
214
|
return nodeId;
|
|
206
215
|
}
|
|
207
|
-
removeNode(nodeId) {
|
|
216
|
+
removeNode(nodeId, removeOrphans = true) {
|
|
208
217
|
this.invalidNodeIds.delete(nodeId);
|
|
209
218
|
this.incompleteNodeIds.delete(nodeId);
|
|
210
219
|
this.incompleteNodePromises.delete(nodeId);
|
|
@@ -222,7 +231,7 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
222
231
|
configKeyNodes.delete(nodeId);
|
|
223
232
|
}
|
|
224
233
|
}
|
|
225
|
-
return super.removeNode(nodeId);
|
|
234
|
+
return super.removeNode(nodeId, removeOrphans);
|
|
226
235
|
}
|
|
227
236
|
getRequestNode(nodeId) {
|
|
228
237
|
let node = (0, _nullthrows().default)(this.getNode(nodeId));
|
|
@@ -489,6 +498,7 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
489
498
|
let count = 0;
|
|
490
499
|
let predictedTime = 0;
|
|
491
500
|
let startTime = Date.now();
|
|
501
|
+
const removeOrphans = !(0, _featureFlags().getFeatureFlag)('fixQuadraticCacheInvalidation');
|
|
492
502
|
for (let {
|
|
493
503
|
path: _path,
|
|
494
504
|
type
|
|
@@ -590,7 +600,7 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
590
600
|
// Delete the file node since it doesn't exist anymore.
|
|
591
601
|
// This ensures that files that don't exist aren't sent
|
|
592
602
|
// to requests as invalidations for future requests.
|
|
593
|
-
this.removeNode(nodeId);
|
|
603
|
+
this.removeNode(nodeId, removeOrphans);
|
|
594
604
|
}
|
|
595
605
|
let configKeyNodes = this.configKeyNodes.get(_filePath);
|
|
596
606
|
if (configKeyNodes && (type === 'delete' || type === 'update')) {
|
|
@@ -607,11 +617,14 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
607
617
|
this.invalidateNode(connectedNode, type === 'delete' ? _constants.FILE_DELETE : _constants.FILE_UPDATE);
|
|
608
618
|
}
|
|
609
619
|
didInvalidate = true;
|
|
610
|
-
this.removeNode(nodeId);
|
|
620
|
+
this.removeNode(nodeId, removeOrphans);
|
|
611
621
|
}
|
|
612
622
|
}
|
|
613
623
|
}
|
|
614
624
|
}
|
|
625
|
+
if ((0, _featureFlags().getFeatureFlag)('fixQuadraticCacheInvalidation')) {
|
|
626
|
+
cleanUpOrphans(this);
|
|
627
|
+
}
|
|
615
628
|
let duration = Date.now() - startTime;
|
|
616
629
|
_logger().default.verbose({
|
|
617
630
|
origin: '@atlaspack/core',
|
|
@@ -1086,4 +1099,18 @@ function logErrorOnBailout(options, snapshotPath, e) {
|
|
|
1086
1099
|
}
|
|
1087
1100
|
});
|
|
1088
1101
|
}
|
|
1102
|
+
}
|
|
1103
|
+
function cleanUpOrphans(graph) {
|
|
1104
|
+
const reachableNodes = new Set();
|
|
1105
|
+
graph.traverse(nodeId => {
|
|
1106
|
+
reachableNodes.add(nodeId);
|
|
1107
|
+
});
|
|
1108
|
+
const removedNodeIds = [];
|
|
1109
|
+
graph.nodes.forEach((_node, nodeId) => {
|
|
1110
|
+
if (!reachableNodes.has(nodeId)) {
|
|
1111
|
+
removedNodeIds.push(nodeId);
|
|
1112
|
+
graph.removeNode(nodeId);
|
|
1113
|
+
}
|
|
1114
|
+
});
|
|
1115
|
+
return removedNodeIds;
|
|
1089
1116
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/core",
|
|
3
|
-
"version": "2.12.1-canary.
|
|
3
|
+
"version": "2.12.1-canary.3426+9ec24d923",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -20,20 +20,20 @@
|
|
|
20
20
|
"check-ts": "tsc --noEmit index.d.ts"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@atlaspack/cache": "2.12.1-canary.
|
|
24
|
-
"@atlaspack/diagnostic": "2.12.1-canary.
|
|
25
|
-
"@atlaspack/events": "2.12.1-canary.
|
|
26
|
-
"@atlaspack/feature-flags": "2.12.1-canary.
|
|
27
|
-
"@atlaspack/fs": "2.12.1-canary.
|
|
28
|
-
"@atlaspack/graph": "3.2.1-canary.
|
|
29
|
-
"@atlaspack/logger": "2.12.1-canary.
|
|
30
|
-
"@atlaspack/package-manager": "2.12.1-canary.
|
|
31
|
-
"@atlaspack/plugin": "2.12.1-canary.
|
|
32
|
-
"@atlaspack/profiler": "2.12.1-canary.
|
|
33
|
-
"@atlaspack/rust": "2.12.1-canary.
|
|
34
|
-
"@atlaspack/types": "2.12.1-canary.
|
|
35
|
-
"@atlaspack/utils": "2.12.1-canary.
|
|
36
|
-
"@atlaspack/workers": "2.12.1-canary.
|
|
23
|
+
"@atlaspack/cache": "2.12.1-canary.3426+9ec24d923",
|
|
24
|
+
"@atlaspack/diagnostic": "2.12.1-canary.3426+9ec24d923",
|
|
25
|
+
"@atlaspack/events": "2.12.1-canary.3426+9ec24d923",
|
|
26
|
+
"@atlaspack/feature-flags": "2.12.1-canary.3426+9ec24d923",
|
|
27
|
+
"@atlaspack/fs": "2.12.1-canary.3426+9ec24d923",
|
|
28
|
+
"@atlaspack/graph": "3.2.1-canary.3426+9ec24d923",
|
|
29
|
+
"@atlaspack/logger": "2.12.1-canary.3426+9ec24d923",
|
|
30
|
+
"@atlaspack/package-manager": "2.12.1-canary.3426+9ec24d923",
|
|
31
|
+
"@atlaspack/plugin": "2.12.1-canary.3426+9ec24d923",
|
|
32
|
+
"@atlaspack/profiler": "2.12.1-canary.3426+9ec24d923",
|
|
33
|
+
"@atlaspack/rust": "2.12.1-canary.3426+9ec24d923",
|
|
34
|
+
"@atlaspack/types": "2.12.1-canary.3426+9ec24d923",
|
|
35
|
+
"@atlaspack/utils": "2.12.1-canary.3426+9ec24d923",
|
|
36
|
+
"@atlaspack/workers": "2.12.1-canary.3426+9ec24d923",
|
|
37
37
|
"@mischnic/json-sourcemap": "^0.1.0",
|
|
38
38
|
"@parcel/source-map": "^2.1.1",
|
|
39
39
|
"base-x": "^3.0.8",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"browser": {
|
|
56
56
|
"./src/serializerCore.js": "./src/serializerCore.browser.js"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "9ec24d923e4361f97bcc64c967c066fbebb7f4b4"
|
|
59
59
|
}
|
package/src/RequestTracker.js
CHANGED
|
@@ -4,12 +4,14 @@ import invariant, {AssertionError} from 'assert';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
|
|
6
6
|
import type {Cache} from '@atlaspack/cache';
|
|
7
|
+
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
7
8
|
import {ContentGraph} from '@atlaspack/graph';
|
|
8
9
|
import type {
|
|
9
10
|
ContentGraphOpts,
|
|
10
11
|
ContentKey,
|
|
11
12
|
NodeId,
|
|
12
13
|
SerializedContentGraph,
|
|
14
|
+
Graph,
|
|
13
15
|
} from '@atlaspack/graph';
|
|
14
16
|
import logger from '@atlaspack/logger';
|
|
15
17
|
import {hashString} from '@atlaspack/rust';
|
|
@@ -370,7 +372,7 @@ export class RequestGraph extends ContentGraph<
|
|
|
370
372
|
return nodeId;
|
|
371
373
|
}
|
|
372
374
|
|
|
373
|
-
removeNode(nodeId: NodeId): void {
|
|
375
|
+
removeNode(nodeId: NodeId, removeOrphans: boolean = true): void {
|
|
374
376
|
this.invalidNodeIds.delete(nodeId);
|
|
375
377
|
this.incompleteNodeIds.delete(nodeId);
|
|
376
378
|
this.incompleteNodePromises.delete(nodeId);
|
|
@@ -388,7 +390,7 @@ export class RequestGraph extends ContentGraph<
|
|
|
388
390
|
configKeyNodes.delete(nodeId);
|
|
389
391
|
}
|
|
390
392
|
}
|
|
391
|
-
return super.removeNode(nodeId);
|
|
393
|
+
return super.removeNode(nodeId, removeOrphans);
|
|
392
394
|
}
|
|
393
395
|
|
|
394
396
|
getRequestNode(nodeId: NodeId): RequestNode {
|
|
@@ -878,6 +880,7 @@ export class RequestGraph extends ContentGraph<
|
|
|
878
880
|
let count = 0;
|
|
879
881
|
let predictedTime = 0;
|
|
880
882
|
let startTime = Date.now();
|
|
883
|
+
const removeOrphans = !getFeatureFlag('fixQuadraticCacheInvalidation');
|
|
881
884
|
|
|
882
885
|
for (let {path: _path, type} of events) {
|
|
883
886
|
if (++count === 256) {
|
|
@@ -1004,7 +1007,7 @@ export class RequestGraph extends ContentGraph<
|
|
|
1004
1007
|
// Delete the file node since it doesn't exist anymore.
|
|
1005
1008
|
// This ensures that files that don't exist aren't sent
|
|
1006
1009
|
// to requests as invalidations for future requests.
|
|
1007
|
-
this.removeNode(nodeId);
|
|
1010
|
+
this.removeNode(nodeId, removeOrphans);
|
|
1008
1011
|
}
|
|
1009
1012
|
|
|
1010
1013
|
let configKeyNodes = this.configKeyNodes.get(_filePath);
|
|
@@ -1036,12 +1039,16 @@ export class RequestGraph extends ContentGraph<
|
|
|
1036
1039
|
);
|
|
1037
1040
|
}
|
|
1038
1041
|
didInvalidate = true;
|
|
1039
|
-
this.removeNode(nodeId);
|
|
1042
|
+
this.removeNode(nodeId, removeOrphans);
|
|
1040
1043
|
}
|
|
1041
1044
|
}
|
|
1042
1045
|
}
|
|
1043
1046
|
}
|
|
1044
1047
|
|
|
1048
|
+
if (getFeatureFlag('fixQuadraticCacheInvalidation')) {
|
|
1049
|
+
cleanUpOrphans(this);
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1045
1052
|
let duration = Date.now() - startTime;
|
|
1046
1053
|
logger.verbose({
|
|
1047
1054
|
origin: '@atlaspack/core',
|
|
@@ -1665,6 +1672,7 @@ async function loadRequestGraph(options): Async<RequestGraph> {
|
|
|
1665
1672
|
|
|
1666
1673
|
return new RequestGraph();
|
|
1667
1674
|
}
|
|
1675
|
+
|
|
1668
1676
|
function logErrorOnBailout(
|
|
1669
1677
|
options: AtlaspackOptions,
|
|
1670
1678
|
snapshotPath: string,
|
|
@@ -1695,3 +1703,20 @@ function logErrorOnBailout(
|
|
|
1695
1703
|
});
|
|
1696
1704
|
}
|
|
1697
1705
|
}
|
|
1706
|
+
|
|
1707
|
+
export function cleanUpOrphans<N, E: number>(graph: Graph<N, E>): NodeId[] {
|
|
1708
|
+
const reachableNodes = new Set();
|
|
1709
|
+
graph.traverse(nodeId => {
|
|
1710
|
+
reachableNodes.add(nodeId);
|
|
1711
|
+
});
|
|
1712
|
+
|
|
1713
|
+
const removedNodeIds = [];
|
|
1714
|
+
graph.nodes.forEach((_node, nodeId) => {
|
|
1715
|
+
if (!reachableNodes.has(nodeId)) {
|
|
1716
|
+
removedNodeIds.push(nodeId);
|
|
1717
|
+
graph.removeNode(nodeId);
|
|
1718
|
+
}
|
|
1719
|
+
});
|
|
1720
|
+
|
|
1721
|
+
return removedNodeIds;
|
|
1722
|
+
}
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import assert from 'assert';
|
|
4
4
|
import nullthrows from 'nullthrows';
|
|
5
|
-
import RequestTracker, {
|
|
5
|
+
import RequestTracker, {
|
|
6
|
+
type RunAPI,
|
|
7
|
+
cleanUpOrphans,
|
|
8
|
+
} from '../src/RequestTracker';
|
|
9
|
+
import {Graph} from '@atlaspack/graph';
|
|
6
10
|
import WorkerFarm from '@atlaspack/workers';
|
|
7
11
|
import {DEFAULT_OPTIONS} from './test-utils';
|
|
8
12
|
import {INITIAL_BUILD} from '../src/constants';
|
|
@@ -446,3 +450,43 @@ describe('RequestTracker', () => {
|
|
|
446
450
|
assert.equal(tracker.graph.getNode(nodeId)?.invalidateReason, 1);
|
|
447
451
|
});
|
|
448
452
|
});
|
|
453
|
+
|
|
454
|
+
describe('cleanUpOrphans', () => {
|
|
455
|
+
it('cleans-up unreachable nodes', () => {
|
|
456
|
+
const graph: Graph<string, number> = new Graph();
|
|
457
|
+
const root = graph.addNode('root');
|
|
458
|
+
graph.setRootNodeId(root);
|
|
459
|
+
const node1 = graph.addNode('node1');
|
|
460
|
+
const node2 = graph.addNode('node2');
|
|
461
|
+
const node3 = graph.addNode('node3');
|
|
462
|
+
const orphan1 = graph.addNode('orphan1');
|
|
463
|
+
const orphan2 = graph.addNode('orphan2');
|
|
464
|
+
|
|
465
|
+
/*
|
|
466
|
+
|
|
467
|
+
root --- node1 --- node2 ----------- orphan1 --- orphan2
|
|
468
|
+
\---- node3 (^ remove)
|
|
469
|
+
|
|
470
|
+
*/
|
|
471
|
+
|
|
472
|
+
const getNonNullNodes = graph => graph.nodes.filter(node => node != null);
|
|
473
|
+
|
|
474
|
+
graph.addEdge(root, node1);
|
|
475
|
+
graph.addEdge(node1, node2);
|
|
476
|
+
graph.addEdge(node2, orphan1);
|
|
477
|
+
graph.addEdge(orphan1, orphan2);
|
|
478
|
+
graph.addEdge(root, node3);
|
|
479
|
+
|
|
480
|
+
assert.deepEqual(cleanUpOrphans(graph), []);
|
|
481
|
+
assert.equal(getNonNullNodes(graph).length, 6);
|
|
482
|
+
assert.equal(Array.from(graph.getAllEdges()).length, 5);
|
|
483
|
+
|
|
484
|
+
graph.removeEdge(node2, orphan1, 1, false);
|
|
485
|
+
assert.equal(getNonNullNodes(graph).length, 6);
|
|
486
|
+
assert.equal(Array.from(graph.getAllEdges()).length, 4);
|
|
487
|
+
|
|
488
|
+
assert.deepEqual(cleanUpOrphans(graph), [orphan1, orphan2]);
|
|
489
|
+
assert.equal(getNonNullNodes(graph).length, 4);
|
|
490
|
+
assert.equal(Array.from(graph.getAllEdges()).length, 3);
|
|
491
|
+
});
|
|
492
|
+
});
|