@atlaspack/core 2.17.3 → 2.17.4
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 +26 -0
- package/lib/Atlaspack.js +3 -1
- package/lib/PackagerRunner.js +42 -8
- package/lib/RequestTracker.js +171 -84
- package/lib/UncommittedAsset.js +17 -0
- package/lib/atlaspack-v3/worker/worker.js +8 -0
- package/lib/public/BundleGraph.js +21 -5
- package/lib/public/Config.js +28 -0
- package/lib/requests/AssetGraphRequest.js +13 -1
- package/lib/requests/BundleGraphRequest.js +13 -1
- package/lib/requests/WriteBundleRequest.js +11 -2
- package/lib/resolveOptions.js +4 -2
- package/package.json +13 -13
- package/src/Atlaspack.js +5 -4
- package/src/PackagerRunner.js +60 -9
- package/src/RequestTracker.js +292 -134
- package/src/UncommittedAsset.js +16 -1
- package/src/atlaspack-v3/worker/compat/plugin-config.js +9 -5
- package/src/atlaspack-v3/worker/worker.js +7 -0
- package/src/public/BundleGraph.js +22 -5
- package/src/public/Config.js +39 -5
- package/src/requests/AssetGraphRequest.js +13 -3
- package/src/requests/BundleGraphRequest.js +13 -3
- package/src/requests/WriteBundleRequest.js +9 -2
- package/src/resolveOptions.js +4 -2
- package/test/RequestTracker.test.js +115 -3
- package/test/test-utils.js +1 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @atlaspack/core
|
|
2
2
|
|
|
3
|
+
## 2.17.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#588](https://github.com/atlassian-labs/atlaspack/pull/588) [`1940859`](https://github.com/atlassian-labs/atlaspack/commit/194085942f0e86532e9d039fc3f8039badce4594) Thanks [@yamadapc](https://github.com/yamadapc)! - Do not invalidate all javascript files when tsconfig files change
|
|
8
|
+
|
|
9
|
+
- [#592](https://github.com/atlassian-labs/atlaspack/pull/592) [`15b6155`](https://github.com/atlassian-labs/atlaspack/commit/15b61556e9114203ebbc9de94b864118ca764598) Thanks [@yamadapc](https://github.com/yamadapc)! - Report large file invalidations
|
|
10
|
+
|
|
11
|
+
- [#503](https://github.com/atlassian-labs/atlaspack/pull/503) [`209692f`](https://github.com/atlassian-labs/atlaspack/commit/209692ffb11eae103a0d65c5e1118a5aa1625818) Thanks [@JakeLane](https://github.com/JakeLane)! - Fix conditional bundling reporter when condition is reused
|
|
12
|
+
|
|
13
|
+
- [#562](https://github.com/atlassian-labs/atlaspack/pull/562) [`d04de26`](https://github.com/atlassian-labs/atlaspack/commit/d04de26af684d7abfba5091fbe3df16a12cd0ebc) Thanks [@yamadapc](https://github.com/yamadapc)! - Update with feature-flagged change to write packages into files rather than LMDB
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [[`124b7ff`](https://github.com/atlassian-labs/atlaspack/commit/124b7fff44f71aac9fbad289a9a9509b3dfc9aaa), [`e052521`](https://github.com/atlassian-labs/atlaspack/commit/e0525210850ed1606146eb86991049cf567c5dec), [`15c6d70`](https://github.com/atlassian-labs/atlaspack/commit/15c6d7000bd89da876bc590aa75b17a619a41896), [`e4d966c`](https://github.com/atlassian-labs/atlaspack/commit/e4d966c3c9c4292c5013372ae65b10d19d4bacc6), [`209692f`](https://github.com/atlassian-labs/atlaspack/commit/209692ffb11eae103a0d65c5e1118a5aa1625818), [`42a775d`](https://github.com/atlassian-labs/atlaspack/commit/42a775de8eec638ad188f3271964170d8c04d84b), [`29c2f10`](https://github.com/atlassian-labs/atlaspack/commit/29c2f106de9679adfb5afa04e1910471dc65a427), [`f4da1e1`](https://github.com/atlassian-labs/atlaspack/commit/f4da1e120e73eeb5e8b8927f05e88f04d6148c7b), [`1ef91fc`](https://github.com/atlassian-labs/atlaspack/commit/1ef91fcc863fdd2831511937083dbbc1263b3d9d)]:
|
|
16
|
+
- @atlaspack/cache@3.2.4
|
|
17
|
+
- @atlaspack/rust@3.3.4
|
|
18
|
+
- @atlaspack/fs@2.15.4
|
|
19
|
+
- @atlaspack/feature-flags@2.16.0
|
|
20
|
+
- @atlaspack/logger@2.14.9
|
|
21
|
+
- @atlaspack/utils@2.14.9
|
|
22
|
+
- @atlaspack/package-manager@2.14.9
|
|
23
|
+
- @atlaspack/graph@3.4.7
|
|
24
|
+
- @atlaspack/workers@2.14.9
|
|
25
|
+
- @atlaspack/profiler@2.14.7
|
|
26
|
+
- @atlaspack/types@2.14.9
|
|
27
|
+
- @atlaspack/plugin@2.14.9
|
|
28
|
+
|
|
3
29
|
## 2.17.3
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/lib/Atlaspack.js
CHANGED
|
@@ -510,7 +510,9 @@ class Atlaspack {
|
|
|
510
510
|
if (this.rustAtlaspack) {
|
|
511
511
|
nativeInvalid = await this.rustAtlaspack.respondToFsEvents(events);
|
|
512
512
|
}
|
|
513
|
-
let
|
|
513
|
+
let {
|
|
514
|
+
didInvalidate: isInvalid
|
|
515
|
+
} = await this.#requestTracker.respondToFSEvents(events, Number.POSITIVE_INFINITY);
|
|
514
516
|
if ((nativeInvalid || isInvalid) && this.#watchQueue.getNumWaiting() === 0) {
|
|
515
517
|
if (this.#watchAbortController) {
|
|
516
518
|
this.#watchAbortController.abort();
|
package/lib/PackagerRunner.js
CHANGED
|
@@ -92,6 +92,13 @@ function _profiler() {
|
|
|
92
92
|
};
|
|
93
93
|
return data;
|
|
94
94
|
}
|
|
95
|
+
function _featureFlags() {
|
|
96
|
+
const data = require("@atlaspack/feature-flags");
|
|
97
|
+
_featureFlags = function () {
|
|
98
|
+
return data;
|
|
99
|
+
};
|
|
100
|
+
return data;
|
|
101
|
+
}
|
|
95
102
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
96
103
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
97
104
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -434,6 +441,10 @@ class PackagerRunner {
|
|
|
434
441
|
devDepHashes += await this.getDevDepHashes(inlineBundle);
|
|
435
442
|
}
|
|
436
443
|
let invalidationHash = await (0, _assetUtils.getInvalidationHash)(invalidations, this.options);
|
|
444
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
445
|
+
const hash = (0, _rust().hashString)(_constants.ATLASPACK_VERSION + devDepHashes + invalidationHash + bundle.target.publicUrl + bundleGraph.getHash(bundle) + JSON.stringify(configResults) + JSON.stringify(globalInfoResults) + this.options.mode + (this.options.shouldBuildLazily ? 'lazy' : 'eager'));
|
|
446
|
+
return _path().default.join(bundle.displayName ?? bundle.name ?? bundle.id, hash);
|
|
447
|
+
}
|
|
437
448
|
return (0, _rust().hashString)(_constants.ATLASPACK_VERSION + devDepHashes + invalidationHash + bundle.target.publicUrl + bundleGraph.getHash(bundle) + JSON.stringify(configResults) + JSON.stringify(globalInfoResults) + this.options.mode + (this.options.shouldBuildLazily ? 'lazy' : 'eager'));
|
|
438
449
|
}
|
|
439
450
|
async getDevDepHashes(bundle) {
|
|
@@ -457,25 +468,27 @@ class PackagerRunner {
|
|
|
457
468
|
let contentKey = PackagerRunner.getContentKey(cacheKey);
|
|
458
469
|
let mapKey = PackagerRunner.getMapKey(cacheKey);
|
|
459
470
|
let isLargeBlob = await this.options.cache.hasLargeBlob(contentKey);
|
|
460
|
-
let contentExists = isLargeBlob || (await this.options.cache.has(contentKey));
|
|
471
|
+
let contentExists = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? isLargeBlob : isLargeBlob || (await this.options.cache.has(contentKey));
|
|
461
472
|
if (!contentExists) {
|
|
462
473
|
return null;
|
|
463
474
|
}
|
|
464
|
-
let mapExists = await this.options.cache.has(mapKey);
|
|
475
|
+
let mapExists = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await this.options.cache.hasLargeBlob(mapKey) : await this.options.cache.has(mapKey);
|
|
465
476
|
return {
|
|
466
477
|
contents: isLargeBlob ? this.options.cache.getStream(contentKey) : (0, _utils().blobToStream)(await this.options.cache.getBlob(contentKey)),
|
|
467
|
-
map: mapExists ? (0, _utils().blobToStream)(await this.options.cache.getBlob(mapKey)) : null
|
|
478
|
+
map: mapExists ? (0, _utils().blobToStream)((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await this.options.cache.getLargeBlob(mapKey) : await this.options.cache.getBlob(mapKey)) : null
|
|
468
479
|
};
|
|
469
480
|
}
|
|
470
481
|
async writeToCache(cacheKeys, type, contents, map) {
|
|
471
482
|
let size = 0;
|
|
472
483
|
let hash;
|
|
473
484
|
let hashReferences = [];
|
|
474
|
-
let isLargeBlob =
|
|
485
|
+
let isLargeBlob = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements');
|
|
475
486
|
|
|
476
487
|
// TODO: don't replace hash references in binary files??
|
|
477
488
|
if (contents instanceof _stream().Readable) {
|
|
478
|
-
|
|
489
|
+
if (!(0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
490
|
+
isLargeBlob = true;
|
|
491
|
+
}
|
|
479
492
|
let boundaryStr = '';
|
|
480
493
|
let h = new (_rust().Hash)();
|
|
481
494
|
await this.options.cache.setStream(cacheKeys.content, (0, _utils().blobToStream)(contents).pipe(new (_utils().TapStream)(buf => {
|
|
@@ -491,15 +504,27 @@ class PackagerRunner {
|
|
|
491
504
|
size = buffer.byteLength;
|
|
492
505
|
hash = (0, _rust().hashBuffer)(buffer);
|
|
493
506
|
hashReferences = contents.match(_constants.HASH_REF_REGEX) ?? [];
|
|
494
|
-
|
|
507
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
508
|
+
await this.options.cache.setLargeBlob(cacheKeys.content, buffer);
|
|
509
|
+
} else {
|
|
510
|
+
await this.options.cache.setBlob(cacheKeys.content, buffer);
|
|
511
|
+
}
|
|
495
512
|
} else {
|
|
496
513
|
size = contents.length;
|
|
497
514
|
hash = (0, _rust().hashBuffer)(contents);
|
|
498
515
|
hashReferences = contents.toString().match(_constants.HASH_REF_REGEX) ?? [];
|
|
499
|
-
|
|
516
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
517
|
+
await this.options.cache.setLargeBlob(cacheKeys.content, contents);
|
|
518
|
+
} else {
|
|
519
|
+
await this.options.cache.setBlob(cacheKeys.content, contents);
|
|
520
|
+
}
|
|
500
521
|
}
|
|
501
522
|
if (map != null) {
|
|
502
|
-
|
|
523
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
524
|
+
await this.options.cache.setLargeBlob(cacheKeys.map, map);
|
|
525
|
+
} else {
|
|
526
|
+
await this.options.cache.setBlob(cacheKeys.map, map);
|
|
527
|
+
}
|
|
503
528
|
}
|
|
504
529
|
let info = {
|
|
505
530
|
type,
|
|
@@ -513,12 +538,21 @@ class PackagerRunner {
|
|
|
513
538
|
return info;
|
|
514
539
|
}
|
|
515
540
|
static getContentKey(cacheKey) {
|
|
541
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
542
|
+
return `PackagerRunner/${_constants.ATLASPACK_VERSION}/${cacheKey}/content`;
|
|
543
|
+
}
|
|
516
544
|
return (0, _rust().hashString)(`${cacheKey}:content`);
|
|
517
545
|
}
|
|
518
546
|
static getMapKey(cacheKey) {
|
|
547
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
548
|
+
return `PackagerRunner/${_constants.ATLASPACK_VERSION}/${cacheKey}/map`;
|
|
549
|
+
}
|
|
519
550
|
return (0, _rust().hashString)(`${cacheKey}:map`);
|
|
520
551
|
}
|
|
521
552
|
static getInfoKey(cacheKey) {
|
|
553
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
554
|
+
return `PackagerRunner/${_constants.ATLASPACK_VERSION}/${cacheKey}/info`;
|
|
555
|
+
}
|
|
522
556
|
return (0, _rust().hashString)(`${cacheKey}:info`);
|
|
523
557
|
}
|
|
524
558
|
}
|
package/lib/RequestTracker.js
CHANGED
|
@@ -6,9 +6,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.RequestGraph = void 0;
|
|
7
7
|
exports.cleanUpOrphans = cleanUpOrphans;
|
|
8
8
|
exports.default = void 0;
|
|
9
|
+
exports.getBiggestFSEventsInvalidations = getBiggestFSEventsInvalidations;
|
|
9
10
|
exports.getWatcherOptions = getWatcherOptions;
|
|
11
|
+
exports.invalidateRequestGraph = invalidateRequestGraph;
|
|
12
|
+
exports.invalidateRequestGraphFSEvents = invalidateRequestGraphFSEvents;
|
|
10
13
|
exports.readAndDeserializeRequestGraph = readAndDeserializeRequestGraph;
|
|
11
14
|
exports.requestTypes = exports.requestGraphEdgeTypes = void 0;
|
|
15
|
+
exports.runInvalidation = runInvalidation;
|
|
12
16
|
function _assert() {
|
|
13
17
|
const data = _interopRequireWildcard(require("assert"));
|
|
14
18
|
_assert = function () {
|
|
@@ -84,6 +88,13 @@ var _projectPath = require("./projectPath");
|
|
|
84
88
|
var _ReporterRunner = require("./ReporterRunner");
|
|
85
89
|
var _ConfigRequest = require("./requests/ConfigRequest");
|
|
86
90
|
var _utils2 = require("./utils");
|
|
91
|
+
function _perf_hooks() {
|
|
92
|
+
const data = require("perf_hooks");
|
|
93
|
+
_perf_hooks = function () {
|
|
94
|
+
return data;
|
|
95
|
+
};
|
|
96
|
+
return data;
|
|
97
|
+
}
|
|
87
98
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
88
99
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
89
100
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
@@ -582,10 +593,12 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
582
593
|
aboveCache.set(fileNameNodeId, above);
|
|
583
594
|
return above;
|
|
584
595
|
};
|
|
596
|
+
const invalidationsByPath = new Map();
|
|
585
597
|
for (let {
|
|
586
598
|
path: _path,
|
|
587
599
|
type
|
|
588
600
|
} of events) {
|
|
601
|
+
const invalidationsBefore = this.getInvalidNodeCount();
|
|
589
602
|
if (!enableOptimization && process.env.ATLASPACK_DISABLE_CACHE_TIMEOUT !== 'true' && ++count === 256) {
|
|
590
603
|
let duration = Date.now() - startTime;
|
|
591
604
|
predictedTime = duration * (events.length >> 8);
|
|
@@ -622,7 +635,10 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
622
635
|
this.invalidNodeIds.add(id);
|
|
623
636
|
}
|
|
624
637
|
}
|
|
625
|
-
return
|
|
638
|
+
return {
|
|
639
|
+
didInvalidate: true,
|
|
640
|
+
invalidationsByPath: new Map()
|
|
641
|
+
};
|
|
626
642
|
}
|
|
627
643
|
|
|
628
644
|
// sometimes mac os reports update events as create events.
|
|
@@ -697,6 +713,8 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
697
713
|
}
|
|
698
714
|
}
|
|
699
715
|
}
|
|
716
|
+
const invalidationsAfter = this.getInvalidNodeCount();
|
|
717
|
+
invalidationsByPath.set(_path, (invalidationsByPath.get(_path) ?? 0) + (invalidationsAfter - invalidationsBefore));
|
|
700
718
|
}
|
|
701
719
|
if ((0, _featureFlags().getFeatureFlag)('fixQuadraticCacheInvalidation')) {
|
|
702
720
|
cleanUpOrphans(this);
|
|
@@ -714,7 +732,10 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
714
732
|
numberOfInvalidatedNodes: invalidatedNodes.size
|
|
715
733
|
}
|
|
716
734
|
});
|
|
717
|
-
return
|
|
735
|
+
return {
|
|
736
|
+
didInvalidate,
|
|
737
|
+
invalidationsByPath
|
|
738
|
+
};
|
|
718
739
|
}
|
|
719
740
|
hasCachedRequestChunk(index) {
|
|
720
741
|
return this.cachedRequestChunks.has(index);
|
|
@@ -725,6 +746,13 @@ class RequestGraph extends _graph().ContentGraph {
|
|
|
725
746
|
removeCachedRequestChunkForNode(nodeId) {
|
|
726
747
|
this.cachedRequestChunks.delete(Math.floor(nodeId / this.nodesPerBlob));
|
|
727
748
|
}
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Returns the number of invalidated nodes in the graph.
|
|
752
|
+
*/
|
|
753
|
+
getInvalidNodeCount() {
|
|
754
|
+
return this.invalidNodeIds.size;
|
|
755
|
+
}
|
|
728
756
|
}
|
|
729
757
|
exports.RequestGraph = RequestGraph;
|
|
730
758
|
class RequestTracker {
|
|
@@ -970,84 +998,85 @@ class RequestTracker {
|
|
|
970
998
|
return result;
|
|
971
999
|
}
|
|
972
1000
|
}
|
|
973
|
-
await runCacheImprovements(async cache => {
|
|
974
|
-
await cache.getNativeRef().startWriteTransaction();
|
|
975
|
-
}, () => Promise.resolve());
|
|
976
1001
|
let cacheKey = getCacheKey(this.options);
|
|
977
|
-
let requestGraphKey = `requestGraph-${cacheKey}`;
|
|
1002
|
+
let requestGraphKey = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? `${cacheKey}/RequestGraph` : `requestGraph-${cacheKey}`;
|
|
1003
|
+
let snapshotKey = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? `${cacheKey}/snapshot` : `snapshot-${cacheKey}`;
|
|
978
1004
|
if (this.options.shouldDisableCache) {
|
|
979
1005
|
return;
|
|
980
1006
|
}
|
|
981
1007
|
let total = 0;
|
|
982
|
-
(
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
size: this.graph.nodes.length
|
|
987
|
-
});
|
|
988
|
-
let serialisedGraph = this.graph.serialize();
|
|
989
|
-
|
|
990
|
-
// Delete an existing request graph cache, to prevent invalid states
|
|
991
|
-
await this.options.cache.deleteLargeBlob(requestGraphKey);
|
|
992
|
-
const serialiseAndSet = async (key, contents) => {
|
|
993
|
-
if (signal !== null && signal !== void 0 && signal.aborted) {
|
|
994
|
-
throw new Error('Serialization was aborted');
|
|
995
|
-
}
|
|
996
|
-
await runCacheImprovements(cache => {
|
|
997
|
-
(0, _logger().instrument)(`cache.put(${key})`, () => {
|
|
998
|
-
cache.getNativeRef().putNoConfirm(key, (0, _buildCache().serialize)(contents));
|
|
999
|
-
});
|
|
1000
|
-
return Promise.resolve();
|
|
1001
|
-
}, async () => {
|
|
1002
|
-
await this.options.cache.setLargeBlob(key, (0, _buildCache().serialize)(contents), signal ? {
|
|
1003
|
-
signal: signal
|
|
1004
|
-
} : undefined);
|
|
1005
|
-
});
|
|
1006
|
-
total += 1;
|
|
1008
|
+
await runCacheImprovements(async cache => {
|
|
1009
|
+
await cache.getNativeRef().startWriteTransaction();
|
|
1010
|
+
}, () => Promise.resolve());
|
|
1011
|
+
try {
|
|
1007
1012
|
(0, _ReporterRunner.report)({
|
|
1008
1013
|
type: 'cache',
|
|
1009
|
-
phase: '
|
|
1014
|
+
phase: 'start',
|
|
1010
1015
|
total,
|
|
1011
1016
|
size: this.graph.nodes.length
|
|
1012
1017
|
});
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1018
|
+
let serialisedGraph = this.graph.serialize();
|
|
1019
|
+
|
|
1020
|
+
// Delete an existing request graph cache, to prevent invalid states
|
|
1021
|
+
await this.options.cache.deleteLargeBlob(requestGraphKey);
|
|
1022
|
+
const serialiseAndSet = async (key, contents) => {
|
|
1023
|
+
if (signal !== null && signal !== void 0 && signal.aborted) {
|
|
1024
|
+
throw new Error('Serialization was aborted');
|
|
1025
|
+
}
|
|
1026
|
+
await runCacheImprovements(cache => {
|
|
1027
|
+
(0, _logger().instrument)(`RequestTracker::writeToCache::cache.put(${key})`, () => {
|
|
1028
|
+
cache.getNativeRef().putNoConfirm(key, (0, _buildCache().serialize)(contents));
|
|
1029
|
+
});
|
|
1030
|
+
return Promise.resolve();
|
|
1031
|
+
}, async () => {
|
|
1032
|
+
await this.options.cache.setLargeBlob(key, (0, _buildCache().serialize)(contents), signal ? {
|
|
1033
|
+
signal: signal
|
|
1034
|
+
} : undefined);
|
|
1035
|
+
});
|
|
1036
|
+
total += 1;
|
|
1037
|
+
(0, _ReporterRunner.report)({
|
|
1038
|
+
type: 'cache',
|
|
1039
|
+
phase: 'write',
|
|
1040
|
+
total,
|
|
1041
|
+
size: this.graph.nodes.length
|
|
1042
|
+
});
|
|
1043
|
+
};
|
|
1044
|
+
let queue = new (_utils().PromiseQueue)({
|
|
1045
|
+
maxConcurrent: 32
|
|
1046
|
+
});
|
|
1017
1047
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1048
|
+
// Preallocating a sparse array is faster than pushing when N is high enough
|
|
1049
|
+
let cacheableNodes = new Array(serialisedGraph.nodes.length);
|
|
1050
|
+
for (let i = 0; i < serialisedGraph.nodes.length; i += 1) {
|
|
1051
|
+
let node = serialisedGraph.nodes[i];
|
|
1052
|
+
let resultCacheKey = node === null || node === void 0 ? void 0 : node.resultCacheKey;
|
|
1053
|
+
if ((node === null || node === void 0 ? void 0 : node.type) === REQUEST && resultCacheKey != null && (node === null || node === void 0 ? void 0 : node.result) != null) {
|
|
1054
|
+
queue.add(() => serialiseAndSet(resultCacheKey, node.result));
|
|
1025
1055
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1056
|
+
// eslint-disable-next-line no-unused-vars
|
|
1057
|
+
let {
|
|
1058
|
+
result: _,
|
|
1059
|
+
...newNode
|
|
1060
|
+
} = node;
|
|
1061
|
+
cacheableNodes[i] = newNode;
|
|
1062
|
+
} else {
|
|
1063
|
+
cacheableNodes[i] = node;
|
|
1064
|
+
}
|
|
1034
1065
|
}
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
}
|
|
1066
|
+
let nodeCountsPerBlob = [];
|
|
1067
|
+
for (let i = 0; i * this.graph.nodesPerBlob < cacheableNodes.length; i += 1) {
|
|
1068
|
+
let nodesStartIndex = i * this.graph.nodesPerBlob;
|
|
1069
|
+
let nodesEndIndex = Math.min((i + 1) * this.graph.nodesPerBlob, cacheableNodes.length);
|
|
1070
|
+
nodeCountsPerBlob.push(nodesEndIndex - nodesStartIndex);
|
|
1071
|
+
if (!this.graph.hasCachedRequestChunk(i)) {
|
|
1072
|
+
// We assume the request graph nodes are immutable and won't change
|
|
1073
|
+
let nodesToCache = cacheableNodes.slice(nodesStartIndex, nodesEndIndex);
|
|
1074
|
+
queue.add(() => serialiseAndSet(getRequestGraphNodeKey(i, cacheKey), nodesToCache).then(() => {
|
|
1075
|
+
// Succeeded in writing to disk, save that we have completed this chunk
|
|
1076
|
+
this.graph.setCachedRequestChunk(i);
|
|
1077
|
+
}));
|
|
1078
|
+
}
|
|
1048
1079
|
}
|
|
1049
|
-
}
|
|
1050
|
-
try {
|
|
1051
1080
|
await queue.run();
|
|
1052
1081
|
|
|
1053
1082
|
// Set the request graph after the queue is flushed to avoid writing an invalid state
|
|
@@ -1056,7 +1085,7 @@ class RequestTracker {
|
|
|
1056
1085
|
nodeCountsPerBlob,
|
|
1057
1086
|
nodes: undefined
|
|
1058
1087
|
});
|
|
1059
|
-
await runCacheImprovements(() => serialiseAndSet(
|
|
1088
|
+
await runCacheImprovements(() => serialiseAndSet(`${cacheKey}/cache_metadata`, {
|
|
1060
1089
|
version: _constants.ATLASPACK_VERSION,
|
|
1061
1090
|
entries: this.options.entries,
|
|
1062
1091
|
mode: this.options.mode,
|
|
@@ -1064,15 +1093,16 @@ class RequestTracker {
|
|
|
1064
1093
|
watchBackend: this.options.watchBackend
|
|
1065
1094
|
}), () => Promise.resolve());
|
|
1066
1095
|
let opts = getWatcherOptions(this.options);
|
|
1067
|
-
let snapshotPath = _path2().default.join(this.options.cacheDir,
|
|
1096
|
+
let snapshotPath = _path2().default.join(this.options.cacheDir, snapshotKey + '.txt');
|
|
1068
1097
|
await this.options.outputFS.writeSnapshot(this.options.watchDir, snapshotPath, opts);
|
|
1069
1098
|
} catch (err) {
|
|
1070
1099
|
// If we have aborted, ignore the error and continue
|
|
1071
1100
|
if (!(signal !== null && signal !== void 0 && signal.aborted)) throw err;
|
|
1101
|
+
} finally {
|
|
1102
|
+
await runCacheImprovements(async cache => {
|
|
1103
|
+
await cache.getNativeRef().commitWriteTransaction();
|
|
1104
|
+
}, () => Promise.resolve());
|
|
1072
1105
|
}
|
|
1073
|
-
await runCacheImprovements(async cache => {
|
|
1074
|
-
await cache.getNativeRef().commitWriteTransaction();
|
|
1075
|
-
}, () => Promise.resolve());
|
|
1076
1106
|
(0, _ReporterRunner.report)({
|
|
1077
1107
|
type: 'cache',
|
|
1078
1108
|
phase: 'end',
|
|
@@ -1109,17 +1139,30 @@ function getWatcherOptions({
|
|
|
1109
1139
|
};
|
|
1110
1140
|
}
|
|
1111
1141
|
function getCacheKey(options) {
|
|
1142
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
1143
|
+
const hash = (0, _rust().hashString)(`${_constants.ATLASPACK_VERSION}:${JSON.stringify(options.entries)}:${options.mode}:${options.shouldBuildLazily ? 'lazy' : 'eager'}:${options.watchBackend ?? ''}`);
|
|
1144
|
+
return `RequestTracker/${_constants.ATLASPACK_VERSION}/${hash}`;
|
|
1145
|
+
}
|
|
1112
1146
|
return (0, _rust().hashString)(`${_constants.ATLASPACK_VERSION}:${JSON.stringify(options.entries)}:${options.mode}:${options.shouldBuildLazily ? 'lazy' : 'eager'}:${options.watchBackend ?? ''}`);
|
|
1113
1147
|
}
|
|
1114
1148
|
function getRequestGraphNodeKey(index, cacheKey) {
|
|
1149
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
1150
|
+
return `${cacheKey}/RequestGraph/nodes/${index}`;
|
|
1151
|
+
}
|
|
1115
1152
|
return `requestGraph-nodes-${index}-${cacheKey}`;
|
|
1116
1153
|
}
|
|
1117
1154
|
async function readAndDeserializeRequestGraph(cache, requestGraphKey, cacheKey) {
|
|
1118
1155
|
let bufferLength = 0;
|
|
1119
1156
|
const getAndDeserialize = async key => {
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1157
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
1158
|
+
const buffer = await cache.getBlob(key);
|
|
1159
|
+
bufferLength += Buffer.byteLength(buffer);
|
|
1160
|
+
return (0, _buildCache().deserialize)(buffer);
|
|
1161
|
+
} else {
|
|
1162
|
+
const buffer = await cache.getLargeBlob(key);
|
|
1163
|
+
bufferLength += Buffer.byteLength(buffer);
|
|
1164
|
+
return (0, _buildCache().deserialize)(buffer);
|
|
1165
|
+
}
|
|
1123
1166
|
};
|
|
1124
1167
|
let serializedRequestGraph = await getAndDeserialize(requestGraphKey);
|
|
1125
1168
|
let nodePromises = serializedRequestGraph.nodeCountsPerBlob.map(async (nodesCount, i) => {
|
|
@@ -1141,9 +1184,9 @@ async function loadRequestGraph(options) {
|
|
|
1141
1184
|
return new RequestGraph();
|
|
1142
1185
|
}
|
|
1143
1186
|
let cacheKey = getCacheKey(options);
|
|
1144
|
-
let requestGraphKey = `requestGraph-${cacheKey}`;
|
|
1187
|
+
let requestGraphKey = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? `${cacheKey}/RequestGraph` : `requestGraph-${cacheKey}`;
|
|
1145
1188
|
let timeout;
|
|
1146
|
-
const snapshotKey = `snapshot-${cacheKey}`;
|
|
1189
|
+
const snapshotKey = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? `${cacheKey}/snapshot` : `snapshot-${cacheKey}`;
|
|
1147
1190
|
const snapshotPath = _path2().default.join(options.cacheDir, snapshotKey + '.txt');
|
|
1148
1191
|
const commonMeta = {
|
|
1149
1192
|
cacheKey,
|
|
@@ -1163,7 +1206,8 @@ async function loadRequestGraph(options) {
|
|
|
1163
1206
|
...commonMeta
|
|
1164
1207
|
}
|
|
1165
1208
|
});
|
|
1166
|
-
|
|
1209
|
+
const hasRequestGraphInCache = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await options.cache.has(requestGraphKey) : await options.cache.hasLargeBlob(requestGraphKey);
|
|
1210
|
+
if (hasRequestGraphInCache) {
|
|
1167
1211
|
try {
|
|
1168
1212
|
let {
|
|
1169
1213
|
requestGraph
|
|
@@ -1230,6 +1274,20 @@ async function loadRequestGraph(options) {
|
|
|
1230
1274
|
* A wrapper around an invalidation type / method
|
|
1231
1275
|
*/
|
|
1232
1276
|
|
|
1277
|
+
/**
|
|
1278
|
+
* Details about an invalidation.
|
|
1279
|
+
*
|
|
1280
|
+
* If this is a fs events invalidation, this key will contain statistics about invalidations
|
|
1281
|
+
* by path.
|
|
1282
|
+
*
|
|
1283
|
+
* If this is a env or option invalidation, this key will contain the list of changed environment
|
|
1284
|
+
* variables or options.
|
|
1285
|
+
*/
|
|
1286
|
+
|
|
1287
|
+
/**
|
|
1288
|
+
* Number of invalidations for a given file-system event.
|
|
1289
|
+
*/
|
|
1290
|
+
|
|
1233
1291
|
/**
|
|
1234
1292
|
* Information about a certain cache invalidation type.
|
|
1235
1293
|
*/
|
|
@@ -1255,9 +1313,7 @@ async function invalidateRequestGraph(requestGraph, options, events) {
|
|
|
1255
1313
|
fn: () => requestGraph.invalidateOptionNodes(options)
|
|
1256
1314
|
}, {
|
|
1257
1315
|
key: 'fsEvents',
|
|
1258
|
-
fn:
|
|
1259
|
-
await requestGraph.respondToFSEvents(options.unstableFileInvalidations || events, options, 10000, true);
|
|
1260
|
-
}
|
|
1316
|
+
fn: () => invalidateRequestGraphFSEvents(requestGraph, options, events)
|
|
1261
1317
|
}];
|
|
1262
1318
|
const invalidations = [];
|
|
1263
1319
|
for (const invalidation of invalidationFns) {
|
|
@@ -1275,18 +1331,34 @@ async function invalidateRequestGraph(requestGraph, options, events) {
|
|
|
1275
1331
|
requestInvalidationRatio: invalidatedCount / requestCount
|
|
1276
1332
|
};
|
|
1277
1333
|
}
|
|
1278
|
-
|
|
1334
|
+
/**
|
|
1335
|
+
* Invalidate the request graph based on file-system events.
|
|
1336
|
+
*
|
|
1337
|
+
* Returns statistics about the invalidations.
|
|
1338
|
+
*/
|
|
1339
|
+
async function invalidateRequestGraphFSEvents(requestGraph, options, events) {
|
|
1340
|
+
const {
|
|
1341
|
+
invalidationsByPath
|
|
1342
|
+
} = await requestGraph.respondToFSEvents(options.unstableFileInvalidations || events, options, 10000, true);
|
|
1343
|
+
const biggestInvalidations = getBiggestFSEventsInvalidations(invalidationsByPath);
|
|
1344
|
+
return {
|
|
1345
|
+
biggestInvalidations
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1279
1348
|
/**
|
|
1280
1349
|
* Runs an invalidation function and reports metrics.
|
|
1281
1350
|
*/
|
|
1282
1351
|
async function runInvalidation(requestGraph, invalidationFn) {
|
|
1283
|
-
const
|
|
1352
|
+
const start = _perf_hooks().performance.now();
|
|
1353
|
+
const startInvalidationCount = requestGraph.getInvalidNodeCount();
|
|
1284
1354
|
const result = await invalidationFn.fn();
|
|
1285
|
-
const count = requestGraph.
|
|
1355
|
+
const count = requestGraph.getInvalidNodeCount() - startInvalidationCount;
|
|
1356
|
+
const duration = _perf_hooks().performance.now() - start;
|
|
1286
1357
|
return {
|
|
1287
1358
|
key: invalidationFn.key,
|
|
1288
1359
|
count,
|
|
1289
|
-
|
|
1360
|
+
detail: result ?? null,
|
|
1361
|
+
duration
|
|
1290
1362
|
};
|
|
1291
1363
|
}
|
|
1292
1364
|
function logErrorOnBailout(options, snapshotPath, e) {
|
|
@@ -1328,4 +1400,19 @@ function cleanUpOrphans(graph) {
|
|
|
1328
1400
|
}
|
|
1329
1401
|
});
|
|
1330
1402
|
return removedNodeIds;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
/**
|
|
1406
|
+
* Returns paths that invalidated the most nodes
|
|
1407
|
+
*/
|
|
1408
|
+
function getBiggestFSEventsInvalidations(invalidationsByPath, limit = 10) {
|
|
1409
|
+
const invalidations = [];
|
|
1410
|
+
for (const [path, count] of invalidationsByPath) {
|
|
1411
|
+
invalidations.push({
|
|
1412
|
+
path,
|
|
1413
|
+
count
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
invalidations.sort((a, b) => b.count - a.count);
|
|
1417
|
+
return invalidations.slice(0, limit);
|
|
1331
1418
|
}
|
package/lib/UncommittedAsset.js
CHANGED
|
@@ -53,6 +53,13 @@ var _assetUtils = require("./assetUtils");
|
|
|
53
53
|
var _types = require("./types");
|
|
54
54
|
var _utils2 = require("./utils");
|
|
55
55
|
var _projectPath = require("./projectPath");
|
|
56
|
+
function _featureFlags() {
|
|
57
|
+
const data = require("@atlaspack/feature-flags");
|
|
58
|
+
_featureFlags = function () {
|
|
59
|
+
return data;
|
|
60
|
+
};
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
56
63
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
57
64
|
class UncommittedAsset {
|
|
58
65
|
constructor({
|
|
@@ -133,6 +140,8 @@ class UncommittedAsset {
|
|
|
133
140
|
hash = (0, _rust().hashBuffer)(content);
|
|
134
141
|
size = content.length;
|
|
135
142
|
}
|
|
143
|
+
|
|
144
|
+
// Maybe we should just store this in a file instead of LMDB
|
|
136
145
|
await this.options.cache.setBlob(contentKey, content);
|
|
137
146
|
return {
|
|
138
147
|
size,
|
|
@@ -184,6 +193,10 @@ class UncommittedAsset {
|
|
|
184
193
|
this.content = buffer;
|
|
185
194
|
this.clearAST();
|
|
186
195
|
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @deprecated This has been broken on any cache other than FSCache for a long time.
|
|
199
|
+
*/
|
|
187
200
|
setStream(stream) {
|
|
188
201
|
this.content = stream;
|
|
189
202
|
this.clearAST();
|
|
@@ -248,6 +261,10 @@ class UncommittedAsset {
|
|
|
248
261
|
this.value.astGenerator = null;
|
|
249
262
|
}
|
|
250
263
|
getCacheKey(key) {
|
|
264
|
+
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
265
|
+
const filePath = (0, _projectPath.fromProjectPathRelative)(this.value.filePath);
|
|
266
|
+
return `Asset/${_constants.ATLASPACK_VERSION}/${filePath}/${this.value.id}/${key}`;
|
|
267
|
+
}
|
|
251
268
|
return (0, _rust().hashString)(_constants.ATLASPACK_VERSION + key + this.value.id);
|
|
252
269
|
}
|
|
253
270
|
addDependency(opts) {
|