@atlaspack/core 2.16.2-canary.2 → 2.16.2-canary.20
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/CHANGELOG.md +62 -0
- package/lib/Atlaspack.js +14 -3
- package/lib/RequestTracker.js +131 -11
- package/package.json +17 -17
- package/src/Atlaspack.js +16 -8
- package/src/RequestTracker.js +228 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# @atlaspack/core
|
|
2
2
|
|
|
3
|
+
## 2.17.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`a1773d2`](https://github.com/atlassian-labs/atlaspack/commit/a1773d2a62d0ef7805ac7524621dcabcc1afe929), [`556d6ab`](https://github.com/atlassian-labs/atlaspack/commit/556d6ab8ede759fa7f37fcd3f4da336ef1c55e8f)]:
|
|
8
|
+
- @atlaspack/feature-flags@2.15.0
|
|
9
|
+
- @atlaspack/logger@2.14.7
|
|
10
|
+
- @atlaspack/rust@3.3.2
|
|
11
|
+
- @atlaspack/cache@3.2.2
|
|
12
|
+
- @atlaspack/fs@2.15.2
|
|
13
|
+
- @atlaspack/graph@3.4.5
|
|
14
|
+
- @atlaspack/utils@2.14.7
|
|
15
|
+
- @atlaspack/package-manager@2.14.7
|
|
16
|
+
- @atlaspack/workers@2.14.7
|
|
17
|
+
- @atlaspack/profiler@2.14.5
|
|
18
|
+
- @atlaspack/types@2.14.7
|
|
19
|
+
- @atlaspack/plugin@2.14.7
|
|
20
|
+
|
|
21
|
+
## 2.17.1
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [[`e0f5337`](https://github.com/atlassian-labs/atlaspack/commit/e0f533757bd1019dbd108a04952c87da15286e09)]:
|
|
26
|
+
- @atlaspack/feature-flags@2.14.4
|
|
27
|
+
- @atlaspack/rust@3.3.1
|
|
28
|
+
- @atlaspack/cache@3.2.1
|
|
29
|
+
- @atlaspack/fs@2.15.1
|
|
30
|
+
- @atlaspack/graph@3.4.4
|
|
31
|
+
- @atlaspack/utils@2.14.6
|
|
32
|
+
- @atlaspack/logger@2.14.6
|
|
33
|
+
- @atlaspack/package-manager@2.14.6
|
|
34
|
+
- @atlaspack/profiler@2.14.4
|
|
35
|
+
- @atlaspack/types@2.14.6
|
|
36
|
+
- @atlaspack/workers@2.14.6
|
|
37
|
+
- @atlaspack/plugin@2.14.6
|
|
38
|
+
|
|
39
|
+
## 2.17.0
|
|
40
|
+
|
|
41
|
+
### Minor Changes
|
|
42
|
+
|
|
43
|
+
- [#541](https://github.com/atlassian-labs/atlaspack/pull/541) [`e2ba0f6`](https://github.com/atlassian-labs/atlaspack/commit/e2ba0f69702656f3d1ce95ab1454e35062b13b39) Thanks [@yamadapc](https://github.com/yamadapc)! - Add database compaction debug command
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- [#530](https://github.com/atlassian-labs/atlaspack/pull/530) [`2e90c9b`](https://github.com/atlassian-labs/atlaspack/commit/2e90c9bd07d7eb52645f9d84ccbb7f82685cbc8c) Thanks [@yamadapc](https://github.com/yamadapc)! - Write metadata about the cache in a new entry
|
|
48
|
+
|
|
49
|
+
- [#511](https://github.com/atlassian-labs/atlaspack/pull/511) [`11d6f16`](https://github.com/atlassian-labs/atlaspack/commit/11d6f16b6397dee2f217167e5c98b39edb63f7a7) Thanks [@yamadapc](https://github.com/yamadapc)! - Clean-up dylib worker threads segmentation fault bug fix feature-flag
|
|
50
|
+
|
|
51
|
+
- Updated dependencies [[`11d6f16`](https://github.com/atlassian-labs/atlaspack/commit/11d6f16b6397dee2f217167e5c98b39edb63f7a7), [`e2ba0f6`](https://github.com/atlassian-labs/atlaspack/commit/e2ba0f69702656f3d1ce95ab1454e35062b13b39), [`d2c50c2`](https://github.com/atlassian-labs/atlaspack/commit/d2c50c2c020888b33bb25b8690d9320c2b69e2a6), [`46a90dc`](https://github.com/atlassian-labs/atlaspack/commit/46a90dccd019a26b222c878a92d23acc75dc67c5), [`4c17141`](https://github.com/atlassian-labs/atlaspack/commit/4c1714103dab2aa9039c488f381551d2b65d1d01)]:
|
|
52
|
+
- @atlaspack/feature-flags@2.14.3
|
|
53
|
+
- @atlaspack/rust@3.3.0
|
|
54
|
+
- @atlaspack/cache@3.2.0
|
|
55
|
+
- @atlaspack/fs@2.15.0
|
|
56
|
+
- @atlaspack/graph@3.4.3
|
|
57
|
+
- @atlaspack/utils@2.14.5
|
|
58
|
+
- @atlaspack/logger@2.14.5
|
|
59
|
+
- @atlaspack/package-manager@2.14.5
|
|
60
|
+
- @atlaspack/profiler@2.14.3
|
|
61
|
+
- @atlaspack/types@2.14.5
|
|
62
|
+
- @atlaspack/workers@2.14.5
|
|
63
|
+
- @atlaspack/plugin@2.14.5
|
|
64
|
+
|
|
3
65
|
## 2.16.1
|
|
4
66
|
|
|
5
67
|
### Patch Changes
|
package/lib/Atlaspack.js
CHANGED
|
@@ -166,9 +166,7 @@ class Atlaspack {
|
|
|
166
166
|
...this.#initialOptions.featureFlags
|
|
167
167
|
};
|
|
168
168
|
(0, _featureFlags().setFeatureFlags)(featureFlags);
|
|
169
|
-
|
|
170
|
-
(0, _rustWorkerThreadDylibHack.loadRustWorkerThreadDylibHack)();
|
|
171
|
-
}
|
|
169
|
+
(0, _rustWorkerThreadDylibHack.loadRustWorkerThreadDylibHack)();
|
|
172
170
|
await _sourceMap().init;
|
|
173
171
|
await (_rust().init === null || _rust().init === void 0 ? void 0 : (0, _rust().init)());
|
|
174
172
|
this.#disposable = new (_events().Disposable)();
|
|
@@ -603,6 +601,19 @@ class Atlaspack {
|
|
|
603
601
|
}
|
|
604
602
|
return result;
|
|
605
603
|
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Copy the cache to a new directory and compact it.
|
|
607
|
+
*/
|
|
608
|
+
async unstable_compactCache() {
|
|
609
|
+
await this._init();
|
|
610
|
+
const cache = (0, _nullthrows().default)(this.#resolvedOptions).cache;
|
|
611
|
+
if (cache instanceof _cache().LMDBLiteCache) {
|
|
612
|
+
await cache.compact('parcel-cache-compacted');
|
|
613
|
+
} else {
|
|
614
|
+
throw new Error('Cache is not an LMDBLiteCache');
|
|
615
|
+
}
|
|
616
|
+
}
|
|
606
617
|
async unstable_transform(options) {
|
|
607
618
|
var _options$env;
|
|
608
619
|
if (!this.#initialized) {
|
package/lib/RequestTracker.js
CHANGED
|
@@ -279,6 +279,12 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
279
279
|
// If the node is invalidated, the cached request chunk on disk needs to be re-written
|
|
280
280
|
this.removeCachedRequestChunkForNode(nodeId);
|
|
281
281
|
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Nodes that are invalidated on start-up, such as JavaScript babel configuration files which are
|
|
285
|
+
* imported when the build kicks-off and might doing arbitrary work such as reading from the file
|
|
286
|
+
* system.
|
|
287
|
+
*/
|
|
282
288
|
invalidateUnpredictableNodes() {
|
|
283
289
|
for (let nodeId of this.unpredicatableNodeIds) {
|
|
284
290
|
let node = (0, _nullthrows().default)(this.getNode(nodeId));
|
|
@@ -286,6 +292,10 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
286
292
|
this.invalidateNode(nodeId, _constants.STARTUP);
|
|
287
293
|
}
|
|
288
294
|
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Effectively uncacheable nodes.
|
|
298
|
+
*/
|
|
289
299
|
invalidateOnBuildNodes() {
|
|
290
300
|
for (let nodeId of this.invalidateOnBuildNodeIds) {
|
|
291
301
|
let node = (0, _nullthrows().default)(this.getNode(nodeId));
|
|
@@ -293,29 +303,45 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
293
303
|
this.invalidateNode(nodeId, _constants.STARTUP);
|
|
294
304
|
}
|
|
295
305
|
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Nodes invalidated by environment changes, corresponds to `env: ...` inputs.
|
|
309
|
+
*/
|
|
296
310
|
invalidateEnvNodes(env) {
|
|
311
|
+
const invalidatedKeys = [];
|
|
297
312
|
for (let nodeId of this.envNodeIds) {
|
|
298
313
|
let node = (0, _nullthrows().default)(this.getNode(nodeId));
|
|
299
314
|
(0, _assert().default)(node.type === ENV);
|
|
300
|
-
|
|
315
|
+
const key = keyFromEnvContentKey(node.id);
|
|
316
|
+
if (env[key] !== node.value) {
|
|
317
|
+
invalidatedKeys.push(key);
|
|
301
318
|
let parentNodes = this.getNodeIdsConnectedTo(nodeId, requestGraphEdgeTypes.invalidated_by_update);
|
|
302
319
|
for (let parentNode of parentNodes) {
|
|
303
320
|
this.invalidateNode(parentNode, _constants.ENV_CHANGE);
|
|
304
321
|
}
|
|
305
322
|
}
|
|
306
323
|
}
|
|
324
|
+
return invalidatedKeys;
|
|
307
325
|
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Nodes invalidated by option changes.
|
|
329
|
+
*/
|
|
308
330
|
invalidateOptionNodes(options) {
|
|
331
|
+
const invalidatedKeys = [];
|
|
309
332
|
for (let nodeId of this.optionNodeIds) {
|
|
310
333
|
let node = (0, _nullthrows().default)(this.getNode(nodeId));
|
|
311
334
|
(0, _assert().default)(node.type === OPTION);
|
|
312
|
-
|
|
335
|
+
const key = keyFromOptionContentKey(node.id);
|
|
336
|
+
if ((0, _utils2.hashFromOption)(options[key]) !== node.hash) {
|
|
337
|
+
invalidatedKeys.push(key);
|
|
313
338
|
let parentNodes = this.getNodeIdsConnectedTo(nodeId, requestGraphEdgeTypes.invalidated_by_update);
|
|
314
339
|
for (let parentNode of parentNodes) {
|
|
315
340
|
this.invalidateNode(parentNode, _constants.OPTION_CHANGE);
|
|
316
341
|
}
|
|
317
342
|
}
|
|
318
343
|
}
|
|
344
|
+
return invalidatedKeys;
|
|
319
345
|
}
|
|
320
346
|
invalidateOnConfigKeyChange(requestNodeId, filePath, configKey, contentHash) {
|
|
321
347
|
let configKeyNodeId = this.addNode(nodeFromConfigKey(filePath, configKey, contentHash));
|
|
@@ -1030,6 +1056,13 @@ class RequestTracker {
|
|
|
1030
1056
|
nodeCountsPerBlob,
|
|
1031
1057
|
nodes: undefined
|
|
1032
1058
|
});
|
|
1059
|
+
await runCacheImprovements(() => serialiseAndSet(`request_tracker:cache_metadata:${cacheKey}`, {
|
|
1060
|
+
version: _constants.ATLASPACK_VERSION,
|
|
1061
|
+
entries: this.options.entries,
|
|
1062
|
+
mode: this.options.mode,
|
|
1063
|
+
shouldBuildLazily: this.options.shouldBuildLazily,
|
|
1064
|
+
watchBackend: this.options.watchBackend
|
|
1065
|
+
}), () => Promise.resolve());
|
|
1033
1066
|
let opts = getWatcherOptions(this.options);
|
|
1034
1067
|
let snapshotPath = _path2().default.join(this.options.cacheDir, `snapshot-${cacheKey}` + '.txt');
|
|
1035
1068
|
await this.options.outputFS.writeSnapshot(this.options.watchDir, snapshotPath, opts);
|
|
@@ -1112,12 +1145,22 @@ async function loadRequestGraph(options) {
|
|
|
1112
1145
|
let timeout;
|
|
1113
1146
|
const snapshotKey = `snapshot-${cacheKey}`;
|
|
1114
1147
|
const snapshotPath = _path2().default.join(options.cacheDir, snapshotKey + '.txt');
|
|
1148
|
+
const commonMeta = {
|
|
1149
|
+
cacheKey,
|
|
1150
|
+
snapshotKey,
|
|
1151
|
+
cacheKeyOptions: {
|
|
1152
|
+
version: _constants.ATLASPACK_VERSION,
|
|
1153
|
+
entries: options.entries,
|
|
1154
|
+
mode: options.mode,
|
|
1155
|
+
shouldBuildLazily: options.shouldBuildLazily,
|
|
1156
|
+
watchBackend: options.watchBackend
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1115
1159
|
_logger().default.verbose({
|
|
1116
1160
|
origin: '@atlaspack/core',
|
|
1117
1161
|
message: 'Loading request graph',
|
|
1118
1162
|
meta: {
|
|
1119
|
-
|
|
1120
|
-
snapshotKey
|
|
1163
|
+
...commonMeta
|
|
1121
1164
|
}
|
|
1122
1165
|
});
|
|
1123
1166
|
if (await options.cache.hasLargeBlob(requestGraphKey)) {
|
|
@@ -1139,16 +1182,29 @@ async function loadRequestGraph(options) {
|
|
|
1139
1182
|
origin: '@atlaspack/core',
|
|
1140
1183
|
message: `File system event count: ${events.length}`,
|
|
1141
1184
|
meta: {
|
|
1185
|
+
...commonMeta,
|
|
1142
1186
|
trackableEvent: 'watcher_events_count',
|
|
1143
1187
|
watcherEventCount: events.length,
|
|
1144
1188
|
duration: Date.now() - startTime
|
|
1145
1189
|
}
|
|
1146
1190
|
});
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1191
|
+
if ((0, _featureFlags().getFeatureFlag)('verboseRequestInvalidationStats')) {
|
|
1192
|
+
const invalidationStats = await invalidateRequestGraph(requestGraph, options, events);
|
|
1193
|
+
_logger().default.verbose({
|
|
1194
|
+
origin: '@atlaspack/core',
|
|
1195
|
+
message: 'Request track loaded from cache',
|
|
1196
|
+
meta: {
|
|
1197
|
+
...commonMeta,
|
|
1198
|
+
trackableEvent: 'request_tracker_cache_key_hit',
|
|
1199
|
+
invalidationStats
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
} else {
|
|
1203
|
+
requestGraph.invalidateUnpredictableNodes();
|
|
1204
|
+
requestGraph.invalidateOnBuildNodes();
|
|
1205
|
+
requestGraph.invalidateEnvNodes(options.env);
|
|
1206
|
+
requestGraph.invalidateOptionNodes(options);
|
|
1207
|
+
}
|
|
1152
1208
|
return requestGraph;
|
|
1153
1209
|
} catch (e) {
|
|
1154
1210
|
// Prevent logging fs events took too long warning
|
|
@@ -1163,12 +1219,76 @@ async function loadRequestGraph(options) {
|
|
|
1163
1219
|
origin: '@atlaspack/core',
|
|
1164
1220
|
message: 'Cache entry for request tracker was not found, initializing a clean cache.',
|
|
1165
1221
|
meta: {
|
|
1166
|
-
|
|
1167
|
-
|
|
1222
|
+
...commonMeta,
|
|
1223
|
+
trackableEvent: 'request_tracker_cache_key_miss'
|
|
1168
1224
|
}
|
|
1169
1225
|
});
|
|
1170
1226
|
return new RequestGraph();
|
|
1171
1227
|
}
|
|
1228
|
+
|
|
1229
|
+
/**
|
|
1230
|
+
* A wrapper around an invalidation type / method
|
|
1231
|
+
*/
|
|
1232
|
+
|
|
1233
|
+
/**
|
|
1234
|
+
* Information about a certain cache invalidation type.
|
|
1235
|
+
*/
|
|
1236
|
+
|
|
1237
|
+
/**
|
|
1238
|
+
* Respond to unpredictable, build, environment changes, option changes and file-system events
|
|
1239
|
+
* invalidating RequestGraph nodes.
|
|
1240
|
+
*
|
|
1241
|
+
* Returns the count of nodes invalidated by each invalidation type.
|
|
1242
|
+
*/
|
|
1243
|
+
async function invalidateRequestGraph(requestGraph, options, events) {
|
|
1244
|
+
const invalidationFns = [{
|
|
1245
|
+
key: 'unpredictable',
|
|
1246
|
+
fn: () => requestGraph.invalidateUnpredictableNodes()
|
|
1247
|
+
}, {
|
|
1248
|
+
key: 'onBuild',
|
|
1249
|
+
fn: () => requestGraph.invalidateOnBuildNodes()
|
|
1250
|
+
}, {
|
|
1251
|
+
key: 'env',
|
|
1252
|
+
fn: () => requestGraph.invalidateEnvNodes(options.env)
|
|
1253
|
+
}, {
|
|
1254
|
+
key: 'option',
|
|
1255
|
+
fn: () => requestGraph.invalidateOptionNodes(options)
|
|
1256
|
+
}, {
|
|
1257
|
+
key: 'fsEvents',
|
|
1258
|
+
fn: async () => {
|
|
1259
|
+
await requestGraph.respondToFSEvents(options.unstableFileInvalidations || events, options, 10000, true);
|
|
1260
|
+
}
|
|
1261
|
+
}];
|
|
1262
|
+
const invalidations = [];
|
|
1263
|
+
for (const invalidation of invalidationFns) {
|
|
1264
|
+
invalidations.push(await runInvalidation(requestGraph, invalidation));
|
|
1265
|
+
}
|
|
1266
|
+
const invalidatedCount = invalidations.reduce((acc, invalidation) => acc + invalidation.count, 0);
|
|
1267
|
+
const requestCount = requestGraph.nodes.reduce((acc, node) => acc + ((node === null || node === void 0 ? void 0 : node.type) === REQUEST ? 1 : 0), 0);
|
|
1268
|
+
const nodeCount = requestGraph.nodes.length;
|
|
1269
|
+
return {
|
|
1270
|
+
invalidations,
|
|
1271
|
+
nodeCount,
|
|
1272
|
+
requestCount,
|
|
1273
|
+
invalidatedCount,
|
|
1274
|
+
nodeInvalidationRatio: invalidatedCount / nodeCount,
|
|
1275
|
+
requestInvalidationRatio: invalidatedCount / requestCount
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
/**
|
|
1280
|
+
* Runs an invalidation function and reports metrics.
|
|
1281
|
+
*/
|
|
1282
|
+
async function runInvalidation(requestGraph, invalidationFn) {
|
|
1283
|
+
const startInvalidationCount = requestGraph.invalidNodeIds.size;
|
|
1284
|
+
const result = await invalidationFn.fn();
|
|
1285
|
+
const count = requestGraph.invalidNodeIds.size - startInvalidationCount;
|
|
1286
|
+
return {
|
|
1287
|
+
key: invalidationFn.key,
|
|
1288
|
+
count,
|
|
1289
|
+
changes: typeof result === 'object' && Array.isArray(result) ? result : null
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1172
1292
|
function logErrorOnBailout(options, snapshotPath, e) {
|
|
1173
1293
|
if (e.message && e.message.includes('invalid clockspec')) {
|
|
1174
1294
|
const snapshotContents = options.inputFS.readFileSync(snapshotPath, 'utf-8');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/core",
|
|
3
|
-
"version": "2.16.2-canary.
|
|
3
|
+
"version": "2.16.2-canary.20+30f60175b",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -20,21 +20,21 @@
|
|
|
20
20
|
"check-ts": "tsc --noEmit index.d.ts"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@atlaspack/build-cache": "2.13.3-canary.
|
|
24
|
-
"@atlaspack/cache": "3.1.1-canary.
|
|
25
|
-
"@atlaspack/diagnostic": "2.14.1-canary.
|
|
26
|
-
"@atlaspack/events": "2.14.1-canary.
|
|
27
|
-
"@atlaspack/feature-flags": "2.14.1-canary.
|
|
28
|
-
"@atlaspack/fs": "2.14.5-canary.
|
|
29
|
-
"@atlaspack/graph": "3.4.1-canary.
|
|
30
|
-
"@atlaspack/logger": "2.14.5-canary.
|
|
31
|
-
"@atlaspack/package-manager": "2.14.5-canary.
|
|
32
|
-
"@atlaspack/plugin": "2.14.5-canary.
|
|
33
|
-
"@atlaspack/profiler": "2.14.1-canary.
|
|
34
|
-
"@atlaspack/rust": "3.2.1-canary.
|
|
35
|
-
"@atlaspack/types": "2.14.5-canary.
|
|
36
|
-
"@atlaspack/utils": "2.14.5-canary.
|
|
37
|
-
"@atlaspack/workers": "2.14.5-canary.
|
|
23
|
+
"@atlaspack/build-cache": "2.13.3-canary.88+30f60175b",
|
|
24
|
+
"@atlaspack/cache": "3.1.1-canary.20+30f60175b",
|
|
25
|
+
"@atlaspack/diagnostic": "2.14.1-canary.88+30f60175b",
|
|
26
|
+
"@atlaspack/events": "2.14.1-canary.88+30f60175b",
|
|
27
|
+
"@atlaspack/feature-flags": "2.14.1-canary.88+30f60175b",
|
|
28
|
+
"@atlaspack/fs": "2.14.5-canary.20+30f60175b",
|
|
29
|
+
"@atlaspack/graph": "3.4.1-canary.88+30f60175b",
|
|
30
|
+
"@atlaspack/logger": "2.14.5-canary.20+30f60175b",
|
|
31
|
+
"@atlaspack/package-manager": "2.14.5-canary.20+30f60175b",
|
|
32
|
+
"@atlaspack/plugin": "2.14.5-canary.20+30f60175b",
|
|
33
|
+
"@atlaspack/profiler": "2.14.1-canary.88+30f60175b",
|
|
34
|
+
"@atlaspack/rust": "3.2.1-canary.20+30f60175b",
|
|
35
|
+
"@atlaspack/types": "2.14.5-canary.20+30f60175b",
|
|
36
|
+
"@atlaspack/utils": "2.14.5-canary.20+30f60175b",
|
|
37
|
+
"@atlaspack/workers": "2.14.5-canary.20+30f60175b",
|
|
38
38
|
"@mischnic/json-sourcemap": "^0.1.0",
|
|
39
39
|
"@parcel/source-map": "^2.1.1",
|
|
40
40
|
"base-x": "^3.0.8",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"./src/serializerCore.js": "./src/serializerCore.browser.js"
|
|
68
68
|
},
|
|
69
69
|
"type": "commonjs",
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "30f60175ba4d272c5fc193973c63bc298584775b"
|
|
71
71
|
}
|
package/src/Atlaspack.js
CHANGED
|
@@ -58,11 +58,7 @@ import {
|
|
|
58
58
|
fromProjectPathRelative,
|
|
59
59
|
} from './projectPath';
|
|
60
60
|
import {tracer} from '@atlaspack/profiler';
|
|
61
|
-
import {
|
|
62
|
-
getFeatureFlag,
|
|
63
|
-
setFeatureFlags,
|
|
64
|
-
DEFAULT_FEATURE_FLAGS,
|
|
65
|
-
} from '@atlaspack/feature-flags';
|
|
61
|
+
import {setFeatureFlags, DEFAULT_FEATURE_FLAGS} from '@atlaspack/feature-flags';
|
|
66
62
|
import {AtlaspackV3, FileSystemV3} from './atlaspack-v3';
|
|
67
63
|
import createAssetGraphRequestJS from './requests/AssetGraphRequest';
|
|
68
64
|
import {createAssetGraphRequestRust} from './requests/AssetGraphRequestRust';
|
|
@@ -122,9 +118,7 @@ export default class Atlaspack {
|
|
|
122
118
|
};
|
|
123
119
|
setFeatureFlags(featureFlags);
|
|
124
120
|
|
|
125
|
-
|
|
126
|
-
loadRustWorkerThreadDylibHack();
|
|
127
|
-
}
|
|
121
|
+
loadRustWorkerThreadDylibHack();
|
|
128
122
|
|
|
129
123
|
await initSourcemaps;
|
|
130
124
|
await initRust?.();
|
|
@@ -645,6 +639,20 @@ export default class Atlaspack {
|
|
|
645
639
|
return result;
|
|
646
640
|
}
|
|
647
641
|
|
|
642
|
+
/**
|
|
643
|
+
* Copy the cache to a new directory and compact it.
|
|
644
|
+
*/
|
|
645
|
+
async unstable_compactCache(): Promise<void> {
|
|
646
|
+
await this._init();
|
|
647
|
+
|
|
648
|
+
const cache = nullthrows(this.#resolvedOptions).cache;
|
|
649
|
+
if (cache instanceof LMDBLiteCache) {
|
|
650
|
+
await cache.compact('parcel-cache-compacted');
|
|
651
|
+
} else {
|
|
652
|
+
throw new Error('Cache is not an LMDBLiteCache');
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
648
656
|
async unstable_transform(
|
|
649
657
|
options: AtlaspackTransformOptions,
|
|
650
658
|
): Promise<Array<Asset>> {
|
package/src/RequestTracker.js
CHANGED
|
@@ -446,6 +446,11 @@ export class RequestGraph extends ContentGraph<
|
|
|
446
446
|
this.removeCachedRequestChunkForNode(nodeId);
|
|
447
447
|
}
|
|
448
448
|
|
|
449
|
+
/**
|
|
450
|
+
* Nodes that are invalidated on start-up, such as JavaScript babel configuration files which are
|
|
451
|
+
* imported when the build kicks-off and might doing arbitrary work such as reading from the file
|
|
452
|
+
* system.
|
|
453
|
+
*/
|
|
449
454
|
invalidateUnpredictableNodes() {
|
|
450
455
|
for (let nodeId of this.unpredicatableNodeIds) {
|
|
451
456
|
let node = nullthrows(this.getNode(nodeId));
|
|
@@ -454,6 +459,9 @@ export class RequestGraph extends ContentGraph<
|
|
|
454
459
|
}
|
|
455
460
|
}
|
|
456
461
|
|
|
462
|
+
/**
|
|
463
|
+
* Effectively uncacheable nodes.
|
|
464
|
+
*/
|
|
457
465
|
invalidateOnBuildNodes() {
|
|
458
466
|
for (let nodeId of this.invalidateOnBuildNodeIds) {
|
|
459
467
|
let node = nullthrows(this.getNode(nodeId));
|
|
@@ -462,11 +470,20 @@ export class RequestGraph extends ContentGraph<
|
|
|
462
470
|
}
|
|
463
471
|
}
|
|
464
472
|
|
|
465
|
-
|
|
473
|
+
/**
|
|
474
|
+
* Nodes invalidated by environment changes, corresponds to `env: ...` inputs.
|
|
475
|
+
*/
|
|
476
|
+
invalidateEnvNodes(env: EnvMap): string[] {
|
|
477
|
+
const invalidatedKeys = [];
|
|
478
|
+
|
|
466
479
|
for (let nodeId of this.envNodeIds) {
|
|
467
480
|
let node = nullthrows(this.getNode(nodeId));
|
|
468
481
|
invariant(node.type === ENV);
|
|
469
|
-
|
|
482
|
+
|
|
483
|
+
const key = keyFromEnvContentKey(node.id);
|
|
484
|
+
if (env[key] !== node.value) {
|
|
485
|
+
invalidatedKeys.push(key);
|
|
486
|
+
|
|
470
487
|
let parentNodes = this.getNodeIdsConnectedTo(
|
|
471
488
|
nodeId,
|
|
472
489
|
requestGraphEdgeTypes.invalidated_by_update,
|
|
@@ -476,15 +493,23 @@ export class RequestGraph extends ContentGraph<
|
|
|
476
493
|
}
|
|
477
494
|
}
|
|
478
495
|
}
|
|
496
|
+
|
|
497
|
+
return invalidatedKeys;
|
|
479
498
|
}
|
|
480
499
|
|
|
481
|
-
|
|
500
|
+
/**
|
|
501
|
+
* Nodes invalidated by option changes.
|
|
502
|
+
*/
|
|
503
|
+
invalidateOptionNodes(options: AtlaspackOptions): string[] {
|
|
504
|
+
const invalidatedKeys = [];
|
|
505
|
+
|
|
482
506
|
for (let nodeId of this.optionNodeIds) {
|
|
483
507
|
let node = nullthrows(this.getNode(nodeId));
|
|
484
508
|
invariant(node.type === OPTION);
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
) {
|
|
509
|
+
const key = keyFromOptionContentKey(node.id);
|
|
510
|
+
|
|
511
|
+
if (hashFromOption(options[key]) !== node.hash) {
|
|
512
|
+
invalidatedKeys.push(key);
|
|
488
513
|
let parentNodes = this.getNodeIdsConnectedTo(
|
|
489
514
|
nodeId,
|
|
490
515
|
requestGraphEdgeTypes.invalidated_by_update,
|
|
@@ -494,6 +519,8 @@ export class RequestGraph extends ContentGraph<
|
|
|
494
519
|
}
|
|
495
520
|
}
|
|
496
521
|
}
|
|
522
|
+
|
|
523
|
+
return invalidatedKeys;
|
|
497
524
|
}
|
|
498
525
|
|
|
499
526
|
invalidateOnConfigKeyChange(
|
|
@@ -1605,6 +1632,18 @@ export default class RequestTracker {
|
|
|
1605
1632
|
nodes: undefined,
|
|
1606
1633
|
});
|
|
1607
1634
|
|
|
1635
|
+
await runCacheImprovements(
|
|
1636
|
+
() =>
|
|
1637
|
+
serialiseAndSet(`request_tracker:cache_metadata:${cacheKey}`, {
|
|
1638
|
+
version: ATLASPACK_VERSION,
|
|
1639
|
+
entries: this.options.entries,
|
|
1640
|
+
mode: this.options.mode,
|
|
1641
|
+
shouldBuildLazily: this.options.shouldBuildLazily,
|
|
1642
|
+
watchBackend: this.options.watchBackend,
|
|
1643
|
+
}),
|
|
1644
|
+
() => Promise.resolve(),
|
|
1645
|
+
);
|
|
1646
|
+
|
|
1608
1647
|
let opts = getWatcherOptions(this.options);
|
|
1609
1648
|
let snapshotPath = path.join(this.options.cacheDir, snapshotKey + '.txt');
|
|
1610
1649
|
|
|
@@ -1715,12 +1754,23 @@ async function loadRequestGraph(options): Async<RequestGraph> {
|
|
|
1715
1754
|
const snapshotKey = `snapshot-${cacheKey}`;
|
|
1716
1755
|
const snapshotPath = path.join(options.cacheDir, snapshotKey + '.txt');
|
|
1717
1756
|
|
|
1757
|
+
const commonMeta = {
|
|
1758
|
+
cacheKey,
|
|
1759
|
+
snapshotKey,
|
|
1760
|
+
cacheKeyOptions: {
|
|
1761
|
+
version: ATLASPACK_VERSION,
|
|
1762
|
+
entries: options.entries,
|
|
1763
|
+
mode: options.mode,
|
|
1764
|
+
shouldBuildLazily: options.shouldBuildLazily,
|
|
1765
|
+
watchBackend: options.watchBackend,
|
|
1766
|
+
},
|
|
1767
|
+
};
|
|
1768
|
+
|
|
1718
1769
|
logger.verbose({
|
|
1719
1770
|
origin: '@atlaspack/core',
|
|
1720
1771
|
message: 'Loading request graph',
|
|
1721
1772
|
meta: {
|
|
1722
|
-
|
|
1723
|
-
snapshotKey,
|
|
1773
|
+
...commonMeta,
|
|
1724
1774
|
},
|
|
1725
1775
|
});
|
|
1726
1776
|
|
|
@@ -1755,23 +1805,36 @@ async function loadRequestGraph(options): Async<RequestGraph> {
|
|
|
1755
1805
|
origin: '@atlaspack/core',
|
|
1756
1806
|
message: `File system event count: ${events.length}`,
|
|
1757
1807
|
meta: {
|
|
1808
|
+
...commonMeta,
|
|
1758
1809
|
trackableEvent: 'watcher_events_count',
|
|
1759
1810
|
watcherEventCount: events.length,
|
|
1760
1811
|
duration: Date.now() - startTime,
|
|
1761
1812
|
},
|
|
1762
1813
|
});
|
|
1763
1814
|
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1815
|
+
if (getFeatureFlag('verboseRequestInvalidationStats')) {
|
|
1816
|
+
const invalidationStats = await invalidateRequestGraph(
|
|
1817
|
+
requestGraph,
|
|
1818
|
+
options,
|
|
1819
|
+
events,
|
|
1820
|
+
);
|
|
1821
|
+
|
|
1822
|
+
logger.verbose({
|
|
1823
|
+
origin: '@atlaspack/core',
|
|
1824
|
+
message: 'Request track loaded from cache',
|
|
1825
|
+
meta: {
|
|
1826
|
+
...commonMeta,
|
|
1827
|
+
trackableEvent: 'request_tracker_cache_key_hit',
|
|
1828
|
+
invalidationStats,
|
|
1829
|
+
},
|
|
1830
|
+
});
|
|
1831
|
+
} else {
|
|
1832
|
+
requestGraph.invalidateUnpredictableNodes();
|
|
1833
|
+
requestGraph.invalidateOnBuildNodes();
|
|
1834
|
+
requestGraph.invalidateEnvNodes(options.env);
|
|
1835
|
+
requestGraph.invalidateOptionNodes(options);
|
|
1836
|
+
}
|
|
1768
1837
|
|
|
1769
|
-
await requestGraph.respondToFSEvents(
|
|
1770
|
-
options.unstableFileInvalidations || events,
|
|
1771
|
-
options,
|
|
1772
|
-
10000,
|
|
1773
|
-
true,
|
|
1774
|
-
);
|
|
1775
1838
|
return requestGraph;
|
|
1776
1839
|
} catch (e) {
|
|
1777
1840
|
// Prevent logging fs events took too long warning
|
|
@@ -1788,13 +1851,158 @@ async function loadRequestGraph(options): Async<RequestGraph> {
|
|
|
1788
1851
|
message:
|
|
1789
1852
|
'Cache entry for request tracker was not found, initializing a clean cache.',
|
|
1790
1853
|
meta: {
|
|
1791
|
-
|
|
1792
|
-
|
|
1854
|
+
...commonMeta,
|
|
1855
|
+
trackableEvent: 'request_tracker_cache_key_miss',
|
|
1793
1856
|
},
|
|
1794
1857
|
});
|
|
1795
1858
|
return new RequestGraph();
|
|
1796
1859
|
}
|
|
1797
1860
|
|
|
1861
|
+
/**
|
|
1862
|
+
* A wrapper around an invalidation type / method
|
|
1863
|
+
*/
|
|
1864
|
+
type InvalidationFn = {|
|
|
1865
|
+
key: string,
|
|
1866
|
+
fn: () => string[] | void | Promise<void>,
|
|
1867
|
+
|};
|
|
1868
|
+
|
|
1869
|
+
type InvalidationStats = {|
|
|
1870
|
+
/**
|
|
1871
|
+
* Total number of request graph nodes
|
|
1872
|
+
*/
|
|
1873
|
+
nodeCount: number,
|
|
1874
|
+
/**
|
|
1875
|
+
* Number of requests in RequestGraph
|
|
1876
|
+
*/
|
|
1877
|
+
requestCount: number,
|
|
1878
|
+
/**
|
|
1879
|
+
* Number of nodes that have been invalidated.
|
|
1880
|
+
*/
|
|
1881
|
+
invalidatedCount: number,
|
|
1882
|
+
/**
|
|
1883
|
+
* Percentage of requests that have been invalidated
|
|
1884
|
+
*/
|
|
1885
|
+
requestInvalidationRatio: number,
|
|
1886
|
+
/**
|
|
1887
|
+
* Percentage of nodes that have been invalidated
|
|
1888
|
+
*/
|
|
1889
|
+
nodeInvalidationRatio: number,
|
|
1890
|
+
/**
|
|
1891
|
+
* Details for each invalidation type
|
|
1892
|
+
*/
|
|
1893
|
+
invalidations: InvalidationFnStats[],
|
|
1894
|
+
|};
|
|
1895
|
+
|
|
1896
|
+
/**
|
|
1897
|
+
* Information about a certain cache invalidation type.
|
|
1898
|
+
*/
|
|
1899
|
+
type InvalidationFnStats = {|
|
|
1900
|
+
/**
|
|
1901
|
+
* Invalidation type, one of:
|
|
1902
|
+
*
|
|
1903
|
+
* - unpredictable
|
|
1904
|
+
* - onBuild
|
|
1905
|
+
* - env
|
|
1906
|
+
* - option
|
|
1907
|
+
* - fsEvents
|
|
1908
|
+
*/
|
|
1909
|
+
key: string,
|
|
1910
|
+
/**
|
|
1911
|
+
* Number of invalidated nodes coming from this invalidation type.
|
|
1912
|
+
*/
|
|
1913
|
+
count: number,
|
|
1914
|
+
/**
|
|
1915
|
+
* If this is a env or option invalidation, this key will contain the list of changed values.
|
|
1916
|
+
*/
|
|
1917
|
+
changes: null | string[],
|
|
1918
|
+
|};
|
|
1919
|
+
|
|
1920
|
+
/**
|
|
1921
|
+
* Respond to unpredictable, build, environment changes, option changes and file-system events
|
|
1922
|
+
* invalidating RequestGraph nodes.
|
|
1923
|
+
*
|
|
1924
|
+
* Returns the count of nodes invalidated by each invalidation type.
|
|
1925
|
+
*/
|
|
1926
|
+
async function invalidateRequestGraph(
|
|
1927
|
+
requestGraph: RequestGraph,
|
|
1928
|
+
options: AtlaspackOptions,
|
|
1929
|
+
events: Event[],
|
|
1930
|
+
): Promise<InvalidationStats> {
|
|
1931
|
+
const invalidationFns: InvalidationFn[] = [
|
|
1932
|
+
{
|
|
1933
|
+
key: 'unpredictable',
|
|
1934
|
+
fn: () => requestGraph.invalidateUnpredictableNodes(),
|
|
1935
|
+
},
|
|
1936
|
+
{
|
|
1937
|
+
key: 'onBuild',
|
|
1938
|
+
fn: () => requestGraph.invalidateOnBuildNodes(),
|
|
1939
|
+
},
|
|
1940
|
+
{
|
|
1941
|
+
key: 'env',
|
|
1942
|
+
fn: () => requestGraph.invalidateEnvNodes(options.env),
|
|
1943
|
+
},
|
|
1944
|
+
{
|
|
1945
|
+
key: 'option',
|
|
1946
|
+
fn: () => requestGraph.invalidateOptionNodes(options),
|
|
1947
|
+
},
|
|
1948
|
+
{
|
|
1949
|
+
key: 'fsEvents',
|
|
1950
|
+
fn: async () => {
|
|
1951
|
+
await requestGraph.respondToFSEvents(
|
|
1952
|
+
options.unstableFileInvalidations || events,
|
|
1953
|
+
options,
|
|
1954
|
+
10000,
|
|
1955
|
+
true,
|
|
1956
|
+
);
|
|
1957
|
+
},
|
|
1958
|
+
},
|
|
1959
|
+
];
|
|
1960
|
+
|
|
1961
|
+
const invalidations = [];
|
|
1962
|
+
for (const invalidation of invalidationFns) {
|
|
1963
|
+
invalidations.push(await runInvalidation(requestGraph, invalidation));
|
|
1964
|
+
}
|
|
1965
|
+
const invalidatedCount = invalidations.reduce(
|
|
1966
|
+
(acc, invalidation) => acc + invalidation.count,
|
|
1967
|
+
0,
|
|
1968
|
+
);
|
|
1969
|
+
const requestCount = requestGraph.nodes.reduce(
|
|
1970
|
+
(acc, node) => acc + (node?.type === REQUEST ? 1 : 0),
|
|
1971
|
+
0,
|
|
1972
|
+
);
|
|
1973
|
+
const nodeCount = requestGraph.nodes.length;
|
|
1974
|
+
const nodeInvalidationRatio = invalidatedCount / nodeCount;
|
|
1975
|
+
const requestInvalidationRatio = invalidatedCount / requestCount;
|
|
1976
|
+
|
|
1977
|
+
return {
|
|
1978
|
+
invalidations,
|
|
1979
|
+
nodeCount,
|
|
1980
|
+
requestCount,
|
|
1981
|
+
invalidatedCount,
|
|
1982
|
+
nodeInvalidationRatio,
|
|
1983
|
+
requestInvalidationRatio,
|
|
1984
|
+
};
|
|
1985
|
+
}
|
|
1986
|
+
|
|
1987
|
+
/**
|
|
1988
|
+
* Runs an invalidation function and reports metrics.
|
|
1989
|
+
*/
|
|
1990
|
+
async function runInvalidation(
|
|
1991
|
+
requestGraph: RequestGraph,
|
|
1992
|
+
invalidationFn: InvalidationFn,
|
|
1993
|
+
): Promise<InvalidationFnStats> {
|
|
1994
|
+
const startInvalidationCount = requestGraph.invalidNodeIds.size;
|
|
1995
|
+
const result = await invalidationFn.fn();
|
|
1996
|
+
const count = requestGraph.invalidNodeIds.size - startInvalidationCount;
|
|
1997
|
+
|
|
1998
|
+
return {
|
|
1999
|
+
key: invalidationFn.key,
|
|
2000
|
+
count,
|
|
2001
|
+
changes:
|
|
2002
|
+
typeof result === 'object' && Array.isArray(result) ? result : null,
|
|
2003
|
+
};
|
|
2004
|
+
}
|
|
2005
|
+
|
|
1798
2006
|
function logErrorOnBailout(
|
|
1799
2007
|
options: AtlaspackOptions,
|
|
1800
2008
|
snapshotPath: string,
|