@fluidframework/container-runtime 2.0.0-dev-rc.4.0.0.261659 → 2.0.0-dev-rc.5.0.0.263932
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/api-report/container-runtime.api.md +62 -22
- package/dist/blobManager.d.ts +7 -7
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +2 -4
- package/dist/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +6 -4
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +19 -8
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +5 -8
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +65 -38
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +9 -6
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +18 -5
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/{deltaManagerSummarizerProxy.d.ts → deltaManagerProxies.d.ts} +28 -3
- package/dist/deltaManagerProxies.d.ts.map +1 -0
- package/dist/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +38 -2
- package/dist/deltaManagerProxies.js.map +1 -0
- package/dist/deltaScheduler.d.ts +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +5 -0
- package/dist/messageTypes.d.ts +5 -2
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +4 -0
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +5 -4
- package/dist/opLifecycle/outbox.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 +6 -0
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +10 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/documentSchema.js +1 -1
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/index.d.ts +1 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -1
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.js +10 -10
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +1 -2
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +1 -1
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +25 -5
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.js +11 -11
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.js +5 -5
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/blobManager.d.ts +7 -7
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +3 -5
- package/lib/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +6 -4
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +20 -9
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +5 -8
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +65 -38
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +9 -6
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +20 -7
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/{deltaManagerSummarizerProxy.d.ts → deltaManagerProxies.d.ts} +28 -3
- package/lib/deltaManagerProxies.d.ts.map +1 -0
- package/lib/{deltaManagerSummarizerProxy.js → deltaManagerProxies.js} +36 -1
- package/lib/deltaManagerProxies.js.map +1 -0
- package/lib/deltaScheduler.d.ts +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +5 -0
- package/lib/messageTypes.d.ts +5 -2
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +4 -0
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +5 -4
- package/lib/opLifecycle/outbox.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 +6 -0
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +10 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/documentSchema.js +1 -1
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/index.d.ts +1 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -1
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.js +1 -1
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +1 -2
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +1 -1
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +25 -5
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.js +1 -1
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.js +1 -1
- package/lib/summary/summaryManager.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +25 -23
- package/src/blobManager.ts +11 -10
- package/src/channelCollection.ts +29 -13
- package/src/connectionTelemetry.ts +1 -1
- package/src/containerRuntime.ts +93 -53
- package/src/dataStore.ts +2 -2
- package/src/dataStoreContext.ts +56 -16
- package/src/{deltaManagerSummarizerProxy.ts → deltaManagerProxies.ts} +55 -3
- package/src/deltaScheduler.ts +1 -1
- package/src/index.ts +5 -0
- package/src/messageTypes.ts +4 -2
- package/src/opLifecycle/batchManager.ts +5 -0
- package/src/opLifecycle/outbox.ts +5 -4
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +11 -1
- package/src/scheduleManager.ts +1 -1
- package/src/summary/documentSchema.ts +1 -1
- package/src/summary/index.ts +4 -0
- package/src/summary/orderedClientElection.ts +1 -1
- package/src/summary/runningSummarizer.ts +1 -1
- package/src/summary/summarizerTypes.ts +1 -2
- package/src/summary/summaryCollection.ts +1 -1
- package/src/summary/summaryFormat.ts +30 -4
- package/src/summary/summaryGenerator.ts +1 -1
- package/src/summary/summaryManager.ts +1 -1
- package/dist/deltaManagerSummarizerProxy.d.ts.map +0 -1
- package/dist/deltaManagerSummarizerProxy.js.map +0 -1
- package/lib/deltaManagerSummarizerProxy.d.ts.map +0 -1
- package/lib/deltaManagerSummarizerProxy.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-runtime",
|
|
3
|
-
"version": "2.0.0-dev-rc.
|
|
3
|
+
"version": "2.0.0-dev-rc.5.0.0.263932",
|
|
4
4
|
"description": "Fluid container runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -127,19 +127,19 @@
|
|
|
127
127
|
"temp-directory": "nyc/.nyc_output"
|
|
128
128
|
},
|
|
129
129
|
"dependencies": {
|
|
130
|
-
"@fluid-internal/client-utils": "2.0.0-dev-rc.
|
|
131
|
-
"@fluidframework/container-definitions": "2.0.0-dev-rc.
|
|
132
|
-
"@fluidframework/container-runtime-definitions": "2.0.0-dev-rc.
|
|
133
|
-
"@fluidframework/core-interfaces": "2.0.0-dev-rc.
|
|
134
|
-
"@fluidframework/core-utils": "2.0.0-dev-rc.
|
|
135
|
-
"@fluidframework/datastore": "2.0.0-dev-rc.
|
|
136
|
-
"@fluidframework/driver-definitions": "2.0.0-dev-rc.
|
|
137
|
-
"@fluidframework/driver-utils": "2.0.0-dev-rc.
|
|
138
|
-
"@fluidframework/id-compressor": "2.0.0-dev-rc.
|
|
130
|
+
"@fluid-internal/client-utils": "2.0.0-dev-rc.5.0.0.263932",
|
|
131
|
+
"@fluidframework/container-definitions": "2.0.0-dev-rc.5.0.0.263932",
|
|
132
|
+
"@fluidframework/container-runtime-definitions": "2.0.0-dev-rc.5.0.0.263932",
|
|
133
|
+
"@fluidframework/core-interfaces": "2.0.0-dev-rc.5.0.0.263932",
|
|
134
|
+
"@fluidframework/core-utils": "2.0.0-dev-rc.5.0.0.263932",
|
|
135
|
+
"@fluidframework/datastore": "2.0.0-dev-rc.5.0.0.263932",
|
|
136
|
+
"@fluidframework/driver-definitions": "2.0.0-dev-rc.5.0.0.263932",
|
|
137
|
+
"@fluidframework/driver-utils": "2.0.0-dev-rc.5.0.0.263932",
|
|
138
|
+
"@fluidframework/id-compressor": "2.0.0-dev-rc.5.0.0.263932",
|
|
139
139
|
"@fluidframework/protocol-definitions": "^3.2.0",
|
|
140
|
-
"@fluidframework/runtime-definitions": "2.0.0-dev-rc.
|
|
141
|
-
"@fluidframework/runtime-utils": "2.0.0-dev-rc.
|
|
142
|
-
"@fluidframework/telemetry-utils": "2.0.0-dev-rc.
|
|
140
|
+
"@fluidframework/runtime-definitions": "2.0.0-dev-rc.5.0.0.263932",
|
|
141
|
+
"@fluidframework/runtime-utils": "2.0.0-dev-rc.5.0.0.263932",
|
|
142
|
+
"@fluidframework/telemetry-utils": "2.0.0-dev-rc.5.0.0.263932",
|
|
143
143
|
"@tylerbu/sorted-btree-es6": "^1.8.0",
|
|
144
144
|
"double-ended-queue": "^2.1.0-0",
|
|
145
145
|
"lz4js": "^0.2.0",
|
|
@@ -148,17 +148,17 @@
|
|
|
148
148
|
"devDependencies": {
|
|
149
149
|
"@arethetypeswrong/cli": "^0.15.2",
|
|
150
150
|
"@biomejs/biome": "^1.6.2",
|
|
151
|
-
"@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.
|
|
152
|
-
"@fluid-private/stochastic-test-utils": "2.0.0-dev-rc.
|
|
153
|
-
"@fluid-private/test-pairwise-generator": "2.0.0-dev-rc.
|
|
151
|
+
"@fluid-internal/mocha-test-setup": "2.0.0-dev-rc.5.0.0.263932",
|
|
152
|
+
"@fluid-private/stochastic-test-utils": "2.0.0-dev-rc.5.0.0.263932",
|
|
153
|
+
"@fluid-private/test-pairwise-generator": "2.0.0-dev-rc.5.0.0.263932",
|
|
154
154
|
"@fluid-tools/benchmark": "^0.48.0",
|
|
155
|
-
"@fluid-tools/build-cli": "0.38.0
|
|
155
|
+
"@fluid-tools/build-cli": "^0.38.0",
|
|
156
156
|
"@fluidframework/build-common": "^2.0.3",
|
|
157
|
-
"@fluidframework/build-tools": "0.38.0
|
|
157
|
+
"@fluidframework/build-tools": "^0.38.0",
|
|
158
158
|
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-rc.3.0.0",
|
|
159
159
|
"@fluidframework/eslint-config-fluid": "^5.1.0",
|
|
160
|
-
"@fluidframework/test-runtime-utils": "2.0.0-dev-rc.
|
|
161
|
-
"@microsoft/api-extractor": "^7.
|
|
160
|
+
"@fluidframework/test-runtime-utils": "2.0.0-dev-rc.5.0.0.263932",
|
|
161
|
+
"@microsoft/api-extractor": "^7.43.1",
|
|
162
162
|
"@types/double-ended-queue": "^2.1.0",
|
|
163
163
|
"@types/mocha": "^9.1.1",
|
|
164
164
|
"@types/node": "^18.19.0",
|
|
@@ -180,7 +180,8 @@
|
|
|
180
180
|
"typeValidation": {
|
|
181
181
|
"broken": {
|
|
182
182
|
"ClassDeclaration_ChannelCollection": {
|
|
183
|
-
"backCompat": false
|
|
183
|
+
"backCompat": false,
|
|
184
|
+
"forwardCompat": false
|
|
184
185
|
},
|
|
185
186
|
"ClassDeclaration_ContainerRuntime": {
|
|
186
187
|
"backCompat": false,
|
|
@@ -215,6 +216,7 @@
|
|
|
215
216
|
"format:prettier": "prettier --write . --cache --ignore-path ../../../.prettierignore",
|
|
216
217
|
"lint": "fluid-build . --task lint",
|
|
217
218
|
"lint:fix": "fluid-build . --task eslint:fix --task format",
|
|
219
|
+
"place:cjs:package-stub": "copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
|
|
218
220
|
"test": "npm run test:mocha",
|
|
219
221
|
"test:benchmark:report": "mocha --timeout 999999 --perfMode --parentProcess --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js \"./dist/**/*.perf.spec.*js\"",
|
|
220
222
|
"test:coverage": "c8 npm test",
|
|
@@ -222,8 +224,8 @@
|
|
|
222
224
|
"test:mocha:cjs": "mocha --recursive \"dist/test/**/*.spec.*js\" --exit",
|
|
223
225
|
"test:mocha:esm": "mocha --recursive \"lib/test/**/*.spec.*js\" --exit",
|
|
224
226
|
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
225
|
-
"tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json &&
|
|
226
|
-
"tsc:watch": "tsc --watch",
|
|
227
|
+
"tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && npm run place:cjs:package-stub",
|
|
228
|
+
"tsc:watch": "npm run place:cjs:package-stub && fluid-tsc commonjs --project ./tsconfig.cjs.json --watch",
|
|
227
229
|
"typetests:gen": "flub generate typetests --dir . -v --publicFallback",
|
|
228
230
|
"typetests:prepare": "flub typetests --dir . --reset --previous --normalize"
|
|
229
231
|
}
|
package/src/blobManager.ts
CHANGED
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
IContainerRuntime,
|
|
10
10
|
IContainerRuntimeEvents,
|
|
11
11
|
} from "@fluidframework/container-runtime-definitions/internal";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
IFluidHandleContext,
|
|
14
|
+
type IFluidHandleInternal,
|
|
15
|
+
} from "@fluidframework/core-interfaces/internal";
|
|
13
16
|
import { assert, Deferred } from "@fluidframework/core-utils/internal";
|
|
14
17
|
import { IDocumentStorageService } from "@fluidframework/driver-definitions/internal";
|
|
15
18
|
import { canRetryOnError, runWithRetry } from "@fluidframework/driver-utils/internal";
|
|
@@ -24,6 +27,7 @@ import {
|
|
|
24
27
|
ITelemetryContext,
|
|
25
28
|
} from "@fluidframework/runtime-definitions";
|
|
26
29
|
import {
|
|
30
|
+
FluidHandleBase,
|
|
27
31
|
SummaryTreeBuilder,
|
|
28
32
|
createResponseError,
|
|
29
33
|
generateHandleContextPath,
|
|
@@ -48,13 +52,9 @@ import { IBlobMetadata } from "./metadata.js";
|
|
|
48
52
|
* DataObject.request() recognizes requests in the form of `/blobs/<id>`
|
|
49
53
|
* and loads blob.
|
|
50
54
|
*/
|
|
51
|
-
export class BlobHandle
|
|
55
|
+
export class BlobHandle extends FluidHandleBase<ArrayBufferLike> {
|
|
52
56
|
private attached: boolean = false;
|
|
53
57
|
|
|
54
|
-
public get IFluidHandle(): IFluidHandle {
|
|
55
|
-
return this;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
58
|
public get isAttached(): boolean {
|
|
59
59
|
return this.routeContext.isAttached && this.attached;
|
|
60
60
|
}
|
|
@@ -64,9 +64,10 @@ export class BlobHandle implements IFluidHandle<ArrayBufferLike> {
|
|
|
64
64
|
constructor(
|
|
65
65
|
public readonly path: string,
|
|
66
66
|
public readonly routeContext: IFluidHandleContext,
|
|
67
|
-
public get: () => Promise<
|
|
67
|
+
public get: () => Promise<ArrayBufferLike>,
|
|
68
68
|
private readonly onAttachGraph?: () => void,
|
|
69
69
|
) {
|
|
70
|
+
super();
|
|
70
71
|
this.absolutePath = generateHandleContextPath(path, this.routeContext);
|
|
71
72
|
}
|
|
72
73
|
|
|
@@ -77,7 +78,7 @@ export class BlobHandle implements IFluidHandle<ArrayBufferLike> {
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
public bind(handle:
|
|
81
|
+
public bind(handle: IFluidHandleInternal) {
|
|
81
82
|
throw new Error("Cannot bind to blob handle");
|
|
82
83
|
}
|
|
83
84
|
}
|
|
@@ -433,7 +434,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
433
434
|
|
|
434
435
|
private async createBlobDetached(
|
|
435
436
|
blob: ArrayBufferLike,
|
|
436
|
-
): Promise<
|
|
437
|
+
): Promise<IFluidHandleInternal<ArrayBufferLike>> {
|
|
437
438
|
// Blobs created while the container is detached are stored in IDetachedBlobStorage.
|
|
438
439
|
// The 'IDocumentStorageService.createBlob()' call below will respond with a localId.
|
|
439
440
|
const response = await this.getStorage().createBlob(blob);
|
|
@@ -444,7 +445,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
444
445
|
public async createBlob(
|
|
445
446
|
blob: ArrayBufferLike,
|
|
446
447
|
signal?: AbortSignal,
|
|
447
|
-
): Promise<
|
|
448
|
+
): Promise<IFluidHandleInternal<ArrayBufferLike>> {
|
|
448
449
|
if (this.runtime.attachState === AttachState.Detached) {
|
|
449
450
|
return this.createBlobDetached(blob);
|
|
450
451
|
}
|
package/src/channelCollection.ts
CHANGED
|
@@ -7,14 +7,19 @@ import { AttachState } from "@fluidframework/container-definitions";
|
|
|
7
7
|
import {
|
|
8
8
|
FluidObject,
|
|
9
9
|
IDisposable,
|
|
10
|
-
IFluidHandle,
|
|
11
10
|
IRequest,
|
|
12
11
|
IResponse,
|
|
13
12
|
ITelemetryBaseLogger,
|
|
14
13
|
} from "@fluidframework/core-interfaces";
|
|
14
|
+
import type { IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
|
|
15
15
|
import { assert, Lazy, LazyPromise } from "@fluidframework/core-utils/internal";
|
|
16
16
|
import { FluidObjectHandle } from "@fluidframework/datastore/internal";
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
buildSnapshotTree,
|
|
19
|
+
getSnapshotTree,
|
|
20
|
+
isInstanceOfISnapshot,
|
|
21
|
+
} from "@fluidframework/driver-utils/internal";
|
|
22
|
+
import type { ISnapshot } from "@fluidframework/driver-definitions/internal";
|
|
18
23
|
import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
19
24
|
import {
|
|
20
25
|
IGarbageCollectionData,
|
|
@@ -255,7 +260,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
255
260
|
|
|
256
261
|
private readonly disposeOnce = new Lazy<void>(() => this.contexts.dispose());
|
|
257
262
|
|
|
258
|
-
public readonly entryPoint:
|
|
263
|
+
public readonly entryPoint: IFluidHandleInternal<FluidObject>;
|
|
259
264
|
|
|
260
265
|
public readonly containerLoadStats: {
|
|
261
266
|
// number of dataStores during loadContainer
|
|
@@ -269,7 +274,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
269
274
|
private dataStoresSinceLastGC: string[] = [];
|
|
270
275
|
// The handle to the container runtime. This is used mainly for GC purposes to represent outbound reference from
|
|
271
276
|
// the container runtime to other nodes.
|
|
272
|
-
private readonly containerRuntimeHandle:
|
|
277
|
+
private readonly containerRuntimeHandle: IFluidHandleInternal;
|
|
273
278
|
private readonly pendingAliasMap: Map<string, Promise<AliasResult>> = new Map<
|
|
274
279
|
string,
|
|
275
280
|
Promise<AliasResult>
|
|
@@ -279,7 +284,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
279
284
|
private readonly aliasedDataStores: Set<string>;
|
|
280
285
|
|
|
281
286
|
constructor(
|
|
282
|
-
protected readonly baseSnapshot: ISnapshotTree | undefined,
|
|
287
|
+
protected readonly baseSnapshot: ISnapshotTree | ISnapshot | undefined,
|
|
283
288
|
public readonly parentContext: IFluidParentContext,
|
|
284
289
|
baseLogger: ITelemetryBaseLogger,
|
|
285
290
|
private readonly gcNodeUpdated: (props: IGCNodeUpdatedProps) => void,
|
|
@@ -304,7 +309,8 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
304
309
|
// Extract stores stored inside the snapshot
|
|
305
310
|
const fluidDataStores = new Map<string, ISnapshotTree>();
|
|
306
311
|
if (baseSnapshot) {
|
|
307
|
-
|
|
312
|
+
const baseSnapshotTree = getSnapshotTree(baseSnapshot);
|
|
313
|
+
for (const [key, value] of Object.entries(baseSnapshotTree.trees)) {
|
|
308
314
|
fluidDataStores.set(key, value);
|
|
309
315
|
}
|
|
310
316
|
}
|
|
@@ -320,9 +326,16 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
320
326
|
}
|
|
321
327
|
// If we have a detached container, then create local data store contexts.
|
|
322
328
|
if (this.parentContext.attachState !== AttachState.Detached) {
|
|
329
|
+
let snapshotForRemoteFluidDatastoreContext: ISnapshot | ISnapshotTree = value;
|
|
330
|
+
if (isInstanceOfISnapshot(baseSnapshot)) {
|
|
331
|
+
snapshotForRemoteFluidDatastoreContext = {
|
|
332
|
+
...baseSnapshot,
|
|
333
|
+
snapshotTree: value,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
323
336
|
dataStoreContext = new RemoteFluidDataStoreContext({
|
|
324
337
|
id: key,
|
|
325
|
-
|
|
338
|
+
snapshot: snapshotForRemoteFluidDatastoreContext,
|
|
326
339
|
parentContext: this.wrapContextForInnerChannel(key),
|
|
327
340
|
storage: this.parentContext.storage,
|
|
328
341
|
scope: this.parentContext.scope,
|
|
@@ -443,9 +456,12 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
443
456
|
}
|
|
444
457
|
|
|
445
458
|
const flatAttachBlobs = new Map<string, ArrayBufferLike>();
|
|
446
|
-
let
|
|
459
|
+
let snapshot: ISnapshotTree | ISnapshot | undefined;
|
|
447
460
|
if (attachMessage.snapshot) {
|
|
448
|
-
|
|
461
|
+
snapshot = buildSnapshotTree(attachMessage.snapshot.entries, flatAttachBlobs);
|
|
462
|
+
if (isInstanceOfISnapshot(this.baseSnapshot)) {
|
|
463
|
+
snapshot = { ...this.baseSnapshot, snapshotTree: snapshot };
|
|
464
|
+
}
|
|
449
465
|
}
|
|
450
466
|
|
|
451
467
|
// Include the type of attach message which is the pkg of the store to be
|
|
@@ -453,7 +469,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
453
469
|
const pkg = [attachMessage.type];
|
|
454
470
|
const remoteFluidDataStoreContext = new RemoteFluidDataStoreContext({
|
|
455
471
|
id: attachMessage.id,
|
|
456
|
-
|
|
472
|
+
snapshot,
|
|
457
473
|
parentContext: this.wrapContextForInnerChannel(attachMessage.id),
|
|
458
474
|
storage: new StorageServiceWithAttachBlobs(this.parentContext.storage, flatAttachBlobs),
|
|
459
475
|
scope: this.parentContext.scope,
|
|
@@ -563,8 +579,8 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
563
579
|
* If the container is detached, this data store will be part of the summary that makes the container attached.
|
|
564
580
|
*/
|
|
565
581
|
if (this.parentContext.attachState !== AttachState.Detached) {
|
|
566
|
-
localContext.setAttachState(AttachState.Attaching);
|
|
567
582
|
this.submitAttachChannelOp(localContext);
|
|
583
|
+
localContext.setAttachState(AttachState.Attaching);
|
|
568
584
|
}
|
|
569
585
|
|
|
570
586
|
this.contexts.bind(id);
|
|
@@ -644,7 +660,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
644
660
|
createProps?: any,
|
|
645
661
|
loadingGroupId?: string,
|
|
646
662
|
) {
|
|
647
|
-
assert(loadingGroupId !== "",
|
|
663
|
+
assert(loadingGroupId !== "", 0x974 /* loadingGroupId should not be the empty string */);
|
|
648
664
|
const context = new contextCtor({
|
|
649
665
|
id,
|
|
650
666
|
pkg,
|
|
@@ -1154,7 +1170,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
1154
1170
|
0x166 /* "BaseSnapshot should be there as detached container loaded from snapshot" */,
|
|
1155
1171
|
);
|
|
1156
1172
|
dataStoreSummary = convertSnapshotTreeToSummaryTree(
|
|
1157
|
-
this.baseSnapshot.trees[key],
|
|
1173
|
+
getSnapshotTree(this.baseSnapshot).trees[key],
|
|
1158
1174
|
);
|
|
1159
1175
|
}
|
|
1160
1176
|
builder.addWithStats(key, dataStoreSummary);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { performance } from "@fluid-internal/client-utils";
|
|
7
|
-
import { IDeltaManager } from "@fluidframework/container-definitions";
|
|
7
|
+
import { IDeltaManager } from "@fluidframework/container-definitions/internal";
|
|
8
8
|
import { IContainerRuntimeEvents } from "@fluidframework/container-runtime-definitions/internal";
|
|
9
9
|
import { IEventProvider } from "@fluidframework/core-interfaces";
|
|
10
10
|
import { assert } from "@fluidframework/core-utils/internal";
|
package/src/containerRuntime.ts
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
IAudience,
|
|
10
10
|
ISelf,
|
|
11
11
|
ICriticalContainerError,
|
|
12
|
-
IDeltaManager,
|
|
13
12
|
} from "@fluidframework/container-definitions";
|
|
14
13
|
import {
|
|
15
14
|
IBatchMessage,
|
|
@@ -19,6 +18,7 @@ import {
|
|
|
19
18
|
IRuntime,
|
|
20
19
|
LoaderHeader,
|
|
21
20
|
type IAudienceEvents,
|
|
21
|
+
IDeltaManager,
|
|
22
22
|
} from "@fluidframework/container-definitions/internal";
|
|
23
23
|
import {
|
|
24
24
|
IContainerRuntime,
|
|
@@ -28,11 +28,12 @@ import {
|
|
|
28
28
|
FluidObject,
|
|
29
29
|
IFluidHandle,
|
|
30
30
|
IFluidHandleContext,
|
|
31
|
+
type IFluidHandleInternal,
|
|
31
32
|
IProvideFluidHandleContext,
|
|
32
33
|
IRequest,
|
|
33
34
|
IResponse,
|
|
34
35
|
ITelemetryBaseLogger,
|
|
35
|
-
} from "@fluidframework/core-interfaces";
|
|
36
|
+
} from "@fluidframework/core-interfaces/internal";
|
|
36
37
|
import { ISignalEnvelope } from "@fluidframework/core-interfaces/internal";
|
|
37
38
|
import {
|
|
38
39
|
assert,
|
|
@@ -130,7 +131,7 @@ import { IPerfSignalReport, ReportOpPerfTelemetry } from "./connectionTelemetry.
|
|
|
130
131
|
import { ContainerFluidHandleContext } from "./containerHandleContext.js";
|
|
131
132
|
import { channelToDataStore } from "./dataStore.js";
|
|
132
133
|
import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
133
|
-
import { DeltaManagerSummarizerProxy } from "./
|
|
134
|
+
import { DeltaManagerPendingOpsProxy, DeltaManagerSummarizerProxy } from "./deltaManagerProxies.js";
|
|
134
135
|
import {
|
|
135
136
|
GCNodeType,
|
|
136
137
|
GarbageCollector,
|
|
@@ -465,10 +466,7 @@ export interface IContainerRuntimeOptions {
|
|
|
465
466
|
* message to be sent to the service.
|
|
466
467
|
* The grouping an ungrouping of such messages is handled by the "OpGroupingManager".
|
|
467
468
|
*
|
|
468
|
-
* By default, the feature is
|
|
469
|
-
* flag can be used to disable it at runtime.
|
|
470
|
-
*
|
|
471
|
-
* @experimental Not ready for use.
|
|
469
|
+
* By default, the feature is enabled.
|
|
472
470
|
*/
|
|
473
471
|
readonly enableGroupedBatching?: boolean;
|
|
474
472
|
|
|
@@ -801,7 +799,7 @@ export class ContainerRuntime
|
|
|
801
799
|
maxBatchSizeInBytes = defaultMaxBatchSizeInBytes,
|
|
802
800
|
enableRuntimeIdCompressor,
|
|
803
801
|
chunkSizeInBytes = defaultChunkSizeInBytes,
|
|
804
|
-
enableGroupedBatching =
|
|
802
|
+
enableGroupedBatching = true,
|
|
805
803
|
explicitSchemaControl = false,
|
|
806
804
|
} = runtimeOptions;
|
|
807
805
|
|
|
@@ -962,9 +960,6 @@ export class ContainerRuntime
|
|
|
962
960
|
}
|
|
963
961
|
};
|
|
964
962
|
|
|
965
|
-
const disableGroupedBatching = mc.config.getBoolean(
|
|
966
|
-
"Fluid.ContainerRuntime.DisableGroupedBatching",
|
|
967
|
-
);
|
|
968
963
|
const disableCompression = mc.config.getBoolean(
|
|
969
964
|
"Fluid.ContainerRuntime.CompressionDisabled",
|
|
970
965
|
);
|
|
@@ -973,8 +968,6 @@ export class ContainerRuntime
|
|
|
973
968
|
compressionOptions.minimumBatchSizeInBytes !== Infinity &&
|
|
974
969
|
compressionOptions.compressionAlgorithm === "lz4";
|
|
975
970
|
|
|
976
|
-
const opGroupingEnabled = disableGroupedBatching !== true && enableGroupedBatching;
|
|
977
|
-
|
|
978
971
|
const documentSchemaController = new DocumentsSchemaController(
|
|
979
972
|
existing,
|
|
980
973
|
protocolSequenceNumber,
|
|
@@ -983,7 +976,7 @@ export class ContainerRuntime
|
|
|
983
976
|
explicitSchemaControl,
|
|
984
977
|
compressionLz4,
|
|
985
978
|
idCompressorMode,
|
|
986
|
-
opGroupingEnabled,
|
|
979
|
+
opGroupingEnabled: enableGroupedBatching,
|
|
987
980
|
disallowedVersions: [],
|
|
988
981
|
},
|
|
989
982
|
(schema) => {
|
|
@@ -992,7 +985,6 @@ export class ContainerRuntime
|
|
|
992
985
|
);
|
|
993
986
|
|
|
994
987
|
const featureGatesForTelemetry: Record<string, boolean | number | undefined> = {
|
|
995
|
-
disableGroupedBatching,
|
|
996
988
|
disableCompression,
|
|
997
989
|
};
|
|
998
990
|
|
|
@@ -1394,6 +1386,7 @@ export class ContainerRuntime
|
|
|
1394
1386
|
loader,
|
|
1395
1387
|
pendingLocalState,
|
|
1396
1388
|
supportedFeatures,
|
|
1389
|
+
snapshotWithContents,
|
|
1397
1390
|
} = context;
|
|
1398
1391
|
|
|
1399
1392
|
this.mc = createChildMonitoringContext({
|
|
@@ -1413,7 +1406,6 @@ export class ContainerRuntime
|
|
|
1413
1406
|
};
|
|
1414
1407
|
|
|
1415
1408
|
this.innerDeltaManager = deltaManager;
|
|
1416
|
-
this.deltaManager = new DeltaManagerSummarizerProxy(this.innerDeltaManager);
|
|
1417
1409
|
|
|
1418
1410
|
// Here we could wrap/intercept on these functions to block/modify outgoing messages if needed.
|
|
1419
1411
|
// This makes ContainerRuntime the final gatekeeper for outgoing messages.
|
|
@@ -1518,6 +1510,44 @@ export class ContainerRuntime
|
|
|
1518
1510
|
opGroupingManager,
|
|
1519
1511
|
);
|
|
1520
1512
|
|
|
1513
|
+
const pendingRuntimeState = pendingLocalState as IPendingRuntimeState | undefined;
|
|
1514
|
+
this.pendingStateManager = new PendingStateManager(
|
|
1515
|
+
{
|
|
1516
|
+
applyStashedOp: this.applyStashedOp.bind(this),
|
|
1517
|
+
clientId: () => this.clientId,
|
|
1518
|
+
close: this.closeFn,
|
|
1519
|
+
connected: () => this.connected,
|
|
1520
|
+
reSubmit: (message: IPendingBatchMessage) => {
|
|
1521
|
+
this.reSubmit(message);
|
|
1522
|
+
this.flush();
|
|
1523
|
+
},
|
|
1524
|
+
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
1525
|
+
isActiveConnection: () => this.innerDeltaManager.active,
|
|
1526
|
+
isAttached: () => this.attachState !== AttachState.Detached,
|
|
1527
|
+
},
|
|
1528
|
+
pendingRuntimeState?.pending,
|
|
1529
|
+
this.logger,
|
|
1530
|
+
);
|
|
1531
|
+
|
|
1532
|
+
let outerDeltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
|
|
1533
|
+
const useDeltaManagerOpsProxy =
|
|
1534
|
+
this.mc.config.getBoolean("Fluid.ContainerRuntime.DeltaManagerOpsProxy") !== false;
|
|
1535
|
+
// The summarizerDeltaManager Proxy is used to lie to the summarizer to convince it is in the right state as a summarizer client.
|
|
1536
|
+
const summarizerDeltaManagerProxy = new DeltaManagerSummarizerProxy(this.innerDeltaManager);
|
|
1537
|
+
outerDeltaManager = summarizerDeltaManagerProxy;
|
|
1538
|
+
|
|
1539
|
+
// The DeltaManagerPendingOpsProxy is used to control the minimum sequence number
|
|
1540
|
+
// It allows us to lie to the layers below so that they can maintain enough local state for rebasing ops.
|
|
1541
|
+
if (useDeltaManagerOpsProxy) {
|
|
1542
|
+
const pendingOpsDeltaManagerProxy = new DeltaManagerPendingOpsProxy(
|
|
1543
|
+
summarizerDeltaManagerProxy,
|
|
1544
|
+
this.pendingStateManager,
|
|
1545
|
+
);
|
|
1546
|
+
outerDeltaManager = pendingOpsDeltaManagerProxy;
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
this.deltaManager = outerDeltaManager;
|
|
1550
|
+
|
|
1521
1551
|
this.handleContext = new ContainerFluidHandleContext("", this);
|
|
1522
1552
|
|
|
1523
1553
|
if (this.summaryConfiguration.state === "enabled") {
|
|
@@ -1543,8 +1573,6 @@ export class ContainerRuntime
|
|
|
1543
1573
|
this._flushMode = runtimeOptions.flushMode;
|
|
1544
1574
|
}
|
|
1545
1575
|
|
|
1546
|
-
const pendingRuntimeState = pendingLocalState as IPendingRuntimeState | undefined;
|
|
1547
|
-
|
|
1548
1576
|
if (context.attachState === AttachState.Attached) {
|
|
1549
1577
|
const maxSnapshotCacheDurationMs = this._storage?.policies?.maximumCacheDurationMs;
|
|
1550
1578
|
if (
|
|
@@ -1616,8 +1644,19 @@ export class ContainerRuntime
|
|
|
1616
1644
|
return this.submitSignalFn(envelope2, targetClientId);
|
|
1617
1645
|
};
|
|
1618
1646
|
|
|
1647
|
+
let snapshot: ISnapshot | ISnapshotTree | undefined = getSummaryForDatastores(
|
|
1648
|
+
baseSnapshot,
|
|
1649
|
+
metadata,
|
|
1650
|
+
);
|
|
1651
|
+
if (snapshot !== undefined && snapshotWithContents !== undefined) {
|
|
1652
|
+
snapshot = {
|
|
1653
|
+
...snapshotWithContents,
|
|
1654
|
+
snapshotTree: snapshot,
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1619
1658
|
this.channelCollection = new ChannelCollection(
|
|
1620
|
-
|
|
1659
|
+
snapshot,
|
|
1621
1660
|
parentContext,
|
|
1622
1661
|
this.mc.logger,
|
|
1623
1662
|
(props) => this.garbageCollector.nodeUpdated(props),
|
|
@@ -1660,24 +1699,6 @@ export class ContainerRuntime
|
|
|
1660
1699
|
createChildLogger({ logger: this.logger, namespace: "ScheduleManager" }),
|
|
1661
1700
|
);
|
|
1662
1701
|
|
|
1663
|
-
this.pendingStateManager = new PendingStateManager(
|
|
1664
|
-
{
|
|
1665
|
-
applyStashedOp: this.applyStashedOp.bind(this),
|
|
1666
|
-
clientId: () => this.clientId,
|
|
1667
|
-
close: this.closeFn,
|
|
1668
|
-
connected: () => this.connected,
|
|
1669
|
-
reSubmit: (message: IPendingBatchMessage) => {
|
|
1670
|
-
this.reSubmit(message);
|
|
1671
|
-
this.flush();
|
|
1672
|
-
},
|
|
1673
|
-
reSubmitBatch: this.reSubmitBatch.bind(this),
|
|
1674
|
-
isActiveConnection: () => this.innerDeltaManager.active,
|
|
1675
|
-
isAttached: () => this.attachState !== AttachState.Detached,
|
|
1676
|
-
},
|
|
1677
|
-
pendingRuntimeState?.pending,
|
|
1678
|
-
this.logger,
|
|
1679
|
-
);
|
|
1680
|
-
|
|
1681
1702
|
const disablePartialFlush = this.mc.config.getBoolean(
|
|
1682
1703
|
"Fluid.ContainerRuntime.DisablePartialFlush",
|
|
1683
1704
|
);
|
|
@@ -1729,7 +1750,7 @@ export class ContainerRuntime
|
|
|
1729
1750
|
let oldClientId = this.clientId;
|
|
1730
1751
|
this.on("connected", () => {
|
|
1731
1752
|
const clientId = this.clientId;
|
|
1732
|
-
assert(clientId !== undefined,
|
|
1753
|
+
assert(clientId !== undefined, 0x975 /* can't be undefined */);
|
|
1733
1754
|
(audience as unknown as TypedEventEmitter<IAudienceEvents>).emit(
|
|
1734
1755
|
"selfChanged",
|
|
1735
1756
|
{ clientId: oldClientId },
|
|
@@ -2321,6 +2342,7 @@ export class ContainerRuntime
|
|
|
2321
2342
|
let newState: boolean;
|
|
2322
2343
|
|
|
2323
2344
|
try {
|
|
2345
|
+
this.submitIdAllocationOpIfNeeded(true);
|
|
2324
2346
|
// replay the ops
|
|
2325
2347
|
this.pendingStateManager.replayPendingStates();
|
|
2326
2348
|
} finally {
|
|
@@ -2373,8 +2395,6 @@ export class ContainerRuntime
|
|
|
2373
2395
|
return;
|
|
2374
2396
|
case ContainerMessageType.BlobAttach:
|
|
2375
2397
|
return;
|
|
2376
|
-
case ContainerMessageType.ChunkedOp:
|
|
2377
|
-
throw new Error("chunkedOp not expected here");
|
|
2378
2398
|
case ContainerMessageType.Rejoin:
|
|
2379
2399
|
throw new Error("rejoin not expected here");
|
|
2380
2400
|
case ContainerMessageType.GC:
|
|
@@ -2387,7 +2407,7 @@ export class ContainerRuntime
|
|
|
2387
2407
|
const compatBehavior = opContents.compatDetails?.behavior;
|
|
2388
2408
|
if (!compatBehaviorAllowsMessageType(opContents.type, compatBehavior)) {
|
|
2389
2409
|
const error = DataProcessingError.create(
|
|
2390
|
-
"Stashed runtime message of
|
|
2410
|
+
"Stashed runtime message of unexpected type",
|
|
2391
2411
|
"applyStashedOp",
|
|
2392
2412
|
undefined /* sequencedMessage */,
|
|
2393
2413
|
{
|
|
@@ -2420,7 +2440,7 @@ export class ContainerRuntime
|
|
|
2420
2440
|
for (const range of ops) {
|
|
2421
2441
|
compressor.finalizeCreationRange(range);
|
|
2422
2442
|
}
|
|
2423
|
-
assert(this.pendingIdCompressorOps.length === 0,
|
|
2443
|
+
assert(this.pendingIdCompressorOps.length === 0, 0x976 /* No new ops added */);
|
|
2424
2444
|
this._idCompressor = compressor;
|
|
2425
2445
|
})
|
|
2426
2446
|
.catch((error) => {
|
|
@@ -2434,8 +2454,11 @@ export class ContainerRuntime
|
|
|
2434
2454
|
public setConnectionState(connected: boolean, clientId?: string) {
|
|
2435
2455
|
// Validate we have consistent state
|
|
2436
2456
|
const currentClientId = this._audience.getSelf()?.clientId;
|
|
2437
|
-
assert(clientId === currentClientId,
|
|
2438
|
-
assert(
|
|
2457
|
+
assert(clientId === currentClientId, 0x977 /* input clientId does not match Audience */);
|
|
2458
|
+
assert(
|
|
2459
|
+
this.clientId === currentClientId,
|
|
2460
|
+
0x978 /* this.clientId does not match Audience */,
|
|
2461
|
+
);
|
|
2439
2462
|
|
|
2440
2463
|
if (connected && this.idCompressorMode === "delayed") {
|
|
2441
2464
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -2582,6 +2605,17 @@ export class ContainerRuntime
|
|
|
2582
2605
|
*/
|
|
2583
2606
|
private processCore(messageWithContext: MessageWithContext) {
|
|
2584
2607
|
const { message, local } = messageWithContext;
|
|
2608
|
+
|
|
2609
|
+
// Intercept to reduce minimum sequence number to the delta manager's minimum sequence number.
|
|
2610
|
+
// Sequence numbers are not guaranteed to follow any sort of order. Re-entrancy is one of those situations
|
|
2611
|
+
if (
|
|
2612
|
+
this.deltaManager.minimumSequenceNumber <
|
|
2613
|
+
messageWithContext.message.minimumSequenceNumber
|
|
2614
|
+
) {
|
|
2615
|
+
messageWithContext.message.minimumSequenceNumber =
|
|
2616
|
+
this.deltaManager.minimumSequenceNumber;
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2585
2619
|
// Surround the actual processing of the operation with messages to the schedule manager indicating
|
|
2586
2620
|
// the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
|
|
2587
2621
|
// messages once a batch has been fully processed.
|
|
@@ -2672,7 +2706,7 @@ export class ContainerRuntime
|
|
|
2672
2706
|
} else {
|
|
2673
2707
|
assert(
|
|
2674
2708
|
this.pendingIdCompressorOps.length === 0,
|
|
2675
|
-
|
|
2709
|
+
0x979 /* there should be no pending ops! */,
|
|
2676
2710
|
);
|
|
2677
2711
|
this._idCompressor.finalizeCreationRange(range);
|
|
2678
2712
|
}
|
|
@@ -3204,7 +3238,7 @@ export class ContainerRuntime
|
|
|
3204
3238
|
|
|
3205
3239
|
return { stats, summary };
|
|
3206
3240
|
} finally {
|
|
3207
|
-
|
|
3241
|
+
summaryLogger.sendTelemetryEvent({
|
|
3208
3242
|
eventName: "SummarizeTelemetry",
|
|
3209
3243
|
details: telemetryContext.serialize(),
|
|
3210
3244
|
});
|
|
@@ -3880,14 +3914,16 @@ export class ContainerRuntime
|
|
|
3880
3914
|
public async uploadBlob(
|
|
3881
3915
|
blob: ArrayBufferLike,
|
|
3882
3916
|
signal?: AbortSignal,
|
|
3883
|
-
): Promise<
|
|
3917
|
+
): Promise<IFluidHandleInternal<ArrayBufferLike>> {
|
|
3884
3918
|
this.verifyNotClosed();
|
|
3885
3919
|
return this.blobManager.createBlob(blob, signal);
|
|
3886
3920
|
}
|
|
3887
3921
|
|
|
3888
|
-
private submitIdAllocationOpIfNeeded(): void {
|
|
3922
|
+
private submitIdAllocationOpIfNeeded(resubmitOutstandingRanges = false): void {
|
|
3889
3923
|
if (this._idCompressor) {
|
|
3890
|
-
const idRange =
|
|
3924
|
+
const idRange = resubmitOutstandingRanges
|
|
3925
|
+
? this.idCompressor?.takeUnfinalizedCreationRange()
|
|
3926
|
+
: this._idCompressor.takeNextCreationRange();
|
|
3891
3927
|
// Don't include the idRange if there weren't any Ids allocated
|
|
3892
3928
|
if (idRange?.ids !== undefined) {
|
|
3893
3929
|
const idAllocationMessage: ContainerRuntimeIdAllocationMessage = {
|
|
@@ -4103,11 +4139,15 @@ export class ContainerRuntime
|
|
|
4103
4139
|
this.channelCollection.reSubmit(message.type, message.contents, localOpMetadata);
|
|
4104
4140
|
break;
|
|
4105
4141
|
case ContainerMessageType.IdAllocation: {
|
|
4106
|
-
|
|
4142
|
+
// Allocation ops are never resubmitted/rebased. This is because they require special handling to
|
|
4143
|
+
// avoid being submitted out of order. For example, if the pending state manager contained
|
|
4144
|
+
// [idOp1, dataOp1, idOp2, dataOp2] and the resubmission of dataOp1 generated idOp3, that would be
|
|
4145
|
+
// placed into the outbox in the same batch as idOp1, but before idOp2 is resubmitted.
|
|
4146
|
+
// To avoid this, allocation ops are simply never resubmitted. Prior to invoking the pending state
|
|
4147
|
+
// manager to replay pending ops, the runtime will always submit a new allocation range that includes
|
|
4148
|
+
// all pending IDs. The resubmitted allocation ops are then ignored here.
|
|
4107
4149
|
break;
|
|
4108
4150
|
}
|
|
4109
|
-
case ContainerMessageType.ChunkedOp:
|
|
4110
|
-
throw new Error(`chunkedOp not expected here`);
|
|
4111
4151
|
case ContainerMessageType.BlobAttach:
|
|
4112
4152
|
this.blobManager.reSubmit(opMetadata);
|
|
4113
4153
|
break;
|
|
@@ -4134,7 +4174,7 @@ export class ContainerRuntime
|
|
|
4134
4174
|
});
|
|
4135
4175
|
} else {
|
|
4136
4176
|
const error = DataProcessingError.create(
|
|
4137
|
-
"Resubmitting runtime message of
|
|
4177
|
+
"Resubmitting runtime message of unexpected type",
|
|
4138
4178
|
"reSubmitCore",
|
|
4139
4179
|
undefined /* sequencedMessage */,
|
|
4140
4180
|
{
|
package/src/dataStore.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { AttachState } from "@fluidframework/container-definitions";
|
|
7
|
-
import { FluidObject,
|
|
7
|
+
import { FluidObject, type IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
|
|
8
8
|
import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
|
|
9
9
|
import {
|
|
10
10
|
AliasResult,
|
|
@@ -169,7 +169,7 @@ class DataStore implements IDataStore {
|
|
|
169
169
|
/**
|
|
170
170
|
* {@inheritDoc @fluidframework/runtime-definitions#IDataStore.entryPoint}
|
|
171
171
|
*/
|
|
172
|
-
get entryPoint():
|
|
172
|
+
get entryPoint(): IFluidHandleInternal<FluidObject> {
|
|
173
173
|
return this.fluidDataStoreChannel.entryPoint;
|
|
174
174
|
}
|
|
175
175
|
|