@fluidframework/container-runtime 2.0.0-internal.7.2.2 → 2.0.0-internal.7.3.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/CHANGELOG.md +4 -0
- package/README.md +1 -2
- package/dist/batchTracker.d.ts +1 -0
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +5 -11
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +20 -30
- package/dist/containerRuntime.js.map +1 -1
- package/dist/messageTypes.d.ts +3 -6
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/metadata.d.ts +6 -0
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +10 -1
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +2 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +21 -0
- 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 +0 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +1 -11
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts +1 -0
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/batchTracker.d.ts +1 -0
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +5 -11
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +20 -30
- package/lib/containerRuntime.js.map +1 -1
- package/lib/messageTypes.d.ts +3 -6
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/metadata.d.ts +6 -0
- package/lib/metadata.d.ts.map +1 -1
- package/lib/metadata.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +10 -1
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +2 -0
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +21 -0
- 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 +0 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +1 -11
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts +1 -0
- package/lib/scheduleManager.d.ts.map +1 -1
- package/package.json +29 -25
- package/src/connectionTelemetry.ts +1 -1
- package/src/containerRuntime.ts +30 -37
- package/src/messageTypes.ts +2 -7
- package/src/metadata.ts +7 -0
- package/src/opLifecycle/opGroupingManager.ts +10 -1
- package/src/opLifecycle/outbox.ts +34 -0
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +2 -13
package/lib/scheduleManager.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduleManager.d.ts","sourceRoot":"","sources":["../src/scheduleManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACnG,OAAO,EAKN,mBAAmB,EACnB,MAAM,iCAAiC,CAAC;AAczC;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAM1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IARxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAS;gBAGP,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,EACxE,OAAO,EAAE,YAAY,EAC7B,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,mBAAmB;IAStC,kBAAkB,CAAC,OAAO,EAAE,yBAAyB;IAkBrD,iBAAiB,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,EAAE,OAAO,EAAE,yBAAyB;CAwBnF"}
|
|
1
|
+
{"version":3,"file":"scheduleManager.d.ts","sourceRoot":"","sources":["../src/scheduleManager.ts"],"names":[],"mappings":";AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACnG,OAAO,EAKN,mBAAmB,EACnB,MAAM,iCAAiC,CAAC;AAczC;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAM1B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM;IARxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAS;gBAGP,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,EACxE,OAAO,EAAE,YAAY,EAC7B,WAAW,EAAE,MAAM,MAAM,GAAG,SAAS,EAC7B,MAAM,EAAE,mBAAmB;IAStC,kBAAkB,CAAC,OAAO,EAAE,yBAAyB;IAkBrD,iBAAiB,CAAC,KAAK,EAAE,GAAG,GAAG,SAAS,EAAE,OAAO,EAAE,yBAAyB;CAwBnF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-runtime",
|
|
3
|
-
"version": "2.0.0-internal.7.
|
|
3
|
+
"version": "2.0.0-internal.7.3.0",
|
|
4
4
|
"description": "Fluid container runtime",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -35,18 +35,18 @@
|
|
|
35
35
|
"temp-directory": "nyc/.nyc_output"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@fluid-internal/client-utils": ">=2.0.0-internal.7.
|
|
39
|
-
"@fluidframework/container-definitions": ">=2.0.0-internal.7.
|
|
40
|
-
"@fluidframework/container-runtime-definitions": ">=2.0.0-internal.7.
|
|
41
|
-
"@fluidframework/core-interfaces": ">=2.0.0-internal.7.
|
|
42
|
-
"@fluidframework/core-utils": ">=2.0.0-internal.7.
|
|
43
|
-
"@fluidframework/datastore": ">=2.0.0-internal.7.
|
|
44
|
-
"@fluidframework/driver-definitions": ">=2.0.0-internal.7.
|
|
45
|
-
"@fluidframework/driver-utils": ">=2.0.0-internal.7.
|
|
38
|
+
"@fluid-internal/client-utils": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
39
|
+
"@fluidframework/container-definitions": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
40
|
+
"@fluidframework/container-runtime-definitions": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
41
|
+
"@fluidframework/core-interfaces": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
42
|
+
"@fluidframework/core-utils": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
43
|
+
"@fluidframework/datastore": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
44
|
+
"@fluidframework/driver-definitions": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
45
|
+
"@fluidframework/driver-utils": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
46
46
|
"@fluidframework/protocol-definitions": "^3.0.0",
|
|
47
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-internal.7.
|
|
48
|
-
"@fluidframework/runtime-utils": ">=2.0.0-internal.7.
|
|
49
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-internal.7.
|
|
47
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
48
|
+
"@fluidframework/runtime-utils": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
49
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
50
50
|
"double-ended-queue": "^2.1.0-0",
|
|
51
51
|
"events": "^3.1.0",
|
|
52
52
|
"lz4js": "^0.2.0",
|
|
@@ -54,16 +54,16 @@
|
|
|
54
54
|
"uuid": "^9.0.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@fluid-
|
|
57
|
+
"@fluid-private/stochastic-test-utils": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
58
58
|
"@fluid-tools/benchmark": "^0.48.0",
|
|
59
|
-
"@fluid-tools/build-cli": "^0.
|
|
59
|
+
"@fluid-tools/build-cli": "^0.28.0",
|
|
60
60
|
"@fluidframework/build-common": "^2.0.3",
|
|
61
|
-
"@fluidframework/build-tools": "^0.
|
|
62
|
-
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.7.2.
|
|
63
|
-
"@fluidframework/eslint-config-fluid": "^3.
|
|
64
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.7.
|
|
65
|
-
"@fluidframework/test-runtime-utils": ">=2.0.0-internal.7.
|
|
66
|
-
"@microsoft/api-extractor": "^7.
|
|
61
|
+
"@fluidframework/build-tools": "^0.28.0",
|
|
62
|
+
"@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.0.0-internal.7.2.0",
|
|
63
|
+
"@fluidframework/eslint-config-fluid": "^3.1.0",
|
|
64
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
65
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-internal.7.3.0 <2.0.0-internal.7.4.0",
|
|
66
|
+
"@microsoft/api-extractor": "^7.38.3",
|
|
67
67
|
"@types/double-ended-queue": "^2.1.0",
|
|
68
68
|
"@types/events": "^3.0.0",
|
|
69
69
|
"@types/mocha": "^9.1.1",
|
|
@@ -82,7 +82,11 @@
|
|
|
82
82
|
"typescript": "~5.1.6"
|
|
83
83
|
},
|
|
84
84
|
"typeValidation": {
|
|
85
|
-
"broken": {
|
|
85
|
+
"broken": {
|
|
86
|
+
"ClassDeclaration_ContainerRuntime": {
|
|
87
|
+
"backCompat": false
|
|
88
|
+
}
|
|
89
|
+
}
|
|
86
90
|
},
|
|
87
91
|
"scripts": {
|
|
88
92
|
"build": "fluid-build . --task build",
|
|
@@ -93,18 +97,18 @@
|
|
|
93
97
|
"build:genver": "gen-version",
|
|
94
98
|
"build:test": "tsc --project ./src/test/tsconfig.json",
|
|
95
99
|
"ci:build:docs": "api-extractor run",
|
|
96
|
-
"clean": "rimraf --glob dist lib \"
|
|
100
|
+
"clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
|
|
97
101
|
"eslint": "eslint --format stylish src",
|
|
98
102
|
"eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
|
|
99
103
|
"format": "npm run prettier:fix",
|
|
100
104
|
"lint": "npm run prettier && npm run eslint",
|
|
101
|
-
"lint:fix": "npm run prettier:fix &&npm run eslint:fix",
|
|
105
|
+
"lint:fix": "npm run prettier:fix && npm run eslint:fix",
|
|
102
106
|
"prettier": "prettier --check . --ignore-path ../../../.prettierignore",
|
|
103
107
|
"prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
|
|
104
108
|
"test": "npm run test:mocha",
|
|
105
|
-
"test:benchmark:report": "mocha --timeout 999999 --perfMode --parentProcess --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js ./dist/**/*.perf.spec.js",
|
|
109
|
+
"test:benchmark:report": "mocha --timeout 999999 --perfMode --parentProcess --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js \"./dist/**/*.perf.spec.js\"",
|
|
106
110
|
"test:coverage": "c8 npm test",
|
|
107
|
-
"test:mocha": "mocha --ignore
|
|
111
|
+
"test:mocha": "mocha --ignore \"dist/test/types/*\" --recursive dist/test -r node_modules/@fluidframework/mocha-test-setup",
|
|
108
112
|
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
109
113
|
"tsc": "tsc",
|
|
110
114
|
"tsc:watch": "tsc --watch",
|
|
@@ -110,7 +110,7 @@ class OpPerfTelemetry {
|
|
|
110
110
|
|
|
111
111
|
this.deltaLatencyLogger = createSampledLogger(logger, deltaLatencyEventSampler);
|
|
112
112
|
|
|
113
|
-
// The SampledLogger here is used get access to the isSamplingDisabled property
|
|
113
|
+
// The SampledLogger here is used get access to the isSamplingDisabled property derived from
|
|
114
114
|
// telemetry config properties. The actual sampling logic for op messages happens outside this SampledLogger
|
|
115
115
|
// due to complexity of the different asynchronus scenarios of the op message lifecycle.
|
|
116
116
|
this.opLatencyLogger = createSampledLogger(logger);
|
package/src/containerRuntime.ts
CHANGED
|
@@ -91,7 +91,7 @@ import {
|
|
|
91
91
|
IIdCompressor,
|
|
92
92
|
IIdCompressorCore,
|
|
93
93
|
IdCreationRange,
|
|
94
|
-
|
|
94
|
+
SerializedIdCompressorWithOngoingSession,
|
|
95
95
|
} from "@fluidframework/runtime-definitions";
|
|
96
96
|
import {
|
|
97
97
|
addBlobToSummary,
|
|
@@ -185,13 +185,12 @@ import {
|
|
|
185
185
|
getLongStack,
|
|
186
186
|
} from "./opLifecycle";
|
|
187
187
|
import { DeltaManagerSummarizerProxy } from "./deltaManagerSummarizerProxy";
|
|
188
|
-
import { IBatchMetadata } from "./metadata";
|
|
188
|
+
import { IBatchMetadata, IIdAllocationMetadata } from "./metadata";
|
|
189
189
|
import {
|
|
190
190
|
ContainerMessageType,
|
|
191
191
|
type InboundSequencedContainerRuntimeMessage,
|
|
192
192
|
type InboundSequencedContainerRuntimeMessageOrSystemMessage,
|
|
193
193
|
type ContainerRuntimeIdAllocationMessage,
|
|
194
|
-
type LocalContainerRuntimeIdAllocationMessage,
|
|
195
194
|
type LocalContainerRuntimeMessage,
|
|
196
195
|
type OutboundContainerRuntimeMessage,
|
|
197
196
|
type UnknownContainerRuntimeMessage,
|
|
@@ -213,15 +212,6 @@ function compatBehaviorAllowsMessageType(
|
|
|
213
212
|
return compatBehavior === "Ignore";
|
|
214
213
|
}
|
|
215
214
|
|
|
216
|
-
function prepareLocalContainerRuntimeIdAllocationMessageForTransit(
|
|
217
|
-
message: LocalContainerRuntimeIdAllocationMessage | ContainerRuntimeIdAllocationMessage,
|
|
218
|
-
): asserts message is ContainerRuntimeIdAllocationMessage {
|
|
219
|
-
// Remove the stashedState from the op if it's a stashed op
|
|
220
|
-
if ("stashedState" in message.contents) {
|
|
221
|
-
delete message.contents.stashedState;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
215
|
/**
|
|
226
216
|
* @public
|
|
227
217
|
*/
|
|
@@ -557,6 +547,10 @@ export interface IPendingRuntimeState {
|
|
|
557
547
|
* Pending blobs from BlobManager
|
|
558
548
|
*/
|
|
559
549
|
pendingAttachmentBlobs?: IPendingBlobs;
|
|
550
|
+
/**
|
|
551
|
+
* Pending idCompressor state
|
|
552
|
+
*/
|
|
553
|
+
pendingIdCompressorState?: SerializedIdCompressorWithOngoingSession;
|
|
560
554
|
}
|
|
561
555
|
|
|
562
556
|
const maxConsecutiveReconnectsKey = "Fluid.ContainerRuntime.MaxConsecutiveReconnects";
|
|
@@ -916,10 +910,16 @@ export class ContainerRuntime
|
|
|
916
910
|
let idCompressor: (IIdCompressor & IIdCompressorCore) | undefined;
|
|
917
911
|
if (idCompressorEnabled) {
|
|
918
912
|
const { IdCompressor, createSessionId } = await import("./id-compressor");
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
913
|
+
|
|
914
|
+
const pendingLocalState = context.pendingLocalState as IPendingRuntimeState;
|
|
915
|
+
|
|
916
|
+
if (pendingLocalState?.pendingIdCompressorState !== undefined) {
|
|
917
|
+
idCompressor = IdCompressor.deserialize(pendingLocalState.pendingIdCompressorState);
|
|
918
|
+
} else if (serializedIdCompressor !== undefined) {
|
|
919
|
+
idCompressor = IdCompressor.deserialize(serializedIdCompressor, createSessionId());
|
|
920
|
+
} else {
|
|
921
|
+
idCompressor = IdCompressor.create(logger);
|
|
922
|
+
}
|
|
923
923
|
}
|
|
924
924
|
|
|
925
925
|
const runtime = new containerRuntimeCtor(
|
|
@@ -2050,20 +2050,6 @@ export class ContainerRuntime
|
|
|
2050
2050
|
this.updateDocumentDirtyState(newState);
|
|
2051
2051
|
}
|
|
2052
2052
|
|
|
2053
|
-
/**
|
|
2054
|
-
* Updates the runtime's IdCompressor with the stashed state present in the given op. This is a bit of a
|
|
2055
|
-
* hack and is unnecessarily expensive. As it stands, every locally stashed op (all ops that get stored in
|
|
2056
|
-
* the PendingStateManager) will store their serialized representation locally until ack'd. Upon receiving
|
|
2057
|
-
* this stashed state, the IdCompressor blindly deserializes to the stashed state and assumes the session.
|
|
2058
|
-
* Technically only the last stashed state is needed to do this correctly, but we would have to write some
|
|
2059
|
-
* more hacky code to modify the batch before it gets sent out.
|
|
2060
|
-
* @param content - An IdAllocationOp with "stashedState", which is a representation of un-ack'd local state.
|
|
2061
|
-
*/
|
|
2062
|
-
private async applyStashedIdAllocationOp(op: IdCreationRangeWithStashedState) {
|
|
2063
|
-
const { IdCompressor } = await import("./id-compressor");
|
|
2064
|
-
this.idCompressor = IdCompressor.deserialize(op.stashedState);
|
|
2065
|
-
}
|
|
2066
|
-
|
|
2067
2053
|
/**
|
|
2068
2054
|
* Parse an op's type and actual content from given serialized content
|
|
2069
2055
|
* ! Note: this format needs to be in-line with what is set in the "ContainerRuntime.submit(...)" method
|
|
@@ -2089,7 +2075,7 @@ export class ContainerRuntime
|
|
|
2089
2075
|
this.idCompressor !== undefined,
|
|
2090
2076
|
0x67b /* IdCompressor should be defined if enabled */,
|
|
2091
2077
|
);
|
|
2092
|
-
return
|
|
2078
|
+
return;
|
|
2093
2079
|
case ContainerMessageType.Alias:
|
|
2094
2080
|
case ContainerMessageType.BlobAttach:
|
|
2095
2081
|
return;
|
|
@@ -2341,7 +2327,14 @@ export class ContainerRuntime
|
|
|
2341
2327
|
this.idCompressor !== undefined,
|
|
2342
2328
|
0x67c /* IdCompressor should be defined if enabled */,
|
|
2343
2329
|
);
|
|
2344
|
-
|
|
2330
|
+
|
|
2331
|
+
// Don't re-finalize the range if we're processing a "savedOp" in
|
|
2332
|
+
// stashed ops flow. The compressor is stashed with these ops already processed.
|
|
2333
|
+
if (
|
|
2334
|
+
(messageWithContext.message.metadata as IIdAllocationMetadata)?.savedOp !== true
|
|
2335
|
+
) {
|
|
2336
|
+
this.idCompressor.finalizeCreationRange(messageWithContext.message.contents);
|
|
2337
|
+
}
|
|
2345
2338
|
break;
|
|
2346
2339
|
case ContainerMessageType.ChunkedOp:
|
|
2347
2340
|
case ContainerMessageType.Rejoin:
|
|
@@ -3516,13 +3509,13 @@ export class ContainerRuntime
|
|
|
3516
3509
|
contents: JSON.stringify(idAllocationMessage),
|
|
3517
3510
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
3518
3511
|
metadata: undefined,
|
|
3519
|
-
localOpMetadata:
|
|
3512
|
+
localOpMetadata: undefined,
|
|
3520
3513
|
type: ContainerMessageType.IdAllocation,
|
|
3521
3514
|
};
|
|
3522
3515
|
}
|
|
3523
3516
|
|
|
3524
3517
|
if (idAllocationBatchMessage !== undefined) {
|
|
3525
|
-
this.outbox.
|
|
3518
|
+
this.outbox.submitIdAllocation(idAllocationBatchMessage);
|
|
3526
3519
|
}
|
|
3527
3520
|
}
|
|
3528
3521
|
}
|
|
@@ -3747,10 +3740,7 @@ export class ContainerRuntime
|
|
|
3747
3740
|
break;
|
|
3748
3741
|
case ContainerMessageType.Attach:
|
|
3749
3742
|
case ContainerMessageType.Alias:
|
|
3750
|
-
this.submit(message, localOpMetadata);
|
|
3751
|
-
break;
|
|
3752
3743
|
case ContainerMessageType.IdAllocation: {
|
|
3753
|
-
prepareLocalContainerRuntimeIdAllocationMessageForTransit(message);
|
|
3754
3744
|
this.submit(message, localOpMetadata);
|
|
3755
3745
|
break;
|
|
3756
3746
|
}
|
|
@@ -3990,9 +3980,12 @@ export class ContainerRuntime
|
|
|
3990
3980
|
return; // no pending state to save
|
|
3991
3981
|
}
|
|
3992
3982
|
|
|
3983
|
+
const pendingIdCompressorState = this.idCompressor?.serialize(true);
|
|
3984
|
+
|
|
3993
3985
|
const pendingState: IPendingRuntimeState = {
|
|
3994
3986
|
pending,
|
|
3995
3987
|
pendingAttachmentBlobs,
|
|
3988
|
+
pendingIdCompressorState,
|
|
3996
3989
|
};
|
|
3997
3990
|
event.end({
|
|
3998
3991
|
attachmentBlobsSize: Object.keys(pendingAttachmentBlobs ?? {}).length,
|
package/src/messageTypes.ts
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
IEnvelope,
|
|
9
9
|
InboundAttachMessage,
|
|
10
10
|
IAttachMessage,
|
|
11
|
-
IdCreationRangeWithStashedState,
|
|
12
11
|
IdCreationRange,
|
|
13
12
|
} from "@fluidframework/runtime-definitions";
|
|
14
13
|
import { IDataStoreAliasMessage } from "./dataStore";
|
|
@@ -116,13 +115,9 @@ export type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage<
|
|
|
116
115
|
ContainerMessageType.Alias,
|
|
117
116
|
IDataStoreAliasMessage
|
|
118
117
|
>;
|
|
119
|
-
export type LocalContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
|
|
120
|
-
ContainerMessageType.IdAllocation,
|
|
121
|
-
IdCreationRangeWithStashedState
|
|
122
|
-
>;
|
|
123
118
|
export type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
|
|
124
119
|
ContainerMessageType.IdAllocation,
|
|
125
|
-
IdCreationRange
|
|
120
|
+
IdCreationRange
|
|
126
121
|
>;
|
|
127
122
|
|
|
128
123
|
/**
|
|
@@ -163,7 +158,7 @@ export type LocalContainerRuntimeMessage =
|
|
|
163
158
|
| ContainerRuntimeBlobAttachMessage
|
|
164
159
|
| ContainerRuntimeRejoinMessage
|
|
165
160
|
| ContainerRuntimeAliasMessage
|
|
166
|
-
|
|
|
161
|
+
| ContainerRuntimeIdAllocationMessage
|
|
167
162
|
// In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type
|
|
168
163
|
| UnknownContainerRuntimeMessage;
|
|
169
164
|
|
package/src/metadata.ts
CHANGED
|
@@ -17,3 +17,10 @@ export interface IBlobMetadata {
|
|
|
17
17
|
blobId?: string;
|
|
18
18
|
localId?: string;
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The IdCompressor needs to know if this is a replayed savedOp as those need to be skipped in stashed ops scenarios.
|
|
23
|
+
*/
|
|
24
|
+
export interface IIdAllocationMetadata {
|
|
25
|
+
savedOp?: boolean;
|
|
26
|
+
}
|
|
@@ -96,12 +96,21 @@ export class OpGroupingManager {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
public ungroupOp(op: ISequencedDocumentMessage): ISequencedDocumentMessage[] {
|
|
99
|
+
let fakeCsn = 1;
|
|
99
100
|
if (!isGroupContents(op.contents)) {
|
|
101
|
+
// Align the worlds of what clientSequenceNumber represents when grouped batching is enabled
|
|
102
|
+
if (this.config.groupedBatchingEnabled) {
|
|
103
|
+
return [
|
|
104
|
+
{
|
|
105
|
+
...op,
|
|
106
|
+
clientSequenceNumber: fakeCsn,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
}
|
|
100
110
|
return [op];
|
|
101
111
|
}
|
|
102
112
|
|
|
103
113
|
const messages = op.contents.contents;
|
|
104
|
-
let fakeCsn = 1;
|
|
105
114
|
return messages.map((subMessage) => ({
|
|
106
115
|
...op,
|
|
107
116
|
clientSequenceNumber: fakeCsn++,
|
|
@@ -89,6 +89,7 @@ export class Outbox {
|
|
|
89
89
|
private readonly attachFlowBatch: BatchManager;
|
|
90
90
|
private readonly mainBatch: BatchManager;
|
|
91
91
|
private readonly blobAttachBatch: BatchManager;
|
|
92
|
+
private readonly idAllocationBatch: BatchManager;
|
|
92
93
|
private readonly defaultAttachFlowSoftLimitInBytes = 320 * 1024;
|
|
93
94
|
private batchRebasesToReport = 5;
|
|
94
95
|
private rebasing = false;
|
|
@@ -114,6 +115,7 @@ export class Outbox {
|
|
|
114
115
|
this.attachFlowBatch = new BatchManager({ hardLimit, softLimit });
|
|
115
116
|
this.mainBatch = new BatchManager({ hardLimit });
|
|
116
117
|
this.blobAttachBatch = new BatchManager({ hardLimit });
|
|
118
|
+
this.idAllocationBatch = new BatchManager({ hardLimit });
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
public get messageCount(): number {
|
|
@@ -230,6 +232,37 @@ export class Outbox {
|
|
|
230
232
|
}
|
|
231
233
|
}
|
|
232
234
|
|
|
235
|
+
public submitIdAllocation(message: BatchMessage) {
|
|
236
|
+
this.maybeFlushPartialBatch();
|
|
237
|
+
|
|
238
|
+
if (
|
|
239
|
+
!this.idAllocationBatch.push(
|
|
240
|
+
message,
|
|
241
|
+
this.isContextReentrant(),
|
|
242
|
+
this.params.getCurrentSequenceNumbers().clientSequenceNumber,
|
|
243
|
+
)
|
|
244
|
+
) {
|
|
245
|
+
// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged
|
|
246
|
+
// when queue is not empty.
|
|
247
|
+
// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit
|
|
248
|
+
this.flushInternal(this.idAllocationBatch);
|
|
249
|
+
|
|
250
|
+
this.addMessageToBatchManager(this.idAllocationBatch, message);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// If compression is enabled, we will always successfully receive
|
|
254
|
+
// attach ops and compress then send them at the next JS turn, regardless
|
|
255
|
+
// of the overall size of the accumulated ops in the batch.
|
|
256
|
+
// However, it is more efficient to flush these ops faster, preferably
|
|
257
|
+
// after they reach a size which would benefit from compression.
|
|
258
|
+
if (
|
|
259
|
+
this.idAllocationBatch.contentSizeInBytes >=
|
|
260
|
+
this.params.config.compressionOptions.minimumBatchSizeInBytes
|
|
261
|
+
) {
|
|
262
|
+
this.flushInternal(this.idAllocationBatch);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
233
266
|
private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {
|
|
234
267
|
if (
|
|
235
268
|
!batchManager.push(
|
|
@@ -258,6 +291,7 @@ export class Outbox {
|
|
|
258
291
|
}
|
|
259
292
|
|
|
260
293
|
private flushAll() {
|
|
294
|
+
this.flushInternal(this.idAllocationBatch);
|
|
261
295
|
this.flushInternal(this.attachFlowBatch);
|
|
262
296
|
this.flushInternal(this.blobAttachBatch, true /* disableGroupedBatching */);
|
|
263
297
|
this.flushInternal(this.mainBatch);
|
package/src/packageVersion.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
|
11
11
|
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
12
12
|
import { DataProcessingError, ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { InboundSequencedContainerRuntimeMessage } from "./messageTypes";
|
|
15
15
|
import { pkgVersion } from "./packageVersion";
|
|
16
16
|
import { IBatchMetadata } from "./metadata";
|
|
17
17
|
|
|
@@ -21,7 +21,6 @@ import { IBatchMetadata } from "./metadata";
|
|
|
21
21
|
*/
|
|
22
22
|
export interface IPendingMessage {
|
|
23
23
|
type: "message";
|
|
24
|
-
clientSequenceNumber: number;
|
|
25
24
|
referenceSequenceNumber: number;
|
|
26
25
|
content: string;
|
|
27
26
|
localOpMetadata: unknown;
|
|
@@ -128,18 +127,9 @@ export class PendingStateManager implements IDisposable {
|
|
|
128
127
|
return {
|
|
129
128
|
pendingStates: [...this.savedOps, ...this.pendingMessages.toArray()].map(
|
|
130
129
|
(message) => {
|
|
131
|
-
let content = message.content;
|
|
132
|
-
const parsedContent = JSON.parse(content);
|
|
133
|
-
// IdAllocations need their localOpMetadata stashed in the contents
|
|
134
|
-
// of the op to correctly resume the session when processing stashed ops
|
|
135
|
-
if (parsedContent.type === ContainerMessageType.IdAllocation) {
|
|
136
|
-
parsedContent.contents.stashedState = message.localOpMetadata;
|
|
137
|
-
content = JSON.stringify(parsedContent);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
130
|
// delete localOpMetadata since it may not be serializable
|
|
141
131
|
// and will be regenerated by applyStashedOp()
|
|
142
|
-
return { ...message,
|
|
132
|
+
return { ...message, localOpMetadata: undefined };
|
|
143
133
|
},
|
|
144
134
|
),
|
|
145
135
|
};
|
|
@@ -176,7 +166,6 @@ export class PendingStateManager implements IDisposable {
|
|
|
176
166
|
) {
|
|
177
167
|
const pendingMessage: IPendingMessage = {
|
|
178
168
|
type: "message",
|
|
179
|
-
clientSequenceNumber: -1, // dummy value (not to be used anywhere)
|
|
180
169
|
referenceSequenceNumber,
|
|
181
170
|
content,
|
|
182
171
|
localOpMetadata,
|