@fluidframework/container-runtime 2.0.0-internal.1.0.0.83139 → 2.0.0-internal.1.0.1
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.map +1 -1
- package/dist/blobManager.js +16 -16
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +1 -38
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +60 -109
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +2 -3
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStores.d.ts +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +2 -2
- package/dist/dataStores.js.map +1 -1
- 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.js +1 -1
- package/dist/runningSummarizer.js.map +1 -1
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +20 -1
- package/dist/summarizer.js.map +1 -1
- package/dist/summaryGenerator.js +1 -1
- 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.map +1 -1
- package/lib/blobManager.js +16 -16
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +1 -38
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +60 -109
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +2 -3
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStores.d.ts +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +2 -2
- package/lib/dataStores.js.map +1 -1
- 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.js +1 -1
- package/lib/runningSummarizer.js.map +1 -1
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +22 -3
- package/lib/summarizer.js.map +1 -1
- package/lib/summaryGenerator.js +1 -1
- package/lib/summaryGenerator.js.map +1 -1
- package/package.json +27 -18
- package/src/batchTracker.ts +1 -1
- package/src/blobManager.ts +20 -16
- package/src/containerRuntime.ts +84 -164
- package/src/dataStore.ts +1 -4
- package/src/dataStores.ts +13 -13
- package/src/packageVersion.ts +1 -1
- package/src/runningSummarizer.ts +1 -1
- package/src/summarizer.ts +28 -3
- package/src/summaryGenerator.ts +1 -1
package/lib/containerRuntime.js
CHANGED
|
@@ -74,7 +74,6 @@ export var RuntimeHeaders;
|
|
|
74
74
|
/** True if the request is coming from an IFluidHandle. */
|
|
75
75
|
RuntimeHeaders["viaHandle"] = "viaHandle";
|
|
76
76
|
})(RuntimeHeaders || (RuntimeHeaders = {}));
|
|
77
|
-
const useDataStoreAliasingKey = "Fluid.ContainerRuntime.UseDataStoreAliasing";
|
|
78
77
|
const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
|
|
79
78
|
// Feature gate for the max op size. If the value is negative, chunking is enabled
|
|
80
79
|
// and all ops over 16k would be chunked. If the value is positive, all ops with
|
|
@@ -372,7 +371,7 @@ export function getDeviceSpec() {
|
|
|
372
371
|
*/
|
|
373
372
|
export class ContainerRuntime extends TypedEventEmitter {
|
|
374
373
|
constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration) {
|
|
375
|
-
var _a, _b, _c, _d, _e, _f
|
|
374
|
+
var _a, _b, _c, _d, _e, _f;
|
|
376
375
|
if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
|
|
377
376
|
super();
|
|
378
377
|
this.context = context;
|
|
@@ -441,15 +440,12 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
441
440
|
this.summarizerClientElectionEnabled = this.isSummarizerClientElectionEnabled();
|
|
442
441
|
this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
|
|
443
442
|
this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
|
|
444
|
-
this.
|
|
445
|
-
((_c = this.mc.config.getBoolean(useDataStoreAliasingKey)) !== null && _c !== void 0 ? _c : false) ||
|
|
446
|
-
((_d = runtimeOptions.useDataStoreAliasing) !== null && _d !== void 0 ? _d : false);
|
|
447
|
-
this._maxOpSizeInBytes = ((_e = this.mc.config.getNumber(maxOpSizeInBytesKey)) !== null && _e !== void 0 ? _e : defaultMaxOpSizeInBytes);
|
|
443
|
+
this._maxOpSizeInBytes = ((_c = this.mc.config.getNumber(maxOpSizeInBytesKey)) !== null && _c !== void 0 ? _c : defaultMaxOpSizeInBytes);
|
|
448
444
|
this.maxConsecutiveReconnects =
|
|
449
|
-
(
|
|
445
|
+
(_d = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _d !== void 0 ? _d : this.defaultMaxConsecutiveReconnects;
|
|
450
446
|
this._flushMode = runtimeOptions.flushMode;
|
|
451
447
|
const pendingRuntimeState = context.pendingLocalState;
|
|
452
|
-
const baseSnapshot = (
|
|
448
|
+
const baseSnapshot = (_e = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _e !== void 0 ? _e : context.baseSnapshot;
|
|
453
449
|
this.garbageCollector = GarbageCollector.create({
|
|
454
450
|
runtime: this,
|
|
455
451
|
gcOptions: this.runtimeOptions.gcOptions,
|
|
@@ -576,7 +572,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
576
572
|
};
|
|
577
573
|
// summaryNumber was renamed from summaryCount. For older docs that haven't been opened for a long time,
|
|
578
574
|
// the count is reset to 0.
|
|
579
|
-
loadSummaryNumber = (
|
|
575
|
+
loadSummaryNumber = (_f = metadata === null || metadata === void 0 ? void 0 : metadata.summaryNumber) !== null && _f !== void 0 ? _f : 0;
|
|
580
576
|
}
|
|
581
577
|
else {
|
|
582
578
|
this.createContainerMetadata = {
|
|
@@ -611,7 +607,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
611
607
|
runtimeVersion: pkgVersion,
|
|
612
608
|
},
|
|
613
609
|
});
|
|
614
|
-
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close",
|
|
610
|
+
const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, enableOfflineLoad = false, } = runtimeOptions;
|
|
615
611
|
const pendingRuntimeState = context.pendingLocalState;
|
|
616
612
|
const baseSnapshot = (_b = pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.baseSnapshot) !== null && _b !== void 0 ? _b : context.baseSnapshot;
|
|
617
613
|
const storage = !pendingRuntimeState ?
|
|
@@ -664,7 +660,6 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
664
660
|
summaryOptions,
|
|
665
661
|
gcOptions,
|
|
666
662
|
loadSequenceNumberVerification,
|
|
667
|
-
useDataStoreAliasing,
|
|
668
663
|
flushMode,
|
|
669
664
|
enableOfflineLoad,
|
|
670
665
|
}, containerScope, logger, loadExisting, blobManagerSnapshot, storage, requestHandler);
|
|
@@ -1046,8 +1041,8 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1046
1041
|
// ensure we don't submit ops referencing a blob that has not been uploaded
|
|
1047
1042
|
const connecting = connected && !this._connected && !this.deltaManager.readOnlyInfo.readonly;
|
|
1048
1043
|
if (connecting && this.blobManager.hasPendingOfflineUploads) {
|
|
1049
|
-
assert(!this.delayConnectClientId,
|
|
1050
|
-
assert(!!clientId,
|
|
1044
|
+
assert(!this.delayConnectClientId, 0x392 /* Connect event delay must be canceled before subsequent connect event */);
|
|
1045
|
+
assert(!!clientId, 0x393 /* Must have clientId when connecting */);
|
|
1051
1046
|
this.delayConnectClientId = clientId;
|
|
1052
1047
|
this.blobManager.onConnected().then(() => {
|
|
1053
1048
|
// make sure we didn't reconnect before the promise resolved
|
|
@@ -1061,7 +1056,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1061
1056
|
this.setConnectionStateCore(connected, clientId);
|
|
1062
1057
|
}
|
|
1063
1058
|
setConnectionStateCore(connected, clientId) {
|
|
1064
|
-
assert(!this.delayConnectClientId,
|
|
1059
|
+
assert(!this.delayConnectClientId, 0x394 /* connect event delay must be cleared before propagating connect event */);
|
|
1065
1060
|
this.verifyNotClosed();
|
|
1066
1061
|
// There might be no change of state due to Container calling this API after loading runtime.
|
|
1067
1062
|
const changeOfState = this._connected !== connected;
|
|
@@ -1303,59 +1298,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1303
1298
|
}
|
|
1304
1299
|
async createDataStore(pkg) {
|
|
1305
1300
|
const internalId = uuid();
|
|
1306
|
-
return channelToDataStore(await this._createDataStore(pkg,
|
|
1307
|
-
}
|
|
1308
|
-
/**
|
|
1309
|
-
* Creates a root datastore directly with a user generated id and attaches it to storage.
|
|
1310
|
-
* It is vulnerable to name collisions and should not be used.
|
|
1311
|
-
*
|
|
1312
|
-
* This method will be removed. See #6465.
|
|
1313
|
-
*/
|
|
1314
|
-
async createRootDataStoreLegacy(pkg, rootDataStoreId) {
|
|
1315
|
-
const fluidDataStore = await this._createDataStore(pkg, true /* isRoot */, rootDataStoreId);
|
|
1316
|
-
fluidDataStore.makeVisibleAndAttachGraph();
|
|
1317
|
-
return fluidDataStore;
|
|
1318
|
-
}
|
|
1319
|
-
/**
|
|
1320
|
-
* @deprecated - will be removed in an upcoming release. See #9660.
|
|
1321
|
-
*/
|
|
1322
|
-
async createRootDataStore(pkg, rootDataStoreId) {
|
|
1323
|
-
if (rootDataStoreId.includes("/")) {
|
|
1324
|
-
throw new UsageError(`Id cannot contain slashes: '${rootDataStoreId}'`);
|
|
1325
|
-
}
|
|
1326
|
-
return this._aliasingEnabled === true ?
|
|
1327
|
-
this.createAndAliasDataStore(pkg, rootDataStoreId) :
|
|
1328
|
-
this.createRootDataStoreLegacy(pkg, rootDataStoreId);
|
|
1329
|
-
}
|
|
1330
|
-
/**
|
|
1331
|
-
* Creates a data store then attempts to alias it.
|
|
1332
|
-
* If aliasing fails, it will raise an exception.
|
|
1333
|
-
*
|
|
1334
|
-
* This method will be removed. See #6465.
|
|
1335
|
-
*
|
|
1336
|
-
* @param pkg - Package name of the data store
|
|
1337
|
-
* @param alias - Alias to be assigned to the data store
|
|
1338
|
-
* @param props - Properties for the data store
|
|
1339
|
-
* @returns - An aliased data store which can can be found / loaded by alias.
|
|
1340
|
-
*/
|
|
1341
|
-
async createAndAliasDataStore(pkg, alias, props) {
|
|
1342
|
-
const internalId = uuid();
|
|
1343
|
-
try {
|
|
1344
|
-
// A similar call may have been initiated by the same client, so we should try to get
|
|
1345
|
-
// a possible existing aliased datastore first.
|
|
1346
|
-
const existingDataStore = await this.getRootDataStoreChannel(alias, /* wait */ false);
|
|
1347
|
-
return channelToDataStore(existingDataStore, internalId, this, this.dataStores, this.mc.logger, true);
|
|
1348
|
-
}
|
|
1349
|
-
catch (err) {
|
|
1350
|
-
const newChannel = await this._createDataStore(pkg, false /* isRoot */, internalId, props);
|
|
1351
|
-
const newDataStore = channelToDataStore(newChannel, internalId, this, this.dataStores, this.mc.logger);
|
|
1352
|
-
const aliasResult = await newDataStore.trySetAlias(alias);
|
|
1353
|
-
if (aliasResult === "Success") {
|
|
1354
|
-
return newDataStore;
|
|
1355
|
-
}
|
|
1356
|
-
const existingDataStore = await this.getRootDataStoreChannel(alias, /* wait */ false);
|
|
1357
|
-
return channelToDataStore(existingDataStore, internalId, this, this.dataStores, this.mc.logger, true);
|
|
1358
|
-
}
|
|
1301
|
+
return channelToDataStore(await this._createDataStore(pkg, internalId), internalId, this, this.dataStores, this.mc.logger);
|
|
1359
1302
|
}
|
|
1360
1303
|
createDetachedRootDataStore(pkg, rootDataStoreId) {
|
|
1361
1304
|
if (rootDataStoreId.includes("/")) {
|
|
@@ -1366,31 +1309,13 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1366
1309
|
createDetachedDataStore(pkg) {
|
|
1367
1310
|
return this.dataStores.createDetachedDataStoreCore(pkg, false);
|
|
1368
1311
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
* It is vulnerable to name collisions if both aforementioned conditions are true, and should not be used.
|
|
1372
|
-
*
|
|
1373
|
-
* This method will be removed. See #6465.
|
|
1374
|
-
*/
|
|
1375
|
-
async _createDataStoreWithPropsLegacy(pkg, props, id = uuid(), isRoot = false) {
|
|
1376
|
-
const fluidDataStore = await this.dataStores._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, isRoot, props).realize();
|
|
1377
|
-
if (isRoot) {
|
|
1378
|
-
fluidDataStore.makeVisibleAndAttachGraph();
|
|
1379
|
-
this.logger.sendTelemetryEvent({
|
|
1380
|
-
eventName: "Root datastore with props",
|
|
1381
|
-
hasProps: props !== undefined,
|
|
1382
|
-
});
|
|
1383
|
-
}
|
|
1312
|
+
async _createDataStoreWithProps(pkg, props, id = uuid()) {
|
|
1313
|
+
const fluidDataStore = await this.dataStores._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props).realize();
|
|
1384
1314
|
return channelToDataStore(fluidDataStore, id, this, this.dataStores, this.mc.logger);
|
|
1385
1315
|
}
|
|
1386
|
-
async
|
|
1387
|
-
return this._aliasingEnabled === true && isRoot ?
|
|
1388
|
-
this.createAndAliasDataStore(pkg, id, props) :
|
|
1389
|
-
this._createDataStoreWithPropsLegacy(pkg, props, id, isRoot);
|
|
1390
|
-
}
|
|
1391
|
-
async _createDataStore(pkg, isRoot, id = uuid(), props) {
|
|
1316
|
+
async _createDataStore(pkg, id = uuid(), props) {
|
|
1392
1317
|
return this.dataStores
|
|
1393
|
-
._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id,
|
|
1318
|
+
._createFluidDataStoreContext(Array.isArray(pkg) ? pkg : [pkg], id, props)
|
|
1394
1319
|
.realize();
|
|
1395
1320
|
}
|
|
1396
1321
|
canSendOps() {
|
|
@@ -1664,16 +1589,19 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1664
1589
|
const summaryNumberLogger = ChildLogger.create(summaryLogger, undefined, {
|
|
1665
1590
|
all: { summaryNumber },
|
|
1666
1591
|
});
|
|
1592
|
+
let latestSnapshotVersionId;
|
|
1667
1593
|
if (refreshLatestAck) {
|
|
1668
|
-
const
|
|
1669
|
-
|
|
1594
|
+
const latestSnapshotInfo = await this.refreshLatestSummaryAckFromServer(ChildLogger.create(summaryNumberLogger, undefined, { all: { safeSummary: true } }));
|
|
1595
|
+
const latestSnapshotRefSeq = latestSnapshotInfo.latestSnapshotRefSeq;
|
|
1596
|
+
latestSnapshotVersionId = latestSnapshotInfo.latestSnapshotVersionId;
|
|
1597
|
+
if (latestSnapshotRefSeq > this.deltaManager.lastSequenceNumber) {
|
|
1670
1598
|
// We need to catch up to the latest summary's reference sequence number before pausing.
|
|
1671
1599
|
await PerformanceEvent.timedExecAsync(summaryNumberLogger, {
|
|
1672
1600
|
eventName: "WaitingForSeq",
|
|
1673
1601
|
lastSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
1674
|
-
targetSequenceNumber:
|
|
1602
|
+
targetSequenceNumber: latestSnapshotRefSeq,
|
|
1675
1603
|
lastKnownSeqNumber: this.deltaManager.lastKnownSeqNumber,
|
|
1676
|
-
}, async () => waitForSeq(this.deltaManager,
|
|
1604
|
+
}, async () => waitForSeq(this.deltaManager, latestSnapshotRefSeq), { start: true, end: true, cancel: "error" });
|
|
1677
1605
|
}
|
|
1678
1606
|
}
|
|
1679
1607
|
try {
|
|
@@ -1709,7 +1637,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1709
1637
|
error: `lastSequenceNumber changed before uploading to storage. ${this.deltaManager.lastSequenceNumber} !== ${summaryRefSeqNum}`,
|
|
1710
1638
|
};
|
|
1711
1639
|
}
|
|
1712
|
-
assert(summaryRefSeqNum === ((_a = this.deltaManager.lastMessage) === null || _a === void 0 ? void 0 : _a.sequenceNumber),
|
|
1640
|
+
assert(summaryRefSeqNum === ((_a = this.deltaManager.lastMessage) === null || _a === void 0 ? void 0 : _a.sequenceNumber), 0x395 /* it's one and the same thing */);
|
|
1713
1641
|
if (lastAck !== this.summaryCollection.latestAck) {
|
|
1714
1642
|
return {
|
|
1715
1643
|
continue: false,
|
|
@@ -1774,17 +1702,34 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
1774
1702
|
if (!continueResult.continue) {
|
|
1775
1703
|
return Object.assign(Object.assign({ stage: "generate" }, generateSummaryData), { error: continueResult.error });
|
|
1776
1704
|
}
|
|
1777
|
-
|
|
1778
|
-
|
|
1705
|
+
// It may happen that the lastAck it not correct due to missing summaryAck in case of single commit
|
|
1706
|
+
// summary. So if the previous summarizer closes just after submitting the summary and before
|
|
1707
|
+
// submitting the summaryOp then we can't rely on summaryAck. So in case we have
|
|
1708
|
+
// latestSnapshotVersionId from storage and it does not match with the lastAck ackHandle, then use
|
|
1709
|
+
// the one fetched from storage as parent as that is the latest.
|
|
1710
|
+
let summaryContext;
|
|
1711
|
+
if ((lastAck === null || lastAck === void 0 ? void 0 : lastAck.summaryAck.contents.handle) !== latestSnapshotVersionId
|
|
1712
|
+
&& latestSnapshotVersionId !== undefined) {
|
|
1713
|
+
summaryContext = {
|
|
1714
|
+
proposalHandle: undefined,
|
|
1715
|
+
ackHandle: latestSnapshotVersionId,
|
|
1716
|
+
referenceSequenceNumber: summaryRefSeqNum,
|
|
1717
|
+
};
|
|
1718
|
+
}
|
|
1719
|
+
else if (lastAck === undefined) {
|
|
1720
|
+
summaryContext = {
|
|
1779
1721
|
proposalHandle: undefined,
|
|
1780
1722
|
ackHandle: (_b = this.context.getLoadedFromVersion()) === null || _b === void 0 ? void 0 : _b.id,
|
|
1781
1723
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
1782
|
-
}
|
|
1783
|
-
|
|
1724
|
+
};
|
|
1725
|
+
}
|
|
1726
|
+
else {
|
|
1727
|
+
summaryContext = {
|
|
1784
1728
|
proposalHandle: lastAck.summaryOp.contents.handle,
|
|
1785
1729
|
ackHandle: lastAck.summaryAck.contents.handle,
|
|
1786
1730
|
referenceSequenceNumber: summaryRefSeqNum,
|
|
1787
1731
|
};
|
|
1732
|
+
}
|
|
1788
1733
|
let handle;
|
|
1789
1734
|
try {
|
|
1790
1735
|
handle = await this.storage.uploadSummaryWithContext(summarizeResult.summary, summaryContext);
|
|
@@ -2023,12 +1968,18 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2023
1968
|
/** Implementation of ISummarizerInternalsProvider.refreshLatestSummaryAck */
|
|
2024
1969
|
async refreshLatestSummaryAck(proposalHandle, ackHandle, summaryRefSeq, summaryLogger) {
|
|
2025
1970
|
const readAndParseBlob = async (id) => readAndParse(this.storage, id);
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
1971
|
+
// The call to fetch the snapshot is very expensive and not always needed.
|
|
1972
|
+
// It should only be done by the summarizerNode, if required.
|
|
1973
|
+
const snapshotTreeFetcher = async () => {
|
|
1974
|
+
const fetchResult = await this.fetchSnapshotFromStorage(ackHandle, summaryLogger, {
|
|
1975
|
+
eventName: "RefreshLatestSummaryGetSnapshot",
|
|
1976
|
+
ackHandle,
|
|
1977
|
+
summaryRefSeq,
|
|
1978
|
+
fetchLatest: false,
|
|
1979
|
+
});
|
|
1980
|
+
return fetchResult.snapshotTree;
|
|
1981
|
+
};
|
|
1982
|
+
const result = await this.summarizerNode.refreshLatestSummary(proposalHandle, summaryRefSeq, snapshotTreeFetcher, readAndParseBlob, summaryLogger);
|
|
2032
1983
|
// Notify the garbage collector so it can update its latest summary state.
|
|
2033
1984
|
await this.garbageCollector.latestSummaryStateRefreshed(result, readAndParseBlob);
|
|
2034
1985
|
}
|
|
@@ -2039,16 +1990,16 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2039
1990
|
* @returns downloaded snapshot's reference sequence number
|
|
2040
1991
|
*/
|
|
2041
1992
|
async refreshLatestSummaryAckFromServer(summaryLogger) {
|
|
2042
|
-
const
|
|
1993
|
+
const { snapshotTree, versionId } = await this.fetchSnapshotFromStorage(null, summaryLogger, {
|
|
2043
1994
|
eventName: "RefreshLatestSummaryGetSnapshot",
|
|
2044
1995
|
fetchLatest: true,
|
|
2045
1996
|
}, FetchSource.noCache);
|
|
2046
1997
|
const readAndParseBlob = async (id) => readAndParse(this.storage, id);
|
|
2047
|
-
const
|
|
2048
|
-
const result = await this.summarizerNode.refreshLatestSummary(undefined,
|
|
1998
|
+
const latestSnapshotRefSeq = await seqFromTree(snapshotTree, readAndParseBlob);
|
|
1999
|
+
const result = await this.summarizerNode.refreshLatestSummary(undefined, latestSnapshotRefSeq, async () => snapshotTree, readAndParseBlob, summaryLogger);
|
|
2049
2000
|
// Notify the garbage collector so it can update its latest summary state.
|
|
2050
2001
|
await this.garbageCollector.latestSummaryStateRefreshed(result, readAndParseBlob);
|
|
2051
|
-
return
|
|
2002
|
+
return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
|
|
2052
2003
|
}
|
|
2053
2004
|
async fetchSnapshotFromStorage(versionId, logger, event, fetchSource) {
|
|
2054
2005
|
return PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
|
|
@@ -2061,7 +2012,7 @@ export class ContainerRuntime extends TypedEventEmitter {
|
|
|
2061
2012
|
assert(!!maybeSnapshot, 0x138 /* "Failed to get snapshot from storage" */);
|
|
2062
2013
|
stats.getSnapshotDuration = trace.trace().duration;
|
|
2063
2014
|
perfEvent.end(stats);
|
|
2064
|
-
return maybeSnapshot;
|
|
2015
|
+
return { snapshotTree: maybeSnapshot, versionId: versions[0].id };
|
|
2065
2016
|
});
|
|
2066
2017
|
}
|
|
2067
2018
|
notifyAttaching(snapshot) {
|