@fluidframework/container-runtime 2.61.0 → 2.62.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/.eslintrc.cjs +4 -72
- package/CHANGELOG.md +4 -0
- package/container-runtime.test-files.tar +0 -0
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +10 -7
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
- package/dist/channelCollection.js +2 -2
- package/dist/channelCollection.js.map +1 -1
- package/dist/containerRuntime.d.ts +1 -2
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +93 -96
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +2 -2
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/deltaScheduler.js +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +3 -1
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.js +3 -1
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +4 -3
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/inboundBatchAggregator.js +1 -1
- package/dist/inboundBatchAggregator.js.map +1 -1
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +2 -1
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +2 -2
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +8 -3
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js +3 -2
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.js +1 -1
- package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js +1 -1
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +10 -7
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
- package/lib/channelCollection.js +2 -2
- package/lib/channelCollection.js.map +1 -1
- package/lib/containerRuntime.d.ts +1 -2
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +22 -25
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +2 -2
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/deltaScheduler.js +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +3 -1
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.js +3 -1
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +4 -3
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/inboundBatchAggregator.js +1 -1
- package/lib/inboundBatchAggregator.js.map +1 -1
- package/lib/metadata.d.ts.map +1 -1
- package/lib/metadata.js +2 -1
- package/lib/metadata.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +2 -2
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +8 -3
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js +3 -2
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.js +1 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js +1 -1
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
- package/package.json +18 -18
- package/src/blobManager/blobManager.ts +12 -7
- package/src/blobManager/blobManagerSnapSum.ts +1 -1
- package/src/channelCollection.ts +3 -3
- package/src/containerRuntime.ts +58 -65
- package/src/dataStoreContext.ts +3 -3
- package/src/deltaScheduler.ts +1 -1
- package/src/gc/garbageCollection.ts +5 -2
- package/src/gc/gcConfigs.ts +3 -3
- package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
- package/src/gc/gcTelemetry.ts +4 -5
- package/src/inboundBatchAggregator.ts +1 -1
- package/src/metadata.ts +2 -1
- package/src/opLifecycle/opGroupingManager.ts +2 -2
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +11 -5
- package/src/summary/summaryDelayLoadedModule/runningSummarizer.ts +3 -2
- package/src/summary/summaryDelayLoadedModule/summarizer.ts +1 -1
- package/src/summary/summaryDelayLoadedModule/summaryGenerator.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-runtime",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.62.0",
|
|
4
4
|
"description": "Fluid container runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -119,18 +119,18 @@
|
|
|
119
119
|
"temp-directory": "nyc/.nyc_output"
|
|
120
120
|
},
|
|
121
121
|
"dependencies": {
|
|
122
|
-
"@fluid-internal/client-utils": "~2.
|
|
123
|
-
"@fluidframework/container-definitions": "~2.
|
|
124
|
-
"@fluidframework/container-runtime-definitions": "~2.
|
|
125
|
-
"@fluidframework/core-interfaces": "~2.
|
|
126
|
-
"@fluidframework/core-utils": "~2.
|
|
127
|
-
"@fluidframework/datastore": "~2.
|
|
128
|
-
"@fluidframework/driver-definitions": "~2.
|
|
129
|
-
"@fluidframework/driver-utils": "~2.
|
|
130
|
-
"@fluidframework/id-compressor": "~2.
|
|
131
|
-
"@fluidframework/runtime-definitions": "~2.
|
|
132
|
-
"@fluidframework/runtime-utils": "~2.
|
|
133
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
122
|
+
"@fluid-internal/client-utils": "~2.62.0",
|
|
123
|
+
"@fluidframework/container-definitions": "~2.62.0",
|
|
124
|
+
"@fluidframework/container-runtime-definitions": "~2.62.0",
|
|
125
|
+
"@fluidframework/core-interfaces": "~2.62.0",
|
|
126
|
+
"@fluidframework/core-utils": "~2.62.0",
|
|
127
|
+
"@fluidframework/datastore": "~2.62.0",
|
|
128
|
+
"@fluidframework/driver-definitions": "~2.62.0",
|
|
129
|
+
"@fluidframework/driver-utils": "~2.62.0",
|
|
130
|
+
"@fluidframework/id-compressor": "~2.62.0",
|
|
131
|
+
"@fluidframework/runtime-definitions": "~2.62.0",
|
|
132
|
+
"@fluidframework/runtime-utils": "~2.62.0",
|
|
133
|
+
"@fluidframework/telemetry-utils": "~2.62.0",
|
|
134
134
|
"@tylerbu/sorted-btree-es6": "^1.8.0",
|
|
135
135
|
"double-ended-queue": "^2.1.0-0",
|
|
136
136
|
"lz4js": "^0.2.0",
|
|
@@ -140,16 +140,16 @@
|
|
|
140
140
|
"devDependencies": {
|
|
141
141
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
142
142
|
"@biomejs/biome": "~1.9.3",
|
|
143
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
144
|
-
"@fluid-private/stochastic-test-utils": "~2.
|
|
145
|
-
"@fluid-private/test-pairwise-generator": "~2.
|
|
143
|
+
"@fluid-internal/mocha-test-setup": "~2.62.0",
|
|
144
|
+
"@fluid-private/stochastic-test-utils": "~2.62.0",
|
|
145
|
+
"@fluid-private/test-pairwise-generator": "~2.62.0",
|
|
146
146
|
"@fluid-tools/benchmark": "^0.51.0",
|
|
147
147
|
"@fluid-tools/build-cli": "^0.58.3",
|
|
148
148
|
"@fluidframework/build-common": "^2.0.3",
|
|
149
149
|
"@fluidframework/build-tools": "^0.58.3",
|
|
150
150
|
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.60.0",
|
|
151
151
|
"@fluidframework/eslint-config-fluid": "^6.0.0",
|
|
152
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
152
|
+
"@fluidframework/test-runtime-utils": "~2.62.0",
|
|
153
153
|
"@microsoft/api-extractor": "7.52.11",
|
|
154
154
|
"@types/double-ended-queue": "^2.1.0",
|
|
155
155
|
"@types/lz4js": "^0.2.0",
|
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
"test:benchmark:report": "cross-env \"MOCHA_SPEC=dist/**/*.perf.spec.*js\" mocha --timeout 10s --perfMode --parentProcess --fgrep @Benchmark --fgrep @ExecutionTime --reporter @fluid-tools/benchmark/dist/MochaReporter.js",
|
|
214
214
|
"test:coverage": "c8 npm test",
|
|
215
215
|
"test:mocha": "npm run test:mocha:esm && echo skipping cjs to avoid overhead - npm run test:mocha:cjs",
|
|
216
|
-
"test:mocha:cjs": "cross-env
|
|
216
|
+
"test:mocha:cjs": "cross-env FLUID_TEST_MODULE_SYSTEM=CJS mocha",
|
|
217
217
|
"test:mocha:esm": "mocha",
|
|
218
218
|
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
219
219
|
"tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && npm run place:cjs:package-stub",
|
|
@@ -274,7 +274,10 @@ export class BlobManager {
|
|
|
274
274
|
pendingEntry !== undefined,
|
|
275
275
|
0x725 /* Must have pending blob entry for upcoming op */,
|
|
276
276
|
);
|
|
277
|
-
if (
|
|
277
|
+
if (
|
|
278
|
+
pendingEntry?.uploadTime !== undefined &&
|
|
279
|
+
pendingEntry?.minTTLInSeconds !== undefined
|
|
280
|
+
) {
|
|
278
281
|
const secondsSinceUpload = (Date.now() - pendingEntry.uploadTime) / 1000;
|
|
279
282
|
const expired = pendingEntry.minTTLInSeconds - secondsSinceUpload < 0;
|
|
280
283
|
this.mc.logger.sendTelemetryEvent({
|
|
@@ -376,6 +379,8 @@ export class BlobManager {
|
|
|
376
379
|
// eventually and wait. We do this even if the local client doesn't have the blob payloadPending flag
|
|
377
380
|
// enabled, in case a remote client does have it enabled. This wait may be infinite if the uploading
|
|
378
381
|
// client failed the upload and doesn't exist anymore.
|
|
382
|
+
// TODO: Fix this violation and remove the disable
|
|
383
|
+
// eslint-disable-next-line require-atomic-updates
|
|
379
384
|
storageId = await new Promise<string>((resolve) => {
|
|
380
385
|
const onProcessBlobAttach = (_localId: string, _storageId: string): void => {
|
|
381
386
|
if (_localId === localId) {
|
|
@@ -466,7 +471,7 @@ export class BlobManager {
|
|
|
466
471
|
blob: ArrayBufferLike,
|
|
467
472
|
signal?: AbortSignal,
|
|
468
473
|
): Promise<IFluidHandleInternalPayloadPending<ArrayBufferLike>> {
|
|
469
|
-
if (signal?.aborted) {
|
|
474
|
+
if (signal?.aborted === true) {
|
|
470
475
|
throw this.createAbortError();
|
|
471
476
|
}
|
|
472
477
|
|
|
@@ -485,7 +490,7 @@ export class BlobManager {
|
|
|
485
490
|
this.pendingBlobs.set(localId, pendingEntry);
|
|
486
491
|
|
|
487
492
|
const abortListener = (): void => {
|
|
488
|
-
if (
|
|
493
|
+
if (pendingEntry.acked !== true) {
|
|
489
494
|
pendingEntry.handleP.reject(this.createAbortError(pendingEntry));
|
|
490
495
|
}
|
|
491
496
|
};
|
|
@@ -593,7 +598,7 @@ export class BlobManager {
|
|
|
593
598
|
private deletePendingBlobMaybe(localId: string): void {
|
|
594
599
|
if (this.pendingBlobs.has(localId)) {
|
|
595
600
|
const entry = this.pendingBlobs.get(localId);
|
|
596
|
-
if (entry?.attached && entry?.acked) {
|
|
601
|
+
if (entry?.attached === true && entry?.acked === true) {
|
|
597
602
|
this.deletePendingBlob(localId);
|
|
598
603
|
}
|
|
599
604
|
}
|
|
@@ -612,7 +617,7 @@ export class BlobManager {
|
|
|
612
617
|
const entry = this.pendingBlobs.get(localId);
|
|
613
618
|
|
|
614
619
|
assert(entry !== undefined, 0x6c8 /* pending blob entry not found for uploaded blob */);
|
|
615
|
-
if (entry.abortSignal?.aborted === true &&
|
|
620
|
+
if (entry.abortSignal?.aborted === true && entry.opsent !== true) {
|
|
616
621
|
this.mc.logger.sendTelemetryEvent({
|
|
617
622
|
eventName: "BlobAborted",
|
|
618
623
|
localId,
|
|
@@ -632,7 +637,7 @@ export class BlobManager {
|
|
|
632
637
|
// until its storage ID is added to the next summary.
|
|
633
638
|
// 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
|
|
634
639
|
// blob from the server via the storage ID.
|
|
635
|
-
if (
|
|
640
|
+
if (entry.opsent !== true) {
|
|
636
641
|
this.sendBlobAttachOp(localId, response.id);
|
|
637
642
|
}
|
|
638
643
|
const storageIds = getStorageIds(this.redirectTable);
|
|
@@ -687,7 +692,7 @@ export class BlobManager {
|
|
|
687
692
|
);
|
|
688
693
|
const { localId, blobId: storageId } = message.metadata;
|
|
689
694
|
const pendingEntry = this.pendingBlobs.get(localId);
|
|
690
|
-
if (pendingEntry?.abortSignal?.aborted) {
|
|
695
|
+
if (pendingEntry?.abortSignal?.aborted === true) {
|
|
691
696
|
this.deletePendingBlob(localId);
|
|
692
697
|
return;
|
|
693
698
|
}
|
|
@@ -42,7 +42,7 @@ const loadV1 = async (
|
|
|
42
42
|
return {};
|
|
43
43
|
}
|
|
44
44
|
let redirectTableEntries: [string, string][] = [];
|
|
45
|
-
const tableId = blobsTree.blobs[redirectTableBlobName];
|
|
45
|
+
const tableId: string | undefined = blobsTree.blobs[redirectTableBlobName];
|
|
46
46
|
if (tableId) {
|
|
47
47
|
redirectTableEntries = await readAndParse(context.storage, tableId);
|
|
48
48
|
}
|
package/src/channelCollection.ts
CHANGED
|
@@ -545,7 +545,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
545
545
|
|
|
546
546
|
// If message timestamp doesn't exist, this is called in a detached container. Don't notify GC in that case
|
|
547
547
|
// because it doesn't run in detached container and doesn't need to know about this route.
|
|
548
|
-
if (messageTimestampMs) {
|
|
548
|
+
if (messageTimestampMs !== undefined) {
|
|
549
549
|
this.parentContext.addedGCOutboundRoute("/", `/${internalId}`, messageTimestampMs);
|
|
550
550
|
}
|
|
551
551
|
|
|
@@ -1613,8 +1613,8 @@ export function getSummaryForDatastores(
|
|
|
1613
1613
|
}
|
|
1614
1614
|
|
|
1615
1615
|
if (rootHasIsolatedChannels(metadata)) {
|
|
1616
|
-
const datastoresSnapshot = snapshot.trees[channelsTreeName];
|
|
1617
|
-
assert(
|
|
1616
|
+
const datastoresSnapshot: ISnapshotTree | undefined = snapshot.trees[channelsTreeName];
|
|
1617
|
+
assert(datastoresSnapshot !== undefined, 0x168 /* Expected tree in snapshot not found */);
|
|
1618
1618
|
return datastoresSnapshot;
|
|
1619
1619
|
} else {
|
|
1620
1620
|
// back-compat: strip out all non-datastore paths before giving to DataStores object.
|
package/src/containerRuntime.ts
CHANGED
|
@@ -83,6 +83,7 @@ import type {
|
|
|
83
83
|
ISnapshotTree,
|
|
84
84
|
ISummaryContent,
|
|
85
85
|
ISummaryContext,
|
|
86
|
+
SummaryObject,
|
|
86
87
|
} from "@fluidframework/driver-definitions/internal";
|
|
87
88
|
import { FetchSource, MessageType } from "@fluidframework/driver-definitions/internal";
|
|
88
89
|
import { readAndParse } from "@fluidframework/driver-utils/internal";
|
|
@@ -128,22 +129,20 @@ import type {
|
|
|
128
129
|
MinimumVersionForCollab,
|
|
129
130
|
} from "@fluidframework/runtime-definitions/internal";
|
|
130
131
|
import {
|
|
131
|
-
defaultMinVersionForCollab,
|
|
132
|
-
isValidMinVersionForCollab,
|
|
133
|
-
} from "@fluidframework/runtime-utils/internal";
|
|
134
|
-
import {
|
|
135
|
-
GCDataBuilder,
|
|
136
|
-
RequestParser,
|
|
137
|
-
RuntimeHeaders,
|
|
138
|
-
TelemetryContext,
|
|
139
132
|
addBlobToSummary,
|
|
140
133
|
addSummarizeResultToSummary,
|
|
141
134
|
calculateStats,
|
|
142
135
|
create404Response,
|
|
136
|
+
defaultMinVersionForCollab,
|
|
143
137
|
exceptionToResponse,
|
|
138
|
+
GCDataBuilder,
|
|
139
|
+
isValidMinVersionForCollab,
|
|
140
|
+
RequestParser,
|
|
141
|
+
RuntimeHeaders,
|
|
142
|
+
semanticVersionToMinimumVersionForCollab,
|
|
144
143
|
seqFromTree,
|
|
144
|
+
TelemetryContext,
|
|
145
145
|
} from "@fluidframework/runtime-utils/internal";
|
|
146
|
-
import { semanticVersionToMinimumVersionForCollab } from "@fluidframework/runtime-utils/internal";
|
|
147
146
|
import type {
|
|
148
147
|
IEventSampler,
|
|
149
148
|
IFluidErrorBase,
|
|
@@ -257,56 +256,54 @@ import {
|
|
|
257
256
|
} from "./runtimeLayerCompatState.js";
|
|
258
257
|
import { SignalTelemetryManager } from "./signalTelemetryProcessing.js";
|
|
259
258
|
// These types are imported as types here because they are present in summaryDelayLoadedModule, which is loaded dynamically when required.
|
|
260
|
-
import type {
|
|
261
|
-
IDocumentSchemaChangeMessageIncoming,
|
|
262
|
-
IDocumentSchemaCurrent,
|
|
263
|
-
Summarizer,
|
|
264
|
-
IDocumentSchemaFeatures,
|
|
265
|
-
EnqueueSummarizeResult,
|
|
266
|
-
ISerializedElection,
|
|
267
|
-
ISummarizeResults,
|
|
268
|
-
} from "./summary/index.js";
|
|
269
259
|
import {
|
|
260
|
+
aliasBlobName,
|
|
261
|
+
chunksBlobName,
|
|
262
|
+
createRootSummarizerNodeWithGC,
|
|
263
|
+
DefaultSummaryConfiguration,
|
|
270
264
|
DocumentsSchemaController,
|
|
265
|
+
electedSummarizerBlobName,
|
|
266
|
+
type EnqueueSummarizeResult,
|
|
267
|
+
extractSummaryMetadataMessage,
|
|
268
|
+
formCreateSummarizerFn,
|
|
271
269
|
type IBaseSummarizeResult,
|
|
272
270
|
type IConnectableRuntime,
|
|
273
271
|
type IContainerRuntimeMetadata,
|
|
274
272
|
type ICreateContainerMetadata,
|
|
273
|
+
idCompressorBlobName,
|
|
274
|
+
type IdCompressorMode,
|
|
275
|
+
type IDocumentSchemaChangeMessageIncoming,
|
|
276
|
+
type IDocumentSchemaCurrent,
|
|
277
|
+
type IDocumentSchemaFeatures,
|
|
275
278
|
type IEnqueueSummarizeOptions,
|
|
276
|
-
type IGenerateSummaryTreeResult,
|
|
277
279
|
type IGeneratedSummaryStats,
|
|
280
|
+
type IGenerateSummaryTreeResult,
|
|
278
281
|
type IOnDemandSummarizeOptions,
|
|
279
282
|
type IRefreshSummaryAckOptions,
|
|
280
283
|
type IRootSummarizerNodeWithGC,
|
|
284
|
+
type ISerializedElection,
|
|
285
|
+
isSummariesDisabled,
|
|
281
286
|
type ISubmitSummaryOptions,
|
|
287
|
+
type ISummarizeResults,
|
|
282
288
|
type ISummarizerInternalsProvider,
|
|
283
289
|
type ISummarizerRuntime,
|
|
290
|
+
type ISummaryConfiguration,
|
|
284
291
|
type ISummaryMetadataMessage,
|
|
285
|
-
|
|
292
|
+
metadataBlobName,
|
|
293
|
+
OrderedClientCollection,
|
|
286
294
|
OrderedClientElection,
|
|
287
|
-
RetriableSummaryError,
|
|
288
|
-
type SubmitSummaryResult,
|
|
289
|
-
aliasBlobName,
|
|
290
|
-
chunksBlobName,
|
|
291
295
|
recentBatchInfoBlobName,
|
|
292
|
-
|
|
293
|
-
electedSummarizerBlobName,
|
|
294
|
-
extractSummaryMetadataMessage,
|
|
295
|
-
idCompressorBlobName,
|
|
296
|
-
metadataBlobName,
|
|
296
|
+
RetriableSummaryError,
|
|
297
297
|
rootHasIsolatedChannels,
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
summarizerRequestUrl,
|
|
301
|
-
SummaryManager,
|
|
298
|
+
type SubmitSummaryResult,
|
|
299
|
+
type Summarizer,
|
|
302
300
|
SummarizerClientElection,
|
|
301
|
+
summarizerClientType,
|
|
302
|
+
summarizerRequestUrl,
|
|
303
303
|
SummaryCollection,
|
|
304
|
-
|
|
304
|
+
SummaryManager,
|
|
305
305
|
validateSummaryHeuristicConfiguration,
|
|
306
|
-
|
|
307
|
-
DefaultSummaryConfiguration,
|
|
308
|
-
isSummariesDisabled,
|
|
309
|
-
summarizerClientType,
|
|
306
|
+
wrapSummaryInChannelsTree,
|
|
310
307
|
} from "./summary/index.js";
|
|
311
308
|
import { Throttler, formExponentialFn } from "./throttler.js";
|
|
312
309
|
|
|
@@ -682,7 +679,7 @@ export const makeLegacySendBatchFn =
|
|
|
682
679
|
function lastMessageFromMetadata(
|
|
683
680
|
metadata: IContainerRuntimeMetadata | undefined,
|
|
684
681
|
): ISummaryMetadataMessage | undefined {
|
|
685
|
-
return metadata?.documentSchema?.runtime?.explicitSchemaControl
|
|
682
|
+
return metadata?.documentSchema?.runtime?.explicitSchemaControl === true
|
|
686
683
|
? metadata?.lastMessage
|
|
687
684
|
: metadata?.message;
|
|
688
685
|
}
|
|
@@ -973,7 +970,7 @@ export class ContainerRuntime
|
|
|
973
970
|
|
|
974
971
|
const tryFetchBlob = async <T>(blobName: string): Promise<T | undefined> => {
|
|
975
972
|
const blobId = context.baseSnapshot?.blobs[blobName];
|
|
976
|
-
if (context.baseSnapshot && blobId) {
|
|
973
|
+
if (context.baseSnapshot !== undefined && blobId !== undefined) {
|
|
977
974
|
// IContainerContext storage api return type still has undefined in 0.39 package version.
|
|
978
975
|
// So once we release 0.40 container-defn package we can remove this check.
|
|
979
976
|
assert(
|
|
@@ -1013,7 +1010,7 @@ export class ContainerRuntime
|
|
|
1013
1010
|
const runtimeSequenceNumber = messageAtLastSummary?.sequenceNumber;
|
|
1014
1011
|
const protocolSequenceNumber = context.deltaManager.initialSequenceNumber;
|
|
1015
1012
|
// When we load with pending state, we reuse an old snapshot so we don't expect these numbers to match
|
|
1016
|
-
if (
|
|
1013
|
+
if (context.pendingLocalState === undefined && runtimeSequenceNumber !== undefined) {
|
|
1017
1014
|
// Unless bypass is explicitly set, then take action when sequence numbers mismatch.
|
|
1018
1015
|
// eslint-disable-next-line unicorn/no-lonely-if -- Separate if statements make flow easier to parse
|
|
1019
1016
|
if (
|
|
@@ -1463,7 +1460,7 @@ export class ContainerRuntime
|
|
|
1463
1460
|
*/
|
|
1464
1461
|
private readonly loadedFromVersionId: string | undefined;
|
|
1465
1462
|
|
|
1466
|
-
private readonly isSnapshotInstanceOfISnapshot: boolean
|
|
1463
|
+
private readonly isSnapshotInstanceOfISnapshot: boolean;
|
|
1467
1464
|
|
|
1468
1465
|
/**
|
|
1469
1466
|
* The summary context of the last acked summary. The properties from this as used when uploading a summary.
|
|
@@ -1559,6 +1556,8 @@ export class ContainerRuntime
|
|
|
1559
1556
|
// In old loaders without dispose functionality, closeFn is equivalent but will also switch container to readonly mode
|
|
1560
1557
|
this.disposeFn = disposeFn ?? closeFn;
|
|
1561
1558
|
|
|
1559
|
+
this.isSnapshotInstanceOfISnapshot = snapshotWithContents !== undefined;
|
|
1560
|
+
|
|
1562
1561
|
// Validate that the Loader is compatible with this Runtime.
|
|
1563
1562
|
const maybeLoaderCompatDetailsForRuntime = context as FluidObject<ILayerCompatDetails>;
|
|
1564
1563
|
validateLoaderCompatibility(
|
|
@@ -1607,7 +1606,7 @@ export class ContainerRuntime
|
|
|
1607
1606
|
submitSignalFn(envelope, targetClientId);
|
|
1608
1607
|
};
|
|
1609
1608
|
this.submitSignalFn = (envelope: UnsequencedSignalEnvelope, targetClientId?: string) => {
|
|
1610
|
-
if (envelope.address?.startsWith("/")) {
|
|
1609
|
+
if (envelope.address?.startsWith("/") === true) {
|
|
1611
1610
|
throw new Error("General path based addressing is not implemented");
|
|
1612
1611
|
}
|
|
1613
1612
|
sequenceAndSubmitSignal(envelope, targetClientId);
|
|
@@ -1874,10 +1873,6 @@ export class ContainerRuntime
|
|
|
1874
1873
|
|
|
1875
1874
|
const parentContext = wrapContext(this);
|
|
1876
1875
|
|
|
1877
|
-
if (snapshotWithContents !== undefined) {
|
|
1878
|
-
this.isSnapshotInstanceOfISnapshot = true;
|
|
1879
|
-
}
|
|
1880
|
-
|
|
1881
1876
|
// Due to a mismatch between different layers in terms of
|
|
1882
1877
|
// what is the interface of passing signals, we need the
|
|
1883
1878
|
// downstream stores to wrap the signal.
|
|
@@ -2548,7 +2543,7 @@ export class ContainerRuntime
|
|
|
2548
2543
|
);
|
|
2549
2544
|
|
|
2550
2545
|
// Is document schema explicit control on?
|
|
2551
|
-
const explicitSchemaControl = documentSchema?.runtime.explicitSchemaControl;
|
|
2546
|
+
const explicitSchemaControl = documentSchema?.runtime.explicitSchemaControl === true;
|
|
2552
2547
|
|
|
2553
2548
|
const metadata: IContainerRuntimeMetadata = {
|
|
2554
2549
|
...this.createContainerMetadata,
|
|
@@ -2559,7 +2554,7 @@ export class ContainerRuntime
|
|
|
2559
2554
|
telemetryDocumentId: this.telemetryDocumentId,
|
|
2560
2555
|
// If explicit document schema control is not on, use legacy way to supply last message (using 'message' property).
|
|
2561
2556
|
// Otherwise use new 'lastMessage' property, but also put content into the 'message' property that cases old
|
|
2562
|
-
// runtimes (that
|
|
2557
|
+
// runtimes (that preceded document schema control capabilities) to close container on load due to mismatch in
|
|
2563
2558
|
// last message's sequence number.
|
|
2564
2559
|
// See also lastMessageFromMetadata()
|
|
2565
2560
|
message: explicitSchemaControl
|
|
@@ -2960,7 +2955,7 @@ export class ContainerRuntime
|
|
|
2960
2955
|
if ("batchStart" in inboundResult) {
|
|
2961
2956
|
const batchStart: BatchStartInfo = inboundResult.batchStart;
|
|
2962
2957
|
const result = this.duplicateBatchDetector?.processInboundBatch(batchStart);
|
|
2963
|
-
if (result?.duplicate) {
|
|
2958
|
+
if (result?.duplicate === true) {
|
|
2964
2959
|
const error = new DataCorruptionError(
|
|
2965
2960
|
"Duplicate batch - The same batch was sequenced twice",
|
|
2966
2961
|
{ batchId: batchStart.batchId },
|
|
@@ -3430,7 +3425,7 @@ export class ContainerRuntime
|
|
|
3430
3425
|
let checkpoint: IBatchCheckpoint | undefined;
|
|
3431
3426
|
// eslint-disable-next-line import/no-deprecated
|
|
3432
3427
|
let stageControls: StageControlsExperimental | undefined;
|
|
3433
|
-
if (this.mc.config.getBoolean("Fluid.ContainerRuntime.EnableRollback")) {
|
|
3428
|
+
if (this.mc.config.getBoolean("Fluid.ContainerRuntime.EnableRollback") === true) {
|
|
3434
3429
|
if (!this.batchRunner.running && !this.inStagingMode) {
|
|
3435
3430
|
stageControls = this.enterStagingMode();
|
|
3436
3431
|
}
|
|
@@ -3640,7 +3635,7 @@ export class ContainerRuntime
|
|
|
3640
3635
|
private shouldSendOps(): boolean {
|
|
3641
3636
|
// Note that the real (non-proxy) delta manager is needed here to get the readonly info. This is because
|
|
3642
3637
|
// container runtime's ability to send ops depend on the actual readonly state of the delta manager.
|
|
3643
|
-
return this.connected &&
|
|
3638
|
+
return this.connected && this.innerDeltaManager.readOnlyInfo.readonly !== true;
|
|
3644
3639
|
}
|
|
3645
3640
|
|
|
3646
3641
|
private readonly _quorum: IQuorumClients;
|
|
@@ -4299,15 +4294,16 @@ export class ContainerRuntime
|
|
|
4299
4294
|
// Counting dataStores and handles
|
|
4300
4295
|
// Because handles are unchanged dataStores in the current logic,
|
|
4301
4296
|
// summarized dataStore count is total dataStore count minus handle count
|
|
4302
|
-
const dataStoreTree = summaryTree.tree[channelsTreeName];
|
|
4297
|
+
const dataStoreTree: SummaryObject | undefined = summaryTree.tree[channelsTreeName];
|
|
4303
4298
|
|
|
4304
|
-
assert(dataStoreTree
|
|
4299
|
+
assert(dataStoreTree?.type === SummaryType.Tree, 0x1fc /* "summary is not a tree" */);
|
|
4305
4300
|
const handleCount = Object.values(dataStoreTree.tree).filter(
|
|
4306
4301
|
(value) => value.type === SummaryType.Handle,
|
|
4307
4302
|
).length;
|
|
4308
|
-
const gcSummaryTreeStats =
|
|
4309
|
-
|
|
4310
|
-
|
|
4303
|
+
const gcSummaryTreeStats =
|
|
4304
|
+
summaryTree.tree[gcTreeKey] === undefined
|
|
4305
|
+
? undefined
|
|
4306
|
+
: calculateStats(summaryTree.tree[gcTreeKey]);
|
|
4311
4307
|
|
|
4312
4308
|
const summaryStats: IGeneratedSummaryStats = {
|
|
4313
4309
|
dataStoreCount: this.channelCollection.size,
|
|
@@ -4358,7 +4354,7 @@ export class ContainerRuntime
|
|
|
4358
4354
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
4359
4355
|
head: parent!,
|
|
4360
4356
|
message,
|
|
4361
|
-
parents: parent ? [
|
|
4357
|
+
parents: parent === undefined ? [] : [parent],
|
|
4362
4358
|
};
|
|
4363
4359
|
const uploadData = {
|
|
4364
4360
|
...generateSummaryData,
|
|
@@ -4444,7 +4440,7 @@ export class ContainerRuntime
|
|
|
4444
4440
|
// the summarizer.
|
|
4445
4441
|
if (
|
|
4446
4442
|
finalAttempt &&
|
|
4447
|
-
this.mc.config.getBoolean("Fluid.Summarizer.SkipFailingIncorrectSummary")
|
|
4443
|
+
this.mc.config.getBoolean("Fluid.Summarizer.SkipFailingIncorrectSummary") === true
|
|
4448
4444
|
) {
|
|
4449
4445
|
const error = DataProcessingError.create(
|
|
4450
4446
|
"Pending ops during summarization",
|
|
@@ -4599,7 +4595,7 @@ export class ContainerRuntime
|
|
|
4599
4595
|
|
|
4600
4596
|
// Note that the real (non-proxy) delta manager is used here to get the readonly info. This is because
|
|
4601
4597
|
// container runtime's ability to submit ops depend on the actual readonly state of the delta manager.
|
|
4602
|
-
if (this.innerDeltaManager.readOnlyInfo.readonly) {
|
|
4598
|
+
if (this.innerDeltaManager.readOnlyInfo.readonly === true) {
|
|
4603
4599
|
this.mc.logger.sendTelemetryEvent({
|
|
4604
4600
|
eventName: "SubmitOpInReadonly",
|
|
4605
4601
|
connected: this.connected,
|
|
@@ -5031,10 +5027,7 @@ export class ContainerRuntime
|
|
|
5031
5027
|
scenarioName,
|
|
5032
5028
|
FetchSource.noCache,
|
|
5033
5029
|
);
|
|
5034
|
-
assert(
|
|
5035
|
-
!!versions && !!versions[0],
|
|
5036
|
-
0x137 /* "Failed to get version from storage" */,
|
|
5037
|
-
);
|
|
5030
|
+
assert(versions[0] !== undefined, 0x137 /* "Failed to get version from storage" */);
|
|
5038
5031
|
snapshotTree = await this.storage.getSnapshotTree(versions[0]);
|
|
5039
5032
|
assert(!!snapshotTree, 0x138 /* "Failed to get snapshot from storage" */);
|
|
5040
5033
|
props.snapshotVersion = versions[0].id;
|
|
@@ -5070,7 +5063,7 @@ export class ContainerRuntime
|
|
|
5070
5063
|
}
|
|
5071
5064
|
|
|
5072
5065
|
this.verifyNotClosed();
|
|
5073
|
-
if (props?.notifyImminentClosure) {
|
|
5066
|
+
if (props?.notifyImminentClosure === true) {
|
|
5074
5067
|
throw new UsageError("notifyImminentClosure is no longer supported in ContainerRuntime");
|
|
5075
5068
|
}
|
|
5076
5069
|
|
package/src/dataStoreContext.ts
CHANGED
|
@@ -282,7 +282,7 @@ export abstract class FluidDataStoreContext
|
|
|
282
282
|
|
|
283
283
|
private isStagingMode: boolean = false;
|
|
284
284
|
public isReadOnly = (): boolean =>
|
|
285
|
-
(this.isStagingMode && this.channel?.policies?.readonlyInStagingMode
|
|
285
|
+
(this.isStagingMode && this.channel?.policies?.readonlyInStagingMode === true) ||
|
|
286
286
|
this.parentContext.isReadOnly();
|
|
287
287
|
|
|
288
288
|
public get connected(): boolean {
|
|
@@ -1231,7 +1231,7 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
|
|
|
1231
1231
|
private snapshotFetchRequired: boolean | undefined;
|
|
1232
1232
|
private readonly runtime: IContainerRuntimeBase;
|
|
1233
1233
|
private readonly blobContents: Map<string, ArrayBuffer> | undefined;
|
|
1234
|
-
private readonly isSnapshotInISnapshotFormat: boolean
|
|
1234
|
+
private readonly isSnapshotInISnapshotFormat: boolean;
|
|
1235
1235
|
|
|
1236
1236
|
constructor(props: IRemoteFluidDataStoreContextProps) {
|
|
1237
1237
|
super(props, true /* existing */, false /* isLocalDataStore */, () => {
|
|
@@ -1290,7 +1290,7 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
|
|
|
1290
1290
|
this.blobContents,
|
|
1291
1291
|
);
|
|
1292
1292
|
}
|
|
1293
|
-
if (this.snapshotFetchRequired) {
|
|
1293
|
+
if (this.snapshotFetchRequired === true) {
|
|
1294
1294
|
assert(
|
|
1295
1295
|
this.loadingGroupId !== undefined,
|
|
1296
1296
|
0x8f5 /* groupId should be present to fetch snapshot */,
|
package/src/deltaScheduler.ts
CHANGED
|
@@ -69,7 +69,7 @@ export class DeltaScheduler {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
private readonly batchBegin = (message: ISequencedDocumentMessage): void => {
|
|
72
|
-
if (
|
|
72
|
+
if (this.processingStartTime === undefined) {
|
|
73
73
|
this.processingStartTime = performanceNow();
|
|
74
74
|
}
|
|
75
75
|
if (this.schedulingLog === undefined && this.schedulingCount % 500 === 0) {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import type { IRequest } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { assert, LazyPromise, Timer } from "@fluidframework/core-utils/internal";
|
|
8
|
+
import type { ISnapshotTree } from "@fluidframework/driver-definitions/internal";
|
|
8
9
|
import {
|
|
9
10
|
type IGarbageCollectionDetailsBase,
|
|
10
11
|
type ISummarizeResult,
|
|
@@ -190,7 +191,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
190
191
|
);
|
|
191
192
|
let timeoutMs = this.configs.sessionExpiryTimeoutMs;
|
|
192
193
|
|
|
193
|
-
if (pendingSessionExpiryTimerStarted) {
|
|
194
|
+
if (pendingSessionExpiryTimerStarted !== undefined) {
|
|
194
195
|
// NOTE: This assumes the client clock hasn't been tampered with since the original session
|
|
195
196
|
const timeLapsedSincePendingTimer = Date.now() - pendingSessionExpiryTimerStarted;
|
|
196
197
|
timeoutMs -= timeLapsedSincePendingTimer;
|
|
@@ -232,7 +233,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
232
233
|
|
|
233
234
|
try {
|
|
234
235
|
// For newer documents, GC data should be present in the GC tree in the root of the snapshot.
|
|
235
|
-
const gcSnapshotTree = baseSnapshot.trees[gcTreeKey];
|
|
236
|
+
const gcSnapshotTree: ISnapshotTree | undefined = baseSnapshot.trees[gcTreeKey];
|
|
236
237
|
if (gcSnapshotTree === undefined) {
|
|
237
238
|
// back-compat - Older documents get their gc data reset for simplicity as there are few of them
|
|
238
239
|
// incremental gc summary will not work with older gc data as well
|
|
@@ -845,6 +846,8 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
845
846
|
if (gcDataSuperSet.gcNodes[sourceNodeId] === undefined) {
|
|
846
847
|
gcDataSuperSet.gcNodes[sourceNodeId] = outboundRoutes;
|
|
847
848
|
} else {
|
|
849
|
+
// TODO: Fix this violation and remove the disable
|
|
850
|
+
// eslint-disable-next-line @fluid-internal/fluid/no-unchecked-record-access
|
|
848
851
|
gcDataSuperSet.gcNodes[sourceNodeId].push(...outboundRoutes);
|
|
849
852
|
}
|
|
850
853
|
newOutboundRoutesSinceLastRun.push(...outboundRoutes);
|
package/src/gc/gcConfigs.ts
CHANGED
|
@@ -178,7 +178,7 @@ export function computeTombstoneTimeout(
|
|
|
178
178
|
sessionExpiryTimeoutMs: number | undefined,
|
|
179
179
|
): number | undefined {
|
|
180
180
|
const bufferMs = oneDayMs;
|
|
181
|
-
return
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
return sessionExpiryTimeoutMs === undefined
|
|
182
|
+
? undefined
|
|
183
|
+
: sessionExpiryTimeoutMs + maxSnapshotCacheExpiryMs + bufferMs;
|
|
184
184
|
}
|
|
@@ -31,7 +31,7 @@ export function runGarbageCollection(
|
|
|
31
31
|
|
|
32
32
|
// Get the node for the referenced id and add its outbound routes to referencedIds since they are
|
|
33
33
|
// also referenced.
|
|
34
|
-
const routes = referenceGraph[id];
|
|
34
|
+
const routes: string[] | undefined = referenceGraph[id];
|
|
35
35
|
if (routes !== undefined) {
|
|
36
36
|
referencedIds.push(...routes);
|
|
37
37
|
}
|
package/src/gc/gcTelemetry.ts
CHANGED
|
@@ -210,10 +210,9 @@ export class GCTelemetryTracker {
|
|
|
210
210
|
return this.configs.tombstoneTimeoutMs;
|
|
211
211
|
}
|
|
212
212
|
case UnreferencedState.SweepReady: {
|
|
213
|
-
return
|
|
214
|
-
|
|
215
|
-
this.configs.tombstoneTimeoutMs + this.configs.sweepGracePeriodMs
|
|
216
|
-
);
|
|
213
|
+
return this.configs.tombstoneTimeoutMs === undefined
|
|
214
|
+
? undefined
|
|
215
|
+
: this.configs.tombstoneTimeoutMs + this.configs.sweepGracePeriodMs;
|
|
217
216
|
}
|
|
218
217
|
default: {
|
|
219
218
|
return undefined;
|
|
@@ -327,7 +326,7 @@ export class GCTelemetryTracker {
|
|
|
327
326
|
if (
|
|
328
327
|
usageType === "Loaded" &&
|
|
329
328
|
this.configs.throwOnTombstoneLoad &&
|
|
330
|
-
|
|
329
|
+
headers?.allowTombstone !== true
|
|
331
330
|
) {
|
|
332
331
|
this.mc.logger.sendErrorEvent(event);
|
|
333
332
|
} else {
|
|
@@ -190,7 +190,7 @@ export class InboundBatchAggregator {
|
|
|
190
190
|
// - here, when queue was empty and start of batch showed up (batchMetadata === true below).
|
|
191
191
|
// 2. resumed when batch end comes in (batchMetadata === false below)
|
|
192
192
|
|
|
193
|
-
if (batchMetadata) {
|
|
193
|
+
if (batchMetadata === true) {
|
|
194
194
|
assert(
|
|
195
195
|
this.currentBatchClientId === undefined,
|
|
196
196
|
0x29e /* "there can't be active batch" */,
|
package/src/metadata.ts
CHANGED
|
@@ -52,7 +52,8 @@ export interface IBlobMetadata {
|
|
|
52
52
|
|
|
53
53
|
export const isBlobMetadata = (metadata: unknown): metadata is IBlobMetadata => {
|
|
54
54
|
return (
|
|
55
|
-
|
|
55
|
+
typeof metadata === "object" &&
|
|
56
|
+
metadata !== null &&
|
|
56
57
|
typeof (metadata as IBlobMetadata).blobId === "string" &&
|
|
57
58
|
typeof (metadata as IBlobMetadata).localId === "string"
|
|
58
59
|
);
|
|
@@ -134,9 +134,9 @@ export class OpGroupingManager {
|
|
|
134
134
|
// We expect this will be on the first message, if present at all.
|
|
135
135
|
let groupedBatchId;
|
|
136
136
|
for (const message of batch.messages) {
|
|
137
|
-
if (message.metadata) {
|
|
137
|
+
if (message.metadata !== undefined) {
|
|
138
138
|
const { batch: _batch, batchId, ...rest } = message.metadata;
|
|
139
|
-
if (batchId) {
|
|
139
|
+
if (batchId !== undefined) {
|
|
140
140
|
groupedBatchId = batchId;
|
|
141
141
|
}
|
|
142
142
|
assert(Object.keys(rest).length === 0, 0x5dd /* cannot group ops with metadata */);
|
package/src/packageVersion.ts
CHANGED