@fluidframework/container-runtime 1.2.3-83900 → 2.0.0-internal.1.0.0
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/dist/batchTracker.js +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +81 -25
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +301 -100
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +66 -49
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +129 -164
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.js +29 -24
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +3 -4
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +16 -23
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +6 -3
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +13 -5
- package/dist/dataStores.js.map +1 -1
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +17 -12
- package/dist/garbageCollection.js.map +1 -1
- package/dist/opProperties.d.ts +7 -0
- package/dist/opProperties.d.ts.map +1 -0
- package/dist/opProperties.js +20 -0
- package/dist/opProperties.js.map +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/runningSummarizer.d.ts +28 -4
- package/dist/runningSummarizer.d.ts.map +1 -1
- package/dist/runningSummarizer.js +93 -26
- package/dist/runningSummarizer.js.map +1 -1
- package/dist/summarizer.d.ts +0 -2
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +34 -15
- package/dist/summarizer.js.map +1 -1
- package/dist/summarizerHeuristics.d.ts +26 -4
- package/dist/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summarizerHeuristics.js +95 -18
- package/dist/summarizerHeuristics.js.map +1 -1
- package/dist/summarizerTypes.d.ts +30 -10
- package/dist/summarizerTypes.d.ts.map +1 -1
- package/dist/summarizerTypes.js.map +1 -1
- package/dist/summaryCollection.js +1 -1
- package/dist/summaryCollection.js.map +1 -1
- package/dist/summaryFormat.d.ts +0 -5
- package/dist/summaryFormat.d.ts.map +1 -1
- package/dist/summaryFormat.js.map +1 -1
- package/dist/summaryGenerator.d.ts +1 -0
- package/dist/summaryGenerator.d.ts.map +1 -1
- package/dist/summaryGenerator.js +11 -9
- package/dist/summaryGenerator.js.map +1 -1
- package/lib/batchTracker.js +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +81 -25
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +302 -101
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +66 -49
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +131 -166
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.js +29 -24
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +3 -4
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +17 -24
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +6 -3
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +13 -5
- package/lib/dataStores.js.map +1 -1
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +17 -12
- package/lib/garbageCollection.js.map +1 -1
- package/lib/opProperties.d.ts +7 -0
- package/lib/opProperties.d.ts.map +1 -0
- package/lib/opProperties.js +16 -0
- package/lib/opProperties.js.map +1 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/runningSummarizer.d.ts +28 -4
- package/lib/runningSummarizer.d.ts.map +1 -1
- package/lib/runningSummarizer.js +93 -26
- package/lib/runningSummarizer.js.map +1 -1
- package/lib/summarizer.d.ts +0 -2
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +36 -17
- package/lib/summarizer.js.map +1 -1
- package/lib/summarizerHeuristics.d.ts +26 -4
- package/lib/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summarizerHeuristics.js +95 -18
- package/lib/summarizerHeuristics.js.map +1 -1
- package/lib/summarizerTypes.d.ts +30 -10
- package/lib/summarizerTypes.d.ts.map +1 -1
- package/lib/summarizerTypes.js.map +1 -1
- package/lib/summaryCollection.js +1 -1
- package/lib/summaryCollection.js.map +1 -1
- package/lib/summaryFormat.d.ts +0 -5
- package/lib/summaryFormat.d.ts.map +1 -1
- package/lib/summaryFormat.js.map +1 -1
- package/lib/summaryGenerator.d.ts +1 -0
- package/lib/summaryGenerator.d.ts.map +1 -1
- package/lib/summaryGenerator.js +11 -9
- package/lib/summaryGenerator.js.map +1 -1
- package/package.json +55 -21
- package/src/batchTracker.ts +1 -1
- package/src/blobManager.ts +364 -119
- package/src/containerRuntime.ts +232 -216
- package/src/dataStore.ts +49 -37
- package/src/dataStoreContext.ts +16 -23
- package/src/dataStores.ts +27 -16
- package/src/garbageCollection.ts +13 -7
- package/src/opProperties.ts +19 -0
- package/src/packageVersion.ts +1 -1
- package/src/runningSummarizer.ts +108 -23
- package/src/summarizer.ts +47 -28
- package/src/summarizerHeuristics.ts +133 -19
- package/src/summarizerTypes.ts +37 -10
- package/src/summaryCollection.ts +1 -1
- package/src/summaryFormat.ts +0 -6
- package/src/summaryGenerator.ts +40 -22
- package/dist/opTelemetry.d.ts +0 -22
- package/dist/opTelemetry.d.ts.map +0 -1
- package/dist/opTelemetry.js +0 -59
- package/dist/opTelemetry.js.map +0 -1
- package/lib/opTelemetry.d.ts +0 -22
- package/lib/opTelemetry.d.ts.map +0 -1
- package/lib/opTelemetry.js +0 -55
- package/lib/opTelemetry.js.map +0 -1
- package/src/opTelemetry.ts +0 -71
package/dist/containerRuntime.js
CHANGED
|
@@ -32,7 +32,6 @@ const garbageCollection_1 = require("./garbageCollection");
|
|
|
32
32
|
const dataStore_1 = require("./dataStore");
|
|
33
33
|
const batchTracker_1 = require("./batchTracker");
|
|
34
34
|
const serializedSnapshotStorage_1 = require("./serializedSnapshotStorage");
|
|
35
|
-
const opTelemetry_1 = require("./opTelemetry");
|
|
36
35
|
var ContainerMessageType;
|
|
37
36
|
(function (ContainerMessageType) {
|
|
38
37
|
// An op to be delivered to store
|
|
@@ -50,14 +49,18 @@ var ContainerMessageType;
|
|
|
50
49
|
})(ContainerMessageType = exports.ContainerMessageType || (exports.ContainerMessageType = {}));
|
|
51
50
|
exports.DefaultSummaryConfiguration = {
|
|
52
51
|
state: "enabled",
|
|
53
|
-
idleTime:
|
|
54
|
-
|
|
52
|
+
idleTime: 15 * 1000,
|
|
53
|
+
minIdleTime: 0,
|
|
54
|
+
maxIdleTime: 30 * 1000,
|
|
55
|
+
maxTime: 60 * 1000,
|
|
55
56
|
maxOps: 100,
|
|
56
57
|
minOpsForLastSummaryAttempt: 10,
|
|
57
|
-
maxAckWaitTime:
|
|
58
|
+
maxAckWaitTime: 10 * 60 * 1000,
|
|
58
59
|
maxOpsSinceLastSummary: 7000,
|
|
59
|
-
initialSummarizerDelayMs:
|
|
60
|
+
initialSummarizerDelayMs: 5 * 1000,
|
|
60
61
|
summarizerClientElection: false,
|
|
62
|
+
nonRuntimeOpWeight: 0.1,
|
|
63
|
+
runtimeOpWeight: 1.0,
|
|
61
64
|
};
|
|
62
65
|
/**
|
|
63
66
|
* Accepted header keys for requests coming to the runtime.
|
|
@@ -74,7 +77,6 @@ var RuntimeHeaders;
|
|
|
74
77
|
/** True if the request is coming from an IFluidHandle. */
|
|
75
78
|
RuntimeHeaders["viaHandle"] = "viaHandle";
|
|
76
79
|
})(RuntimeHeaders = exports.RuntimeHeaders || (exports.RuntimeHeaders = {}));
|
|
77
|
-
const useDataStoreAliasingKey = "Fluid.ContainerRuntime.UseDataStoreAliasing";
|
|
78
80
|
const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
|
|
79
81
|
// Feature gate for the max op size. If the value is negative, chunking is enabled
|
|
80
82
|
// and all ops over 16k would be chunked. If the value is positive, all ops with
|
|
@@ -84,10 +86,6 @@ const maxOpSizeInBytesKey = "Fluid.ContainerRuntime.MaxOpSizeInBytes";
|
|
|
84
86
|
// in order to account for some extra overhead from serialization
|
|
85
87
|
// to not reach the 1MB limits in socket.io and Kafka.
|
|
86
88
|
const defaultMaxOpSizeInBytes = 768000;
|
|
87
|
-
// By default, the size of the contents for the incoming ops is tracked.
|
|
88
|
-
// However, in certain situations, this may incur a performance hit.
|
|
89
|
-
// The feature-gate below can be used to disable this feature.
|
|
90
|
-
const disableOpTrackingKey = "Fluid.ContainerRuntime.DisableOpTracking";
|
|
91
89
|
const defaultFlushMode = runtime_definitions_1.FlushMode.TurnBased;
|
|
92
90
|
var RuntimeMessage;
|
|
93
91
|
(function (RuntimeMessage) {
|
|
@@ -380,7 +378,7 @@ exports.getDeviceSpec = getDeviceSpec;
|
|
|
380
378
|
*/
|
|
381
379
|
class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
382
380
|
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration) {
|
|
383
|
-
var _a, _b, _c, _d, _e, _f
|
|
381
|
+
var _a, _b, _c, _d, _e, _f;
|
|
384
382
|
if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, exports.DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
|
|
385
383
|
super();
|
|
386
384
|
this.context = context;
|
|
@@ -441,20 +439,20 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
441
439
|
this.chunkMap = new Map(chunks);
|
|
442
440
|
this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
|
|
443
441
|
this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime"));
|
|
442
|
+
if (this.summaryConfiguration.state === "enabled") {
|
|
443
|
+
this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
|
|
444
|
+
}
|
|
444
445
|
this.summariesDisabled = this.isSummariesDisabled();
|
|
445
446
|
this.heuristicsDisabled = this.isHeuristicsDisabled();
|
|
446
447
|
this.summarizerClientElectionEnabled = this.isSummarizerClientElectionEnabled();
|
|
447
448
|
this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
|
|
448
449
|
this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
|
|
449
|
-
this.
|
|
450
|
-
((_c = this.mc.config.getBoolean(useDataStoreAliasingKey)) !== null && _c !== void 0 ? _c : false) ||
|
|
451
|
-
((_d = runtimeOptions.useDataStoreAliasing) !== null && _d !== void 0 ? _d : false);
|
|
452
|
-
this._maxOpSizeInBytes = ((_e = this.mc.config.getNumber(maxOpSizeInBytesKey)) !== null && _e !== void 0 ? _e : defaultMaxOpSizeInBytes);
|
|
450
|
+
this._maxOpSizeInBytes = ((_c = this.mc.config.getNumber(maxOpSizeInBytesKey)) !== null && _c !== void 0 ? _c : defaultMaxOpSizeInBytes);
|
|
453
451
|
this.maxConsecutiveReconnects =
|
|
454
|
-
(
|
|
452
|
+
(_d = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _d !== void 0 ? _d : this.defaultMaxConsecutiveReconnects;
|
|
455
453
|
this._flushMode = runtimeOptions.flushMode;
|
|
456
454
|
const pendingRuntimeState = context.pendingLocalState;
|
|
457
|
-
const baseSnapshot = (
|
|
455
|
+
const baseSnapshot = (_e = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _e !== void 0 ? _e : context.baseSnapshot;
|
|
458
456
|
this.garbageCollector = garbageCollection_1.GarbageCollector.create({
|
|
459
457
|
runtime: this,
|
|
460
458
|
gcOptions: this.runtimeOptions.gcOptions,
|
|
@@ -488,7 +486,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
488
486
|
this.summarizerNode.loadBaseSummaryWithoutDifferential(baseSnapshot);
|
|
489
487
|
}
|
|
490
488
|
this.dataStores = new dataStores_1.DataStores((0, dataStores_1.getSummaryForDatastores)(baseSnapshot, metadata), this, (attachMsg) => this.submit(ContainerMessageType.Attach, attachMsg), (id, createParam) => (summarizeInternal, getGCDataFn, getBaseGCDetailsFn) => this.summarizerNode.createChild(summarizeInternal, id, createParam, undefined, getGCDataFn, getBaseGCDetailsFn), (id) => this.summarizerNode.deleteChild(id), this.mc.logger, async () => this.garbageCollector.getBaseGCDetails(), (path, timestampMs, packagePath) => this.garbageCollector.nodeUpdated(path, "Changed", timestampMs, packagePath), new Map(dataStoreAliasMap), this.garbageCollector.writeDataAtRoot);
|
|
491
|
-
this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (blobId) => this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { blobId }), (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), this
|
|
489
|
+
this.blobManager = new blobManager_1.BlobManager(this.handleContext, blobManagerSnapshot, () => this.storage, (blobId, localId) => this.submit(ContainerMessageType.BlobAttach, undefined, undefined, { blobId, localId }), (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), this);
|
|
492
490
|
this.scheduleManager = new ScheduleManager(context.deltaManager, this, telemetry_utils_1.ChildLogger.create(this.logger, "ScheduleManager"));
|
|
493
491
|
this.deltaSender = this.deltaManager;
|
|
494
492
|
this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
|
|
@@ -579,9 +577,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
579
577
|
createContainerRuntimeVersion: metadata === null || metadata === void 0 ? void 0 : metadata.createContainerRuntimeVersion,
|
|
580
578
|
createContainerTimestamp: metadata === null || metadata === void 0 ? void 0 : metadata.createContainerTimestamp,
|
|
581
579
|
};
|
|
582
|
-
//
|
|
583
|
-
//
|
|
584
|
-
loadSummaryNumber = (
|
|
580
|
+
// summaryNumber was renamed from summaryCount. For older docs that haven't been opened for a long time,
|
|
581
|
+
// the count is reset to 0.
|
|
582
|
+
loadSummaryNumber = (_f = metadata === null || metadata === void 0 ? void 0 : metadata.summaryNumber) !== null && _f !== void 0 ? _f : 0;
|
|
585
583
|
}
|
|
586
584
|
else {
|
|
587
585
|
this.createContainerMetadata = {
|
|
@@ -594,7 +592,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
594
592
|
this.logger.sendTelemetryEvent(Object.assign(Object.assign(Object.assign({ eventName: "ContainerLoadStats" }, this.createContainerMetadata), this.dataStores.containerLoadStats), { summaryNumber: loadSummaryNumber, summaryFormatVersion: metadata === null || metadata === void 0 ? void 0 : metadata.summaryFormatVersion, disableIsolatedChannels: metadata === null || metadata === void 0 ? void 0 : metadata.disableIsolatedChannels, gcVersion: metadata === null || metadata === void 0 ? void 0 : metadata.gcFeature }));
|
|
595
593
|
(0, connectionTelemetry_1.ReportOpPerfTelemetry)(this.context.clientId, this.deltaManager, this.logger);
|
|
596
594
|
(0, batchTracker_1.BindBatchTracker)(this, this.logger);
|
|
597
|
-
this.opTracker = new opTelemetry_1.OpTracker(this.deltaManager, this.mc.config.getBoolean(disableOpTrackingKey) === true);
|
|
598
595
|
}
|
|
599
596
|
get IContainerRuntime() { return this; }
|
|
600
597
|
get IFluidRouter() { return this; }
|
|
@@ -617,7 +614,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
617
614
|
runtimeVersion: packageVersion_1.pkgVersion,
|
|
618
615
|
},
|
|
619
616
|
});
|
|
620
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close",
|
|
617
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, enableOfflineLoad = false, } = runtimeOptions;
|
|
621
618
|
const pendingRuntimeState = context.pendingLocalState;
|
|
622
619
|
const baseSnapshot = (_b = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _b !== void 0 ? _b : context.baseSnapshot;
|
|
623
620
|
const storage = !pendingRuntimeState ?
|
|
@@ -670,7 +667,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
670
667
|
summaryOptions,
|
|
671
668
|
gcOptions,
|
|
672
669
|
loadSequenceNumberVerification,
|
|
673
|
-
useDataStoreAliasing,
|
|
674
670
|
flushMode,
|
|
675
671
|
enableOfflineLoad,
|
|
676
672
|
}, containerScope, logger, loadExisting, blobManagerSnapshot, storage, requestHandler);
|
|
@@ -863,12 +859,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
863
859
|
return this.resolveHandle(requestParser.createSubRequest(1));
|
|
864
860
|
}
|
|
865
861
|
if (id === blobManager_1.BlobManager.basePath && requestParser.isLeaf(2)) {
|
|
866
|
-
const
|
|
867
|
-
if (
|
|
862
|
+
const blob = await this.blobManager.getBlob(requestParser.pathParts[1]);
|
|
863
|
+
if (blob) {
|
|
868
864
|
return {
|
|
869
865
|
status: 200,
|
|
870
866
|
mimeType: "fluid/object",
|
|
871
|
-
value:
|
|
867
|
+
value: blob,
|
|
872
868
|
};
|
|
873
869
|
}
|
|
874
870
|
else {
|
|
@@ -891,13 +887,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
891
887
|
}
|
|
892
888
|
internalId(maybeAlias) {
|
|
893
889
|
var _a;
|
|
894
|
-
return (_a = this.dataStores.aliases
|
|
890
|
+
return (_a = this.dataStores.aliases.get(maybeAlias)) !== null && _a !== void 0 ? _a : maybeAlias;
|
|
895
891
|
}
|
|
896
892
|
async getDataStoreFromRequest(id, request) {
|
|
897
893
|
var _a, _b, _c;
|
|
898
894
|
const wait = typeof ((_a = request.headers) === null || _a === void 0 ? void 0 : _a[RuntimeHeaders.wait]) === "boolean"
|
|
899
895
|
? (_b = request.headers) === null || _b === void 0 ? void 0 : _b[RuntimeHeaders.wait]
|
|
900
896
|
: true;
|
|
897
|
+
await this.dataStores.waitIfPendingAlias(id);
|
|
901
898
|
const internalId = this.internalId(id);
|
|
902
899
|
const dataStoreContext = await this.dataStores.getDataStore(internalId, wait);
|
|
903
900
|
/**
|
|
@@ -927,8 +924,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
927
924
|
addMetadataToSummary(summaryTree) {
|
|
928
925
|
var _a;
|
|
929
926
|
const metadata = Object.assign(Object.assign(Object.assign(Object.assign({}, this.createContainerMetadata), {
|
|
930
|
-
// back-compat 0.59.3000: This is renamed to summaryNumber. Can be removed when 0.59.3000 saturates.
|
|
931
|
-
summaryCount: this.nextSummaryNumber,
|
|
932
927
|
// Increment the summary number for the next summary that will be generated.
|
|
933
928
|
summaryNumber: this.nextSummaryNumber++, summaryFormatVersion: 1, disableIsolatedChannels: this.disableIsolatedChannels || undefined }), this.garbageCollector.getMetadata()), {
|
|
934
929
|
// The last message processed at the time of summary. If there are no new messages, use the message from the
|
|
@@ -943,7 +938,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
943
938
|
const content = JSON.stringify([...this.chunkMap]);
|
|
944
939
|
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summaryFormat_1.chunksBlobName, content);
|
|
945
940
|
}
|
|
946
|
-
const dataStoreAliases = this.dataStores.aliases
|
|
941
|
+
const dataStoreAliases = this.dataStores.aliases;
|
|
947
942
|
if (dataStoreAliases.size > 0) {
|
|
948
943
|
(0, runtime_utils_1.addBlobToSummary)(summaryTree, summaryFormat_1.aliasBlobName, JSON.stringify([...dataStoreAliases]));
|
|
949
944
|
}
|
|
@@ -1040,6 +1035,35 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1040
1035
|
}
|
|
1041
1036
|
}
|
|
1042
1037
|
setConnectionState(connected, clientId) {
|
|
1038
|
+
if (connected === false && this.delayConnectClientId !== undefined) {
|
|
1039
|
+
this.delayConnectClientId = undefined;
|
|
1040
|
+
this.mc.logger.sendTelemetryEvent({
|
|
1041
|
+
eventName: "UnsuccessfulConnectedTransition",
|
|
1042
|
+
});
|
|
1043
|
+
// Don't propagate "disconnected" event because we didn't propagate the previous "connected" event
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
// If attachment blobs were added while disconnected, we need to delay
|
|
1047
|
+
// propagation of the "connected" event until we have uploaded them to
|
|
1048
|
+
// ensure we don't submit ops referencing a blob that has not been uploaded
|
|
1049
|
+
const connecting = connected && !this._connected && !this.deltaManager.readOnlyInfo.readonly;
|
|
1050
|
+
if (connecting && this.blobManager.hasPendingOfflineUploads) {
|
|
1051
|
+
(0, common_utils_1.assert)(!this.delayConnectClientId, 0x392 /* Connect event delay must be canceled before subsequent connect event */);
|
|
1052
|
+
(0, common_utils_1.assert)(!!clientId, 0x393 /* Must have clientId when connecting */);
|
|
1053
|
+
this.delayConnectClientId = clientId;
|
|
1054
|
+
this.blobManager.onConnected().then(() => {
|
|
1055
|
+
// make sure we didn't reconnect before the promise resolved
|
|
1056
|
+
if (this.delayConnectClientId === clientId && !this.disposed) {
|
|
1057
|
+
this.delayConnectClientId = undefined;
|
|
1058
|
+
this.setConnectionStateCore(connected, clientId);
|
|
1059
|
+
}
|
|
1060
|
+
}, (error) => this.closeFn(error));
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
this.setConnectionStateCore(connected, clientId);
|
|
1064
|
+
}
|
|
1065
|
+
setConnectionStateCore(connected, clientId) {
|
|
1066
|
+
(0, common_utils_1.assert)(!this.delayConnectClientId, 0x394 /* connect event delay must be cleared before propagating connect event */);
|
|
1043
1067
|
this.verifyNotClosed();
|
|
1044
1068
|
// There might be no change of state due to Container calling this API after loading runtime.
|
|
1045
1069
|
const changeOfState = this._connected !== connected;
|
|
@@ -1070,7 +1094,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1070
1094
|
(0, telemetry_utils_1.raiseConnectedEvent)(this.mc.logger, this, connected, clientId);
|
|
1071
1095
|
}
|
|
1072
1096
|
process(messageArg, local) {
|
|
1073
|
-
var _a
|
|
1097
|
+
var _a;
|
|
1074
1098
|
this.verifyNotClosed();
|
|
1075
1099
|
// If it's not message for runtime, bail out right away.
|
|
1076
1100
|
if (!(0, driver_utils_1.isUnpackedRuntimeMessage)(messageArg)) {
|
|
@@ -1117,8 +1141,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1117
1141
|
this.dataStores.processFluidDataStoreOp(message, local, localOpMetadata);
|
|
1118
1142
|
break;
|
|
1119
1143
|
case ContainerMessageType.BlobAttach:
|
|
1120
|
-
|
|
1121
|
-
this.blobManager.processBlobAttachOp(message.metadata.blobId, local);
|
|
1144
|
+
this.blobManager.processBlobAttachOp(message, local);
|
|
1122
1145
|
break;
|
|
1123
1146
|
default:
|
|
1124
1147
|
}
|
|
@@ -1188,6 +1211,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1188
1211
|
this.dataStores.processSignal(envelope.address, transformed, local);
|
|
1189
1212
|
}
|
|
1190
1213
|
async getRootDataStore(id, wait = true) {
|
|
1214
|
+
return this.getRootDataStoreChannel(id, wait);
|
|
1215
|
+
}
|
|
1216
|
+
async getRootDataStoreChannel(id, wait = true) {
|
|
1217
|
+
await this.dataStores.waitIfPendingAlias(id);
|
|
1191
1218
|
const internalId = this.internalId(id);
|
|
1192
1219
|
const context = await this.dataStores.getDataStore(internalId, wait);
|
|
1193
1220
|
(0, common_utils_1.assert)(await context.isRoot(), 0x12b /* "did not get root data store" */);
|
|
@@ -1278,67 +1305,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1278
1305
|
}
|
|
1279
1306
|
async createDataStore(pkg) {
|
|
1280
1307
|
const internalId = (0, uuid_1.v4)();
|
|
1281
|
-
return (0, dataStore_1.channelToDataStore)(await this._createDataStore(pkg,
|
|
1282
|
-
}
|
|
1283
|
-
/**
|
|
1284
|
-
* Creates a root datastore directly with a user generated id and attaches it to storage.
|
|
1285
|
-
* It is vulnerable to name collisions and should not be used.
|
|
1286
|
-
*
|
|
1287
|
-
* This method will be removed. See #6465.
|
|
1288
|
-
*/
|
|
1289
|
-
async createRootDataStoreLegacy(pkg, rootDataStoreId) {
|
|
1290
|
-
const fluidDataStore = await this._createDataStore(pkg, true /* isRoot */, rootDataStoreId);
|
|
1291
|
-
// back-compat 0.59.1000 - makeVisibleAndAttachGraph was added in this version to IFluidDataStoreChannel. For
|
|
1292
|
-
// older versions, we still have to call bindToContext.
|
|
1293
|
-
if (fluidDataStore.makeVisibleAndAttachGraph !== undefined) {
|
|
1294
|
-
fluidDataStore.makeVisibleAndAttachGraph();
|
|
1295
|
-
}
|
|
1296
|
-
else {
|
|
1297
|
-
fluidDataStore.bindToContext();
|
|
1298
|
-
}
|
|
1299
|
-
return fluidDataStore;
|
|
1300
|
-
}
|
|
1301
|
-
/**
|
|
1302
|
-
* @deprecated - will be removed in an upcoming release. See #9660.
|
|
1303
|
-
*/
|
|
1304
|
-
async createRootDataStore(pkg, rootDataStoreId) {
|
|
1305
|
-
if (rootDataStoreId.includes("/")) {
|
|
1306
|
-
throw new container_utils_1.UsageError(`Id cannot contain slashes: '${rootDataStoreId}'`);
|
|
1307
|
-
}
|
|
1308
|
-
return this._aliasingEnabled === true ?
|
|
1309
|
-
this.createAndAliasDataStore(pkg, rootDataStoreId) :
|
|
1310
|
-
this.createRootDataStoreLegacy(pkg, rootDataStoreId);
|
|
1311
|
-
}
|
|
1312
|
-
/**
|
|
1313
|
-
* Creates a data store then attempts to alias it.
|
|
1314
|
-
* If aliasing fails, it will raise an exception.
|
|
1315
|
-
*
|
|
1316
|
-
* This method will be removed. See #6465.
|
|
1317
|
-
*
|
|
1318
|
-
* @param pkg - Package name of the data store
|
|
1319
|
-
* @param alias - Alias to be assigned to the data store
|
|
1320
|
-
* @param props - Properties for the data store
|
|
1321
|
-
* @returns - An aliased data store which can can be found / loaded by alias.
|
|
1322
|
-
*/
|
|
1323
|
-
async createAndAliasDataStore(pkg, alias, props) {
|
|
1324
|
-
const internalId = (0, uuid_1.v4)();
|
|
1325
|
-
const dataStore = await this._createDataStore(pkg, false /* isRoot */, internalId, props);
|
|
1326
|
-
const aliasedDataStore = (0, dataStore_1.channelToDataStore)(dataStore, internalId, this, this.dataStores, this.mc.logger);
|
|
1327
|
-
const result = await aliasedDataStore.trySetAlias(alias);
|
|
1328
|
-
if (result !== "Success") {
|
|
1329
|
-
throw new container_utils_1.GenericError("dataStoreAliasFailure", undefined /* error */, {
|
|
1330
|
-
alias: {
|
|
1331
|
-
value: alias,
|
|
1332
|
-
tag: telemetry_utils_1.TelemetryDataTag.UserData,
|
|
1333
|
-
},
|
|
1334
|
-
internalId: {
|
|
1335
|
-
value: internalId,
|
|
1336
|
-
tag: telemetry_utils_1.TelemetryDataTag.PackageData,
|
|
1337
|
-
},
|
|
1338
|
-
aliasResult: result,
|
|
1339
|
-
});
|
|
1340
|
-
}
|
|
1341
|
-
return aliasedDataStore;
|
|
1308
|
+
return (0, dataStore_1.channelToDataStore)(await this._createDataStore(pkg, internalId), internalId, this, this.dataStores, this.mc.logger);
|
|
1342
1309
|
}
|
|
1343
1310
|
createDetachedRootDataStore(pkg, rootDataStoreId) {
|
|
1344
1311
|
if (rootDataStoreId.includes("/")) {
|
|
@@ -1349,38 +1316,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1349
1316
|
createDetachedDataStore(pkg) {
|
|
1350
1317
|
return this.dataStores.createDetachedDataStoreCore(pkg, false);
|
|
1351
1318
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
* It is vulnerable to name collisions if both aforementioned conditions are true, and should not be used.
|
|
1355
|
-
*
|
|
1356
|
-
* This method will be removed. See #6465.
|
|
1357
|
-
*/
|
|
1358
|
-
async _createDataStoreWithPropsLegacy(pkg, props, id = (0, uuid_1.v4)(), isRoot = false) {
|
|
1359
|
-
const fluidDataStore = await this.dataStores._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, isRoot, props).realize();
|
|
1360
|
-
if (isRoot) {
|
|
1361
|
-
// back-compat 0.59.1000 - makeVisibleAndAttachGraph was added in this version to IFluidDataStoreChannel.
|
|
1362
|
-
// For older versions, we still have to call bindToContext.
|
|
1363
|
-
if (fluidDataStore.makeVisibleAndAttachGraph !== undefined) {
|
|
1364
|
-
fluidDataStore.makeVisibleAndAttachGraph();
|
|
1365
|
-
}
|
|
1366
|
-
else {
|
|
1367
|
-
fluidDataStore.bindToContext();
|
|
1368
|
-
}
|
|
1369
|
-
this.logger.sendTelemetryEvent({
|
|
1370
|
-
eventName: "Root datastore with props",
|
|
1371
|
-
hasProps: props !== undefined,
|
|
1372
|
-
});
|
|
1373
|
-
}
|
|
1319
|
+
async _createDataStoreWithProps(pkg, props, id = (0, uuid_1.v4)()) {
|
|
1320
|
+
const fluidDataStore = await this.dataStores._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props).realize();
|
|
1374
1321
|
return (0, dataStore_1.channelToDataStore)(fluidDataStore, id, this, this.dataStores, this.mc.logger);
|
|
1375
1322
|
}
|
|
1376
|
-
async
|
|
1377
|
-
return this._aliasingEnabled === true && isRoot ?
|
|
1378
|
-
this.createAndAliasDataStore(pkg, id, props) :
|
|
1379
|
-
this._createDataStoreWithPropsLegacy(pkg, props, id, isRoot);
|
|
1380
|
-
}
|
|
1381
|
-
async _createDataStore(pkg, isRoot, id = (0, uuid_1.v4)(), props) {
|
|
1323
|
+
async _createDataStore(pkg, id = (0, uuid_1.v4)(), props) {
|
|
1382
1324
|
return this.dataStores
|
|
1383
|
-
._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id,
|
|
1325
|
+
._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props)
|
|
1384
1326
|
.realize();
|
|
1385
1327
|
}
|
|
1386
1328
|
canSendOps() {
|
|
@@ -1646,7 +1588,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1646
1588
|
* @param options - options controlling how the summary is generated or submitted
|
|
1647
1589
|
*/
|
|
1648
1590
|
async submitSummary(options) {
|
|
1649
|
-
var _a, _b
|
|
1591
|
+
var _a, _b;
|
|
1650
1592
|
const { fullTree, refreshLatestAck, summaryLogger } = options;
|
|
1651
1593
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
1652
1594
|
// use it for all events logged during this summary.
|
|
@@ -1654,16 +1596,19 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1654
1596
|
const summaryNumberLogger = telemetry_utils_1.ChildLogger.create(summaryLogger, undefined, {
|
|
1655
1597
|
all: { summaryNumber },
|
|
1656
1598
|
});
|
|
1599
|
+
let latestSnapshotVersionId;
|
|
1657
1600
|
if (refreshLatestAck) {
|
|
1658
|
-
const
|
|
1659
|
-
|
|
1601
|
+
const latestSnapshotInfo = await this.refreshLatestSummaryAckFromServer(telemetry_utils_1.ChildLogger.create(summaryNumberLogger, undefined, { all: { safeSummary: true } }));
|
|
1602
|
+
const latestSnapshotRefSeq = latestSnapshotInfo.latestSnapshotRefSeq;
|
|
1603
|
+
latestSnapshotVersionId = latestSnapshotInfo.latestSnapshotVersionId;
|
|
1604
|
+
if (latestSnapshotRefSeq > this.deltaManager.lastSequenceNumber) {
|
|
1660
1605
|
// We need to catch up to the latest summary's reference sequence number before pausing.
|
|
1661
1606
|
await telemetry_utils_1.PerformanceEvent.timedExecAsync(summaryNumberLogger, {
|
|
1662
1607
|
eventName: "WaitingForSeq",
|
|
1663
1608
|
lastSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
1664
|
-
targetSequenceNumber:
|
|
1609
|
+
targetSequenceNumber: latestSnapshotRefSeq,
|
|
1665
1610
|
lastKnownSeqNumber: this.deltaManager.lastKnownSeqNumber,
|
|
1666
|
-
}, async () => waitForSeq(this.deltaManager,
|
|
1611
|
+
}, async () => waitForSeq(this.deltaManager, latestSnapshotRefSeq), { start: true, end: true, cancel: "error" });
|
|
1667
1612
|
}
|
|
1668
1613
|
}
|
|
1669
1614
|
try {
|
|
@@ -1671,17 +1616,11 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1671
1616
|
const summaryRefSeqNum = this.deltaManager.lastSequenceNumber;
|
|
1672
1617
|
const minimumSequenceNumber = this.deltaManager.minimumSequenceNumber;
|
|
1673
1618
|
const message = `Summary @${summaryRefSeqNum}:${this.deltaManager.minimumSequenceNumber}`;
|
|
1674
|
-
|
|
1675
|
-
// doesn't match the last processed sequence number, log an error.
|
|
1676
|
-
if (summaryRefSeqNum !== ((_a = this.deltaManager.lastMessage) === null || _a === void 0 ? void 0 : _a.sequenceNumber)) {
|
|
1677
|
-
summaryNumberLogger.sendErrorEvent({
|
|
1678
|
-
eventName: "LastSequenceMismatch",
|
|
1679
|
-
error: message,
|
|
1680
|
-
});
|
|
1681
|
-
}
|
|
1619
|
+
const lastAck = this.summaryCollection.latestAck;
|
|
1682
1620
|
this.summarizerNode.startSummary(summaryRefSeqNum, summaryNumberLogger);
|
|
1683
1621
|
// Helper function to check whether we should still continue between each async step.
|
|
1684
1622
|
const checkContinue = () => {
|
|
1623
|
+
var _a;
|
|
1685
1624
|
// Do not check for loss of connectivity directly! Instead leave it up to
|
|
1686
1625
|
// RunWhileConnectedCoordinator to control policy in a single place.
|
|
1687
1626
|
// This will allow easier change of design if we chose to. For example, we may chose to allow
|
|
@@ -1705,6 +1644,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1705
1644
|
error: `lastSequenceNumber changed before uploading to storage. ${this.deltaManager.lastSequenceNumber} !== ${summaryRefSeqNum}`,
|
|
1706
1645
|
};
|
|
1707
1646
|
}
|
|
1647
|
+
(0, common_utils_1.assert)(summaryRefSeqNum === ((_a = this.deltaManager.lastMessage) === null || _a === void 0 ? void 0 : _a.sequenceNumber), 0x395 /* it's one and the same thing */);
|
|
1648
|
+
if (lastAck !== this.summaryCollection.latestAck) {
|
|
1649
|
+
return {
|
|
1650
|
+
continue: false,
|
|
1651
|
+
// eslint-disable-next-line max-len
|
|
1652
|
+
error: `Last summary changed while summarizing. ${this.summaryCollection.latestAck} !== ${lastAck}`,
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1708
1655
|
return { continue: true };
|
|
1709
1656
|
};
|
|
1710
1657
|
let continueResult = checkContinue();
|
|
@@ -1749,7 +1696,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1749
1696
|
const gcSummaryTreeStats = summaryTree.tree[garbageCollection_1.gcTreeKey]
|
|
1750
1697
|
? (0, runtime_utils_1.calculateStats)(summaryTree.tree[garbageCollection_1.gcTreeKey])
|
|
1751
1698
|
: undefined;
|
|
1752
|
-
const summaryStats = Object.assign({ dataStoreCount: this.dataStores.size, summarizedDataStoreCount: this.dataStores.size - handleCount, gcStateUpdatedDataStoreCount: (
|
|
1699
|
+
const summaryStats = Object.assign({ dataStoreCount: this.dataStores.size, summarizedDataStoreCount: this.dataStores.size - handleCount, gcStateUpdatedDataStoreCount: (_a = summarizeResult.gcStats) === null || _a === void 0 ? void 0 : _a.updatedDataStoreCount, gcBlobNodeCount: gcSummaryTreeStats === null || gcSummaryTreeStats === void 0 ? void 0 : gcSummaryTreeStats.blobNodeCount, gcTotalBlobsSize: gcSummaryTreeStats === null || gcSummaryTreeStats === void 0 ? void 0 : gcSummaryTreeStats.totalBlobSize, summaryNumber }, partialStats);
|
|
1753
1700
|
const generateSummaryData = {
|
|
1754
1701
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
1755
1702
|
minimumSequenceNumber,
|
|
@@ -1762,18 +1709,34 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1762
1709
|
if (!continueResult.continue) {
|
|
1763
1710
|
return Object.assign(Object.assign({ stage: "generate" }, generateSummaryData), { error: continueResult.error });
|
|
1764
1711
|
}
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1712
|
+
// It may happen that the lastAck it not correct due to missing summaryAck in case of single commit
|
|
1713
|
+
// summary. So if the previous summarizer closes just after submitting the summary and before
|
|
1714
|
+
// submitting the summaryOp then we can't rely on summaryAck. So in case we have
|
|
1715
|
+
// latestSnapshotVersionId from storage and it does not match with the lastAck ackHandle, then use
|
|
1716
|
+
// the one fetched from storage as parent as that is the latest.
|
|
1717
|
+
let summaryContext;
|
|
1718
|
+
if ((lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck.contents.handle) !== latestSnapshotVersionId
|
|
1719
|
+
&& latestSnapshotVersionId !== undefined) {
|
|
1720
|
+
summaryContext = {
|
|
1768
1721
|
proposalHandle: undefined,
|
|
1769
|
-
ackHandle:
|
|
1722
|
+
ackHandle: latestSnapshotVersionId,
|
|
1770
1723
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
1771
|
-
}
|
|
1772
|
-
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1726
|
+
else if (lastAck === undefined) {
|
|
1727
|
+
summaryContext = {
|
|
1728
|
+
proposalHandle: undefined,
|
|
1729
|
+
ackHandle: (_b = this.context.getLoadedFromVersion()) === null || _b === void 0 ? void 0 : _b.id,
|
|
1730
|
+
referenceSequenceNumber: summaryRefSeqNum,
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1733
|
+
else {
|
|
1734
|
+
summaryContext = {
|
|
1773
1735
|
proposalHandle: lastAck.summaryOp.contents.handle,
|
|
1774
1736
|
ackHandle: lastAck.summaryAck.contents.handle,
|
|
1775
1737
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
1776
1738
|
};
|
|
1739
|
+
}
|
|
1777
1740
|
let handle;
|
|
1778
1741
|
try {
|
|
1779
1742
|
handle = await this.storage.uploadSummaryWithContext(summarizeResult.summary, summaryContext);
|
|
@@ -1803,7 +1766,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1803
1766
|
}
|
|
1804
1767
|
const submitData = Object.assign(Object.assign({ stage: "submit" }, uploadData), { clientSequenceNumber, submitOpDuration: trace.trace().duration });
|
|
1805
1768
|
this.summarizerNode.completeSummary(handle);
|
|
1806
|
-
this.opTracker.reset();
|
|
1807
1769
|
return submitData;
|
|
1808
1770
|
}
|
|
1809
1771
|
finally {
|
|
@@ -1914,14 +1876,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1914
1876
|
// instead of splitting the content, we will fail by explicitly close the container
|
|
1915
1877
|
this.closeFn(new container_utils_1.GenericError("OpTooLarge",
|
|
1916
1878
|
/* error */ undefined, {
|
|
1917
|
-
length:
|
|
1918
|
-
|
|
1919
|
-
tag: telemetry_utils_1.TelemetryDataTag.PackageData,
|
|
1920
|
-
},
|
|
1921
|
-
limit: {
|
|
1922
|
-
value: this._maxOpSizeInBytes,
|
|
1923
|
-
tag: telemetry_utils_1.TelemetryDataTag.PackageData,
|
|
1924
|
-
},
|
|
1879
|
+
length: serializedContent.length,
|
|
1880
|
+
limit: this._maxOpSizeInBytes,
|
|
1925
1881
|
}));
|
|
1926
1882
|
return -1;
|
|
1927
1883
|
}
|
|
@@ -1996,7 +1952,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
1996
1952
|
case ContainerMessageType.ChunkedOp:
|
|
1997
1953
|
throw new Error(`chunkedOp not expected here`);
|
|
1998
1954
|
case ContainerMessageType.BlobAttach:
|
|
1999
|
-
this.
|
|
1955
|
+
this.blobManager.reSubmit(opMetadata);
|
|
2000
1956
|
break;
|
|
2001
1957
|
case ContainerMessageType.Rejoin:
|
|
2002
1958
|
this.submit(type, content);
|
|
@@ -2019,12 +1975,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
2019
1975
|
/** Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck */
|
|
2020
1976
|
async refreshLatestSummaryAck(proposalHandle, ackHandle, summaryRefSeq, summaryLogger) {
|
|
2021
1977
|
const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
|
|
2022
|
-
const
|
|
1978
|
+
const { snapshotTree } = await this.fetchSnapshotFromStorage(ackHandle, summaryLogger, {
|
|
2023
1979
|
eventName: "RefreshLatestSummaryGetSnapshot",
|
|
2024
1980
|
ackHandle,
|
|
2025
1981
|
summaryRefSeq,
|
|
2026
1982
|
fetchLatest: false,
|
|
2027
|
-
})
|
|
1983
|
+
});
|
|
1984
|
+
const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq, async () => snapshotTree, readAndParseBlob, summaryLogger);
|
|
2028
1985
|
// Notify the garbage collector so it can update its latest summary state.
|
|
2029
1986
|
await this.garbageCollector.latestSummaryStateRefreshed(result, readAndParseBlob);
|
|
2030
1987
|
}
|
|
@@ -2035,29 +1992,29 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
2035
1992
|
* @returns downloaded snapshot's reference sequence number
|
|
2036
1993
|
*/
|
|
2037
1994
|
async refreshLatestSummaryAckFromServer(summaryLogger) {
|
|
2038
|
-
const
|
|
1995
|
+
const { snapshotTree, versionId } = await this.fetchSnapshotFromStorage(null, summaryLogger, {
|
|
2039
1996
|
eventName: "RefreshLatestSummaryGetSnapshot",
|
|
2040
1997
|
fetchLatest: true,
|
|
2041
|
-
});
|
|
1998
|
+
}, driver_definitions_1.FetchSource.noCache);
|
|
2042
1999
|
const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
|
|
2043
|
-
const
|
|
2044
|
-
const result = await this.summarizerNode.refreshLatestSummary(undefined,
|
|
2000
|
+
const latestSnapshotRefSeq = await (0, runtime_utils_1.seqFromTree)(snapshotTree, readAndParseBlob);
|
|
2001
|
+
const result = await this.summarizerNode.refreshLatestSummary(undefined, latestSnapshotRefSeq, async () => snapshotTree, readAndParseBlob, summaryLogger);
|
|
2045
2002
|
// Notify the garbage collector so it can update its latest summary state.
|
|
2046
2003
|
await this.garbageCollector.latestSummaryStateRefreshed(result, readAndParseBlob);
|
|
2047
|
-
return
|
|
2004
|
+
return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
|
|
2048
2005
|
}
|
|
2049
|
-
async fetchSnapshotFromStorage(versionId, logger, event) {
|
|
2006
|
+
async fetchSnapshotFromStorage(versionId, logger, event, fetchSource) {
|
|
2050
2007
|
return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
2051
2008
|
const stats = {};
|
|
2052
2009
|
const trace = common_utils_1.Trace.start();
|
|
2053
|
-
const versions = await this.storage.getVersions(versionId, 1);
|
|
2010
|
+
const versions = await this.storage.getVersions(versionId, 1, "refreshLatestSummaryAckFromServer", fetchSource);
|
|
2054
2011
|
(0, common_utils_1.assert)(!!versions && !!versions[0], 0x137 /* "Failed to get version from storage" */);
|
|
2055
2012
|
stats.getVersionDuration = trace.trace().duration;
|
|
2056
2013
|
const maybeSnapshot = await this.storage.getSnapshotTree(versions[0]);
|
|
2057
2014
|
(0, common_utils_1.assert)(!!maybeSnapshot, 0x138 /* "Failed to get snapshot from storage" */);
|
|
2058
2015
|
stats.getSnapshotDuration = trace.trace().duration;
|
|
2059
2016
|
perfEvent.end(stats);
|
|
2060
|
-
return maybeSnapshot;
|
|
2017
|
+
return { snapshotTree: maybeSnapshot, versionId: versions[0].id };
|
|
2061
2018
|
});
|
|
2062
2019
|
}
|
|
2063
2020
|
notifyAttaching(snapshot) {
|
|
@@ -2133,6 +2090,14 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
|
|
|
2133
2090
|
// don't have any more saved ops
|
|
2134
2091
|
await this.pendingStateManager.applyStashedOpsAt();
|
|
2135
2092
|
}
|
|
2093
|
+
validateSummaryHeuristicConfiguration(configuration) {
|
|
2094
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
2095
|
+
for (const prop in configuration) {
|
|
2096
|
+
if (typeof configuration[prop] === "number" && configuration[prop] < 0) {
|
|
2097
|
+
throw new container_utils_1.UsageError(`Summary heuristic configuration property "${prop}" cannot be less than 0`);
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2136
2101
|
}
|
|
2137
2102
|
exports.ContainerRuntime = ContainerRuntime;
|
|
2138
2103
|
/**
|