@fluidframework/container-runtime 2.31.1 → 2.33.0-333010
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 +8 -0
- package/container-runtime.test-files.tar +0 -0
- package/dist/channelCollection.d.ts +0 -14
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +10 -25
- package/dist/channelCollection.js.map +1 -1
- package/dist/containerRuntime.d.ts +16 -9
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +137 -103
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +1 -5
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +0 -8
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +3 -7
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +3 -15
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +3 -40
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +42 -6
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +5 -4
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +6 -4
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts +10 -11
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +21 -20
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +9 -5
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +18 -22
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSerialization.d.ts +20 -0
- package/dist/opLifecycle/opSerialization.d.ts.map +1 -0
- package/dist/opLifecycle/opSerialization.js +40 -0
- package/dist/opLifecycle/opSerialization.js.map +1 -0
- package/dist/opLifecycle/opSplitter.d.ts +12 -13
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +15 -15
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +35 -18
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +111 -72
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +0 -7
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +1 -15
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +2 -2
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +1 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runtimeLayerCompatState.d.ts.map +1 -1
- package/dist/runtimeLayerCompatState.js +6 -5
- package/dist/runtimeLayerCompatState.js.map +1 -1
- package/dist/summary/index.d.ts +5 -8
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +20 -21
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.js +9 -9
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +0 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +3 -3
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +3 -75
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js +2 -0
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/{lib/summary/summaryGenerator.d.ts → dist/summary/summarizerUtils.d.ts} +12 -43
- package/dist/summary/summarizerUtils.d.ts.map +1 -0
- package/dist/summary/summarizerUtils.js +71 -0
- package/dist/summary/summarizerUtils.js.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/index.d.ts +10 -0
- package/dist/summary/summaryDelayLoadedModule/index.d.ts.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/index.js +20 -0
- package/dist/summary/summaryDelayLoadedModule/index.js.map +1 -0
- package/dist/summary/{runWhileConnectedCoordinator.d.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts} +1 -1
- package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -0
- package/dist/summary/{runningSummarizer.d.ts → summaryDelayLoadedModule/runningSummarizer.d.ts} +4 -13
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -0
- package/dist/summary/{runningSummarizer.js → summaryDelayLoadedModule/runningSummarizer.js} +17 -24
- package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -0
- package/dist/summary/{summarizer.d.ts → summaryDelayLoadedModule/summarizer.d.ts} +13 -2
- package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -0
- package/dist/summary/{summarizer.js → summaryDelayLoadedModule/summarizer.js} +13 -3
- package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -0
- package/{lib/summary → dist/summary/summaryDelayLoadedModule}/summarizerHeuristics.d.ts +3 -3
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +36 -0
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -0
- package/dist/summary/{summaryGenerator.js → summaryDelayLoadedModule/summaryGenerator.js} +14 -99
- package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +21 -0
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js +44 -0
- package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +80 -0
- package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -0
- package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js +7 -0
- package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -0
- package/dist/summary/summaryHelpers.d.ts +1 -1
- package/dist/summary/summaryHelpers.d.ts.map +1 -1
- package/dist/summary/summaryHelpers.js +2 -2
- package/dist/summary/summaryHelpers.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +4 -3
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +2 -2
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/channelCollection.d.ts +0 -14
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +6 -21
- package/lib/channelCollection.js.map +1 -1
- package/lib/containerRuntime.d.ts +16 -9
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +140 -106
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +1 -5
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +0 -8
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +3 -7
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +3 -15
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +2 -38
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +42 -6
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +5 -4
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +4 -3
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts +10 -11
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +21 -20
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +9 -5
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +18 -22
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSerialization.d.ts +20 -0
- package/lib/opLifecycle/opSerialization.d.ts.map +1 -0
- package/lib/opLifecycle/opSerialization.js +35 -0
- package/lib/opLifecycle/opSerialization.js.map +1 -0
- package/lib/opLifecycle/opSplitter.d.ts +12 -13
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +14 -14
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +35 -18
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +109 -71
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +0 -7
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +0 -13
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +2 -2
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +1 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/runtimeLayerCompatState.d.ts.map +1 -1
- package/lib/runtimeLayerCompatState.js +3 -2
- package/lib/runtimeLayerCompatState.js.map +1 -1
- package/lib/summary/index.d.ts +5 -8
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +5 -7
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.js +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +0 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +3 -75
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/{dist/summary/summaryGenerator.d.ts → lib/summary/summarizerUtils.d.ts} +12 -43
- package/lib/summary/summarizerUtils.d.ts.map +1 -0
- package/lib/summary/summarizerUtils.js +64 -0
- package/lib/summary/summarizerUtils.js.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/index.d.ts +10 -0
- package/lib/summary/summaryDelayLoadedModule/index.d.ts.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/index.js +9 -0
- package/lib/summary/summaryDelayLoadedModule/index.js.map +1 -0
- package/lib/summary/{runWhileConnectedCoordinator.d.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts} +1 -1
- package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -0
- package/lib/summary/{runningSummarizer.d.ts → summaryDelayLoadedModule/runningSummarizer.d.ts} +4 -13
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -0
- package/lib/summary/{runningSummarizer.js → summaryDelayLoadedModule/runningSummarizer.js} +5 -12
- package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -0
- package/lib/summary/{summarizer.d.ts → summaryDelayLoadedModule/summarizer.d.ts} +13 -2
- package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -0
- package/lib/summary/{summarizer.js → summaryDelayLoadedModule/summarizer.js} +11 -1
- package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -0
- package/{dist/summary → lib/summary/summaryDelayLoadedModule}/summarizerHeuristics.d.ts +3 -3
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +36 -0
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -0
- package/lib/summary/{summaryGenerator.js → summaryDelayLoadedModule/summaryGenerator.js} +4 -85
- package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +21 -0
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js +40 -0
- package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +80 -0
- package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -0
- package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js +6 -0
- package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -0
- package/lib/summary/summaryHelpers.d.ts +1 -1
- package/lib/summary/summaryHelpers.d.ts.map +1 -1
- package/lib/summary/summaryHelpers.js +1 -1
- package/lib/summary/summaryHelpers.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +4 -3
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +2 -2
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +20 -19
- package/src/channelCollection.ts +5 -20
- package/src/containerRuntime.ts +220 -178
- package/src/dataStoreContext.ts +0 -11
- package/src/index.ts +0 -1
- package/src/messageTypes.ts +5 -19
- package/src/opLifecycle/batchManager.ts +12 -51
- package/src/opLifecycle/definitions.ts +49 -6
- package/src/opLifecycle/index.ts +19 -4
- package/src/opLifecycle/opCompressor.ts +26 -25
- package/src/opLifecycle/opGroupingManager.ts +27 -26
- package/src/opLifecycle/opSerialization.ts +46 -0
- package/src/opLifecycle/opSplitter.ts +21 -17
- package/src/opLifecycle/outbox.ts +168 -99
- package/src/opLifecycle/remoteMessageProcessor.ts +0 -17
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +3 -3
- package/src/runtimeLayerCompatState.ts +3 -2
- package/src/summary/index.ts +35 -31
- package/src/summary/orderedClientElection.ts +1 -1
- package/src/summary/summarizerClientElection.ts +1 -2
- package/src/summary/summarizerTypes.ts +7 -91
- package/src/summary/summarizerUtils.ts +132 -0
- package/src/summary/summaryDelayLoadedModule/index.ts +28 -0
- package/src/summary/{runWhileConnectedCoordinator.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.ts} +1 -1
- package/src/summary/{runningSummarizer.ts → summaryDelayLoadedModule/runningSummarizer.ts} +13 -28
- package/src/summary/{summarizer.ts → summaryDelayLoadedModule/summarizer.ts} +19 -8
- package/src/summary/{summarizerHeuristics.ts → summaryDelayLoadedModule/summarizerHeuristics.ts} +3 -3
- package/src/summary/{summaryGenerator.ts → summaryDelayLoadedModule/summaryGenerator.ts} +13 -179
- package/src/summary/summaryDelayLoadedModule/summaryResultBuilder.ts +70 -0
- package/src/summary/summaryDelayLoadedModule/summaryResultTypes.ts +100 -0
- package/src/summary/summaryHelpers.ts +6 -6
- package/src/summary/summaryManager.ts +8 -6
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
- package/dist/summary/runWhileConnectedCoordinator.js.map +0 -1
- package/dist/summary/runningSummarizer.d.ts.map +0 -1
- package/dist/summary/runningSummarizer.js.map +0 -1
- package/dist/summary/summarizer.d.ts.map +0 -1
- package/dist/summary/summarizer.js.map +0 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +0 -1
- package/dist/summary/summarizerHeuristics.js.map +0 -1
- package/dist/summary/summaryGenerator.d.ts.map +0 -1
- package/dist/summary/summaryGenerator.js.map +0 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
- package/lib/summary/runWhileConnectedCoordinator.js.map +0 -1
- package/lib/summary/runningSummarizer.d.ts.map +0 -1
- package/lib/summary/runningSummarizer.js.map +0 -1
- package/lib/summary/summarizer.d.ts.map +0 -1
- package/lib/summary/summarizer.js.map +0 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +0 -1
- package/lib/summary/summarizerHeuristics.js.map +0 -1
- package/lib/summary/summaryGenerator.d.ts.map +0 -1
- package/lib/summary/summaryGenerator.js.map +0 -1
- /package/dist/summary/{runWhileConnectedCoordinator.js → summaryDelayLoadedModule/runWhileConnectedCoordinator.js} +0 -0
- /package/dist/summary/{summarizerHeuristics.js → summaryDelayLoadedModule/summarizerHeuristics.js} +0 -0
- /package/lib/summary/{runWhileConnectedCoordinator.js → summaryDelayLoadedModule/runWhileConnectedCoordinator.js} +0 -0
- /package/lib/summary/{summarizerHeuristics.js → summaryDelayLoadedModule/summarizerHeuristics.js} +0 -0
package/src/dataStoreContext.ts
CHANGED
|
@@ -9,8 +9,6 @@ import { IDeltaManager } from "@fluidframework/container-definitions/internal";
|
|
|
9
9
|
import {
|
|
10
10
|
FluidObject,
|
|
11
11
|
IDisposable,
|
|
12
|
-
IRequest,
|
|
13
|
-
IResponse,
|
|
14
12
|
ITelemetryBaseProperties,
|
|
15
13
|
type IEvent,
|
|
16
14
|
} from "@fluidframework/core-interfaces";
|
|
@@ -796,15 +794,6 @@ export abstract class FluidDataStoreContext
|
|
|
796
794
|
this.parentContext.addedGCOutboundRoute(fromPath, toPath, messageTimestampMs);
|
|
797
795
|
}
|
|
798
796
|
|
|
799
|
-
// eslint-disable-next-line jsdoc/require-description
|
|
800
|
-
/**
|
|
801
|
-
* @deprecated 0.18.Should call request on the runtime directly
|
|
802
|
-
*/
|
|
803
|
-
public async request(request: IRequest): Promise<IResponse> {
|
|
804
|
-
const runtime = await this.realize();
|
|
805
|
-
return runtime.request(request);
|
|
806
|
-
}
|
|
807
|
-
|
|
808
797
|
public submitMessage(type: string, content: unknown, localOpMetadata: unknown): void {
|
|
809
798
|
this.verifyNotClosed("submitMessage");
|
|
810
799
|
assert(!!this.channel, 0x146 /* "Channel must exist when submitting message" */);
|
package/src/index.ts
CHANGED
|
@@ -27,7 +27,6 @@ export { IBlobManagerLoadInfo } from "./blobManager/index.js";
|
|
|
27
27
|
export { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
28
28
|
export {
|
|
29
29
|
detectOutboundReferences,
|
|
30
|
-
RuntimeHeaders,
|
|
31
30
|
ChannelCollectionFactory,
|
|
32
31
|
AllowTombstoneRequestHeaderKey,
|
|
33
32
|
} from "./channelCollection.js";
|
package/src/messageTypes.ts
CHANGED
|
@@ -147,12 +147,12 @@ export type InboundContainerRuntimeMessage =
|
|
|
147
147
|
| ContainerRuntimeAliasMessage
|
|
148
148
|
| ContainerRuntimeIdAllocationMessage
|
|
149
149
|
| ContainerRuntimeGCMessage
|
|
150
|
+
| ContainerRuntimeDocumentSchemaMessage
|
|
150
151
|
// Inbound messages may include unknown types from other clients, so we include that as a special case here
|
|
151
|
-
| UnknownContainerRuntimeMessage
|
|
152
|
-
| ContainerRuntimeDocumentSchemaMessage;
|
|
152
|
+
| UnknownContainerRuntimeMessage;
|
|
153
153
|
|
|
154
154
|
/**
|
|
155
|
-
* A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime
|
|
155
|
+
* A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime, eventually to be sent to the ordering service.
|
|
156
156
|
* These are messages generated by the local runtime, before the outbox's op virtualization step.
|
|
157
157
|
*/
|
|
158
158
|
export type LocalContainerRuntimeMessage =
|
|
@@ -163,23 +163,9 @@ export type LocalContainerRuntimeMessage =
|
|
|
163
163
|
| ContainerRuntimeAliasMessage
|
|
164
164
|
| ContainerRuntimeIdAllocationMessage
|
|
165
165
|
| ContainerRuntimeGCMessage
|
|
166
|
+
| ContainerRuntimeDocumentSchemaMessage
|
|
166
167
|
// In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type
|
|
167
|
-
| UnknownContainerRuntimeMessage
|
|
168
|
-
| ContainerRuntimeDocumentSchemaMessage;
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* A {@link TypedContainerRuntimeMessage} that is being sent to the server from the container runtime.
|
|
172
|
-
*/
|
|
173
|
-
export type OutboundContainerRuntimeMessage =
|
|
174
|
-
| ContainerRuntimeDataStoreOpMessage
|
|
175
|
-
| OutboundContainerRuntimeAttachMessage
|
|
176
|
-
| ContainerRuntimeChunkedOpMessage
|
|
177
|
-
| ContainerRuntimeBlobAttachMessage
|
|
178
|
-
| ContainerRuntimeRejoinMessage
|
|
179
|
-
| ContainerRuntimeAliasMessage
|
|
180
|
-
| ContainerRuntimeIdAllocationMessage
|
|
181
|
-
| ContainerRuntimeGCMessage
|
|
182
|
-
| ContainerRuntimeDocumentSchemaMessage;
|
|
168
|
+
| UnknownContainerRuntimeMessage;
|
|
183
169
|
|
|
184
170
|
/**
|
|
185
171
|
* An unpacked ISequencedDocumentMessage with the inner TypedContainerRuntimeMessage type/contents/etc
|
|
@@ -14,11 +14,10 @@ import { ICompressionRuntimeOptions } from "../containerRuntime.js";
|
|
|
14
14
|
import { asBatchMetadata, type IBatchMetadata } from "../metadata.js";
|
|
15
15
|
import type { IPendingMessage } from "../pendingStateManager.js";
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import { LocalBatchMessage, IBatchCheckpoint, type LocalBatch } from "./definitions.js";
|
|
18
18
|
import type { BatchStartInfo } from "./remoteMessageProcessor.js";
|
|
19
19
|
|
|
20
20
|
export interface IBatchManagerOptions {
|
|
21
|
-
readonly hardLimit: number;
|
|
22
21
|
readonly compressionOptions?: ICompressionRuntimeOptions;
|
|
23
22
|
|
|
24
23
|
/**
|
|
@@ -73,26 +72,16 @@ export function getEffectiveBatchId(
|
|
|
73
72
|
return batchStart.batchId ?? generateBatchId(batchStart.clientId, batchStart.batchStartCsn);
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
/**
|
|
77
|
-
* Estimated size of the stringification overhead for an op accumulated
|
|
78
|
-
* from runtime to loader to the service.
|
|
79
|
-
*/
|
|
80
|
-
const opOverhead = 200;
|
|
81
|
-
|
|
82
75
|
/**
|
|
83
76
|
* Helper class that manages partial batch & rollback.
|
|
84
77
|
*/
|
|
85
78
|
export class BatchManager {
|
|
86
|
-
private pendingBatch:
|
|
87
|
-
private batchContentSize = 0;
|
|
79
|
+
private pendingBatch: LocalBatchMessage[] = [];
|
|
88
80
|
private hasReentrantOps = false;
|
|
89
81
|
|
|
90
82
|
public get length(): number {
|
|
91
83
|
return this.pendingBatch.length;
|
|
92
84
|
}
|
|
93
|
-
public get contentSizeInBytes(): number {
|
|
94
|
-
return this.batchContentSize;
|
|
95
|
-
}
|
|
96
85
|
|
|
97
86
|
public get sequenceNumbers(): BatchSequenceNumbers {
|
|
98
87
|
return {
|
|
@@ -117,32 +106,17 @@ export class BatchManager {
|
|
|
117
106
|
constructor(public readonly options: IBatchManagerOptions) {}
|
|
118
107
|
|
|
119
108
|
public push(
|
|
120
|
-
message:
|
|
109
|
+
message: LocalBatchMessage,
|
|
121
110
|
reentrant: boolean,
|
|
122
111
|
currentClientSequenceNumber?: number,
|
|
123
|
-
):
|
|
124
|
-
const contentSize = this.batchContentSize + (message.contents?.length ?? 0);
|
|
125
|
-
const opCount = this.pendingBatch.length;
|
|
112
|
+
): void {
|
|
126
113
|
this.hasReentrantOps = this.hasReentrantOps || reentrant;
|
|
127
114
|
|
|
128
|
-
// Attempt to estimate batch size, aka socket message size.
|
|
129
|
-
// Each op has pretty large envelope, estimating to be 200 bytes.
|
|
130
|
-
// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.
|
|
131
|
-
// Not taking it into account, as compression work should help there - compressed payload will be
|
|
132
|
-
// initially stored as base64, and that requires only 2 extra escape characters.
|
|
133
|
-
const socketMessageSize = contentSize + opOverhead * opCount;
|
|
134
|
-
|
|
135
|
-
if (socketMessageSize >= this.options.hardLimit) {
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
115
|
if (this.pendingBatch.length === 0) {
|
|
140
116
|
this.clientSequenceNumber = currentClientSequenceNumber;
|
|
141
117
|
}
|
|
142
118
|
|
|
143
|
-
this.batchContentSize = contentSize;
|
|
144
119
|
this.pendingBatch.push(message);
|
|
145
|
-
return true;
|
|
146
120
|
}
|
|
147
121
|
|
|
148
122
|
public get empty(): boolean {
|
|
@@ -152,16 +126,14 @@ export class BatchManager {
|
|
|
152
126
|
/**
|
|
153
127
|
* Gets the pending batch and clears state for the next batch.
|
|
154
128
|
*/
|
|
155
|
-
public popBatch(batchId?: BatchId):
|
|
156
|
-
const batch:
|
|
129
|
+
public popBatch(batchId?: BatchId): LocalBatch {
|
|
130
|
+
const batch: LocalBatch = {
|
|
157
131
|
messages: this.pendingBatch,
|
|
158
|
-
contentSizeInBytes: this.batchContentSize,
|
|
159
132
|
referenceSequenceNumber: this.referenceSequenceNumber,
|
|
160
133
|
hasReentrantOps: this.hasReentrantOps,
|
|
161
134
|
};
|
|
162
135
|
|
|
163
136
|
this.pendingBatch = [];
|
|
164
|
-
this.batchContentSize = 0;
|
|
165
137
|
this.clientSequenceNumber = undefined;
|
|
166
138
|
this.hasReentrantOps = false;
|
|
167
139
|
|
|
@@ -175,19 +147,20 @@ export class BatchManager {
|
|
|
175
147
|
const startSequenceNumber = this.clientSequenceNumber;
|
|
176
148
|
const startPoint = this.pendingBatch.length;
|
|
177
149
|
return {
|
|
178
|
-
rollback: (process: (message:
|
|
150
|
+
rollback: (process: (message: LocalBatchMessage) => void) => {
|
|
179
151
|
this.clientSequenceNumber = startSequenceNumber;
|
|
180
152
|
const rollbackOpsLifo = this.pendingBatch.splice(startPoint).reverse();
|
|
181
153
|
for (const message of rollbackOpsLifo) {
|
|
182
|
-
this.batchContentSize -= message.contents?.length ?? 0;
|
|
183
154
|
process(message);
|
|
184
155
|
}
|
|
185
156
|
const count = this.pendingBatch.length - startPoint;
|
|
186
157
|
if (count !== 0) {
|
|
187
|
-
throw new LoggingError("Ops generated
|
|
158
|
+
throw new LoggingError("Ops generated during rollback", {
|
|
188
159
|
count,
|
|
189
160
|
...tagData(TelemetryDataTag.UserData, {
|
|
190
|
-
ops: JSON.stringify(
|
|
161
|
+
ops: JSON.stringify(
|
|
162
|
+
this.pendingBatch.slice(startPoint).map((b) => b.serializedOp),
|
|
163
|
+
),
|
|
191
164
|
}),
|
|
192
165
|
});
|
|
193
166
|
}
|
|
@@ -196,7 +169,7 @@ export class BatchManager {
|
|
|
196
169
|
}
|
|
197
170
|
}
|
|
198
171
|
|
|
199
|
-
const addBatchMetadata = (batch:
|
|
172
|
+
const addBatchMetadata = (batch: LocalBatch, batchId?: BatchId): LocalBatch => {
|
|
200
173
|
const batchEnd = batch.messages.length - 1;
|
|
201
174
|
|
|
202
175
|
const firstMsg = batch.messages[0];
|
|
@@ -226,18 +199,6 @@ const addBatchMetadata = (batch: IBatch, batchId?: BatchId): IBatch => {
|
|
|
226
199
|
return batch;
|
|
227
200
|
};
|
|
228
201
|
|
|
229
|
-
/**
|
|
230
|
-
* Estimates the real size in bytes on the socket for a given batch. It assumes that
|
|
231
|
-
* the envelope size (and the size of an empty op) is 200 bytes, taking into account
|
|
232
|
-
* extra overhead from stringification.
|
|
233
|
-
*
|
|
234
|
-
* @param batch - the batch to inspect
|
|
235
|
-
* @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
|
|
236
|
-
*/
|
|
237
|
-
export const estimateSocketSize = (batch: IBatch): number => {
|
|
238
|
-
return batch.contentSizeInBytes + opOverhead * batch.messages.length;
|
|
239
|
-
};
|
|
240
|
-
|
|
241
202
|
export const sequenceNumbersMatch = (
|
|
242
203
|
seqNums: BatchSequenceNumbers,
|
|
243
204
|
otherSeqNums: BatchSequenceNumbers,
|
|
@@ -3,28 +3,71 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IBatchMessage } from "@fluidframework/container-definitions/internal";
|
|
6
|
+
import type { IBatchMessage } from "@fluidframework/container-definitions/internal";
|
|
7
7
|
|
|
8
8
|
import { CompressionAlgorithms } from "../containerRuntime.js";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Batch message
|
|
11
|
+
* Local Batch message, before it is virtualized and sent to the ordering service
|
|
12
12
|
*/
|
|
13
|
-
export
|
|
13
|
+
export interface LocalBatchMessage {
|
|
14
|
+
serializedOp: string;
|
|
15
|
+
metadata?: Record<string, unknown>;
|
|
14
16
|
localOpMetadata?: unknown;
|
|
15
17
|
referenceSequenceNumber: number;
|
|
16
18
|
compression?: CompressionAlgorithms;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Use serializedOp
|
|
22
|
+
*/
|
|
23
|
+
contents?: never; // To ensure we don't leave this one when converting from OutboundBatchMessage
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Virtualized Batch message, on its way out the door to the ordering service
|
|
28
|
+
*/
|
|
29
|
+
export type OutboundBatchMessage = IBatchMessage & {
|
|
30
|
+
localOpMetadata?: unknown;
|
|
31
|
+
referenceSequenceNumber: number;
|
|
32
|
+
compression?: CompressionAlgorithms;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated Use contents
|
|
36
|
+
*/
|
|
37
|
+
serializedOp?: never; // To ensure we don't leave this one when converting from LocalBatchMessage
|
|
17
38
|
};
|
|
18
39
|
|
|
19
40
|
/**
|
|
20
|
-
*
|
|
41
|
+
* A batch of messages we have accumulated locally, but haven't sent to the ordering service yet.
|
|
42
|
+
*/
|
|
43
|
+
export type LocalBatch = IBatch<LocalBatchMessage[]>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A batch of messages that has been virtualized as needed (grouped, compressed, chunked)
|
|
47
|
+
* and is ready to be sent to the ordering service.
|
|
48
|
+
* At the very least, the op contents have been serialized to string.
|
|
21
49
|
*/
|
|
22
|
-
export interface
|
|
50
|
+
export interface OutboundBatch<
|
|
51
|
+
TMessages extends OutboundBatchMessage[] = OutboundBatchMessage[],
|
|
52
|
+
> extends IBatch<TMessages> {
|
|
23
53
|
/**
|
|
24
54
|
* Sum of the in-memory content sizes of all messages in the batch.
|
|
25
55
|
* If the batch is compressed, this number reflects the post-compression size.
|
|
26
56
|
*/
|
|
27
57
|
readonly contentSizeInBytes: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* An {@link OutboundBatch} with exactly one message
|
|
62
|
+
* This type is helpful as Grouping yields this kind of batch, and Compression only operates on this type of batch.
|
|
63
|
+
*/
|
|
64
|
+
export type OutboundSingletonBatch = OutboundBatch<[OutboundBatchMessage]>;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Base batch interface used internally by the runtime.
|
|
68
|
+
* See {@link LocalBatch} and {@link OutboundBatch} for the concrete types.
|
|
69
|
+
*/
|
|
70
|
+
interface IBatch<TMessages extends LocalBatchMessage[] | OutboundBatchMessage[]> {
|
|
28
71
|
/**
|
|
29
72
|
* All the messages in the batch
|
|
30
73
|
*/
|
|
@@ -47,7 +90,7 @@ export interface IBatch<TMessages extends BatchMessage[] = BatchMessage[]> {
|
|
|
47
90
|
}
|
|
48
91
|
|
|
49
92
|
export interface IBatchCheckpoint {
|
|
50
|
-
rollback: (action: (message:
|
|
93
|
+
rollback: (action: (message: LocalBatchMessage) => void) => void;
|
|
51
94
|
}
|
|
52
95
|
|
|
53
96
|
/**
|
package/src/opLifecycle/index.ts
CHANGED
|
@@ -7,19 +7,34 @@ export {
|
|
|
7
7
|
BatchId,
|
|
8
8
|
BatchManager,
|
|
9
9
|
BatchSequenceNumbers,
|
|
10
|
-
estimateSocketSize,
|
|
11
10
|
getEffectiveBatchId,
|
|
12
11
|
generateBatchId,
|
|
13
12
|
IBatchManagerOptions,
|
|
14
13
|
} from "./batchManager.js";
|
|
15
|
-
export {
|
|
14
|
+
export {
|
|
15
|
+
LocalBatch,
|
|
16
|
+
LocalBatchMessage,
|
|
17
|
+
OutboundBatch,
|
|
18
|
+
OutboundBatchMessage,
|
|
19
|
+
OutboundSingletonBatch,
|
|
20
|
+
IBatchCheckpoint,
|
|
21
|
+
IChunkedOp,
|
|
22
|
+
} from "./definitions.js";
|
|
16
23
|
export { DuplicateBatchDetector } from "./duplicateBatchDetector.js";
|
|
17
|
-
export {
|
|
24
|
+
export {
|
|
25
|
+
serializeOp,
|
|
26
|
+
ensureContentsDeserialized,
|
|
27
|
+
} from "./opSerialization.js";
|
|
28
|
+
export {
|
|
29
|
+
estimateSocketSize,
|
|
30
|
+
localBatchToOutboundBatch,
|
|
31
|
+
Outbox,
|
|
32
|
+
getLongStack,
|
|
33
|
+
} from "./outbox.js";
|
|
18
34
|
export { OpCompressor } from "./opCompressor.js";
|
|
19
35
|
export { OpDecompressor } from "./opDecompressor.js";
|
|
20
36
|
export { OpSplitter, splitOp, isChunkedMessage } from "./opSplitter.js";
|
|
21
37
|
export {
|
|
22
|
-
ensureContentsDeserialized,
|
|
23
38
|
InboundMessageResult,
|
|
24
39
|
BatchStartInfo,
|
|
25
40
|
RemoteMessageProcessor,
|
|
@@ -7,7 +7,7 @@ import { IsoBuffer } from "@fluid-internal/client-utils";
|
|
|
7
7
|
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
8
8
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
9
9
|
import {
|
|
10
|
-
|
|
10
|
+
DataProcessingError,
|
|
11
11
|
createChildLogger,
|
|
12
12
|
type ITelemetryLoggerExt,
|
|
13
13
|
} from "@fluidframework/telemetry-utils/internal";
|
|
@@ -15,13 +15,14 @@ import { compress } from "lz4js";
|
|
|
15
15
|
|
|
16
16
|
import { CompressionAlgorithms } from "../containerRuntime.js";
|
|
17
17
|
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { type OutboundBatchMessage, type OutboundSingletonBatch } from "./definitions.js";
|
|
19
|
+
import { estimateSocketSize } from "./outbox.js";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* Compresses batches of ops.
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* Compresses batches of ops.
|
|
23
|
+
*
|
|
24
|
+
* @remarks Only single-message batches are supported
|
|
25
|
+
* Use opGroupingManager to group a batch into a singleton batch suitable for compression.
|
|
25
26
|
*/
|
|
26
27
|
export class OpCompressor {
|
|
27
28
|
private readonly logger: ITelemetryLoggerExt;
|
|
@@ -31,14 +32,12 @@ export class OpCompressor {
|
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
|
-
* Combines the contents of the batch into a single JSON string and compresses it, putting
|
|
35
|
-
* the resulting string as the
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* @param batch - The batch to compress
|
|
39
|
-
* @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders
|
|
35
|
+
* Combines the contents of the singleton batch into a single JSON string and compresses it, putting
|
|
36
|
+
* the resulting string as the message contents in place of the original uncompressed payload.
|
|
37
|
+
* @param batch - The batch to compress. Must have only 1 message
|
|
38
|
+
* @returns A singleton batch containing a single compressed message
|
|
40
39
|
*/
|
|
41
|
-
public compressBatch(batch:
|
|
40
|
+
public compressBatch(batch: OutboundSingletonBatch): OutboundSingletonBatch {
|
|
42
41
|
assert(
|
|
43
42
|
batch.contentSizeInBytes > 0 && batch.messages.length === 1,
|
|
44
43
|
0x5a4 /* Batch should not be empty and should contain a single message */,
|
|
@@ -50,7 +49,7 @@ export class OpCompressor {
|
|
|
50
49
|
const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
|
|
51
50
|
const duration = Date.now() - compressionStart;
|
|
52
51
|
|
|
53
|
-
const messages: [
|
|
52
|
+
const messages: [OutboundBatchMessage] = [
|
|
54
53
|
{
|
|
55
54
|
...batch.messages[0],
|
|
56
55
|
contents: JSON.stringify({ packedContents: compressedContent }),
|
|
@@ -59,7 +58,7 @@ export class OpCompressor {
|
|
|
59
58
|
},
|
|
60
59
|
];
|
|
61
60
|
|
|
62
|
-
const compressedBatch = {
|
|
61
|
+
const compressedBatch: OutboundSingletonBatch = {
|
|
63
62
|
contentSizeInBytes: compressedContent.length,
|
|
64
63
|
messages,
|
|
65
64
|
referenceSequenceNumber: batch.referenceSequenceNumber,
|
|
@@ -82,27 +81,29 @@ export class OpCompressor {
|
|
|
82
81
|
/**
|
|
83
82
|
* Combine the batch's content strings into a single JSON string (a serialized array)
|
|
84
83
|
*/
|
|
85
|
-
private serializeBatchContents(batch:
|
|
84
|
+
private serializeBatchContents(batch: OutboundSingletonBatch): string {
|
|
85
|
+
const [message, ...none] = batch.messages;
|
|
86
|
+
assert(none.length === 0, 0xb78 /* Batch should only contain a single message */);
|
|
86
87
|
try {
|
|
87
|
-
//
|
|
88
|
-
return `[${
|
|
89
|
-
} catch (
|
|
90
|
-
if ((
|
|
91
|
-
// This is how
|
|
88
|
+
// This is expressed as a JSON array, for legacy reasons
|
|
89
|
+
return `[${message.contents}]`;
|
|
90
|
+
} catch (error: unknown) {
|
|
91
|
+
if ((error as Partial<Error>).message === "Invalid string length") {
|
|
92
|
+
// This is how string interpolation signals that
|
|
92
93
|
// the content size exceeds its capacity
|
|
93
|
-
const
|
|
94
|
+
const dpe = DataProcessingError.create("Payload too large", "OpCompressor");
|
|
94
95
|
this.logger.sendErrorEvent(
|
|
95
96
|
{
|
|
96
97
|
eventName: "BatchTooLarge",
|
|
97
98
|
size: batch.contentSizeInBytes,
|
|
98
99
|
length: batch.messages.length,
|
|
99
100
|
},
|
|
100
|
-
|
|
101
|
+
dpe,
|
|
101
102
|
);
|
|
102
|
-
throw
|
|
103
|
+
throw dpe;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
throw
|
|
106
|
+
throw error;
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
}
|
|
@@ -11,7 +11,11 @@ import {
|
|
|
11
11
|
type ITelemetryLoggerExt,
|
|
12
12
|
} from "@fluidframework/telemetry-utils/internal";
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
type OutboundBatch,
|
|
16
|
+
type OutboundBatchMessage,
|
|
17
|
+
type OutboundSingletonBatch,
|
|
18
|
+
} from "./definitions.js";
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* Grouping makes assumptions about the shape of message contents. This interface codifies those assumptions, but does not validate them.
|
|
@@ -58,44 +62,51 @@ export class OpGroupingManager {
|
|
|
58
62
|
* This is needed as a placeholder if a batch becomes empty on resubmit, but we are tracking batch IDs.
|
|
59
63
|
* @param resubmittingBatchId - batch ID of the resubmitting batch
|
|
60
64
|
* @param referenceSequenceNumber - reference sequence number
|
|
61
|
-
* @returns -
|
|
65
|
+
* @returns - The outbound batch as well as the interior placeholder message
|
|
62
66
|
*/
|
|
63
67
|
public createEmptyGroupedBatch(
|
|
64
68
|
resubmittingBatchId: string,
|
|
65
69
|
referenceSequenceNumber: number,
|
|
66
|
-
):
|
|
70
|
+
): { outboundBatch: OutboundSingletonBatch; placeholderMessage: OutboundBatchMessage } {
|
|
67
71
|
assert(
|
|
68
72
|
this.config.groupedBatchingEnabled,
|
|
69
73
|
0xa00 /* cannot create empty grouped batch when grouped batching is disabled */,
|
|
70
74
|
);
|
|
71
|
-
const
|
|
75
|
+
const serializedOp = JSON.stringify({
|
|
72
76
|
type: OpGroupingManager.groupedBatchOp,
|
|
73
77
|
contents: [],
|
|
74
78
|
});
|
|
75
79
|
|
|
76
|
-
|
|
80
|
+
const placeholderMessage: OutboundBatchMessage = {
|
|
81
|
+
metadata: { batchId: resubmittingBatchId },
|
|
82
|
+
localOpMetadata: { emptyBatch: true },
|
|
83
|
+
referenceSequenceNumber,
|
|
84
|
+
contents: serializedOp,
|
|
85
|
+
};
|
|
86
|
+
const outboundBatch: OutboundSingletonBatch = {
|
|
77
87
|
contentSizeInBytes: 0,
|
|
78
|
-
messages: [
|
|
79
|
-
{
|
|
80
|
-
metadata: { batchId: resubmittingBatchId },
|
|
81
|
-
localOpMetadata: { emptyBatch: true },
|
|
82
|
-
referenceSequenceNumber,
|
|
83
|
-
contents: serializedContent,
|
|
84
|
-
},
|
|
85
|
-
],
|
|
88
|
+
messages: [placeholderMessage],
|
|
86
89
|
referenceSequenceNumber,
|
|
87
90
|
};
|
|
91
|
+
return { outboundBatch, placeholderMessage };
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
/**
|
|
91
95
|
* Converts the given batch into a "grouped batch" - a batch with a single message of type "groupedBatch",
|
|
92
96
|
* with contents being an array of the original batch's messages.
|
|
93
97
|
*
|
|
98
|
+
* If the batch already has only 1 message, it is returned as-is.
|
|
99
|
+
*
|
|
94
100
|
* @remarks - Remember that a BatchMessage has its content JSON serialized, so the incoming batch message contents
|
|
95
101
|
* must be parsed first, and then the type and contents mentioned above are hidden in that JSON serialization.
|
|
96
102
|
*/
|
|
97
|
-
public groupBatch(batch:
|
|
98
|
-
assert(this.
|
|
103
|
+
public groupBatch(batch: OutboundBatch): OutboundSingletonBatch {
|
|
104
|
+
assert(this.groupedBatchingEnabled(), 0xb79 /* grouping disabled! */);
|
|
105
|
+
assert(batch.messages.length > 0, 0xb7a /* Unexpected attempt to group an empty batch */);
|
|
106
|
+
|
|
107
|
+
if (batch.messages.length === 1) {
|
|
108
|
+
return batch as OutboundSingletonBatch;
|
|
109
|
+
}
|
|
99
110
|
|
|
100
111
|
if (batch.messages.length >= 1000) {
|
|
101
112
|
this.logger.sendTelemetryEvent({
|
|
@@ -126,7 +137,7 @@ export class OpGroupingManager {
|
|
|
126
137
|
})),
|
|
127
138
|
});
|
|
128
139
|
|
|
129
|
-
const groupedBatch:
|
|
140
|
+
const groupedBatch: OutboundSingletonBatch = {
|
|
130
141
|
...batch,
|
|
131
142
|
messages: [
|
|
132
143
|
{
|
|
@@ -153,16 +164,6 @@ export class OpGroupingManager {
|
|
|
153
164
|
}));
|
|
154
165
|
}
|
|
155
166
|
|
|
156
|
-
public shouldGroup(batch: IBatch): boolean {
|
|
157
|
-
return (
|
|
158
|
-
// Grouped batching must be enabled
|
|
159
|
-
this.config.groupedBatchingEnabled &&
|
|
160
|
-
// The number of ops in the batch must be 2 or more
|
|
161
|
-
// or be empty (to allow for empty batches to be grouped)
|
|
162
|
-
batch.messages.length !== 1
|
|
163
|
-
// Support for reentrant batches will be on by default
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
167
|
public groupedBatchingEnabled(): boolean {
|
|
167
168
|
return this.config.groupedBatchingEnabled;
|
|
168
169
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
|
|
7
|
+
import {
|
|
8
|
+
encodeHandleForSerialization,
|
|
9
|
+
isFluidHandle,
|
|
10
|
+
toFluidHandleInternal,
|
|
11
|
+
} from "@fluidframework/runtime-utils/internal";
|
|
12
|
+
|
|
13
|
+
import type { LocalContainerRuntimeMessage } from "../messageTypes.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Takes an incoming runtime message (outer type "op"), JSON.parses the message's contents in place,
|
|
17
|
+
* if needed (old Loader does this for us).
|
|
18
|
+
* Only to be used for runtime messages. The contents here would be the virtualized payload for a batch of ops.
|
|
19
|
+
* @remarks - Serialization during submit happens via {@link serializeOp}
|
|
20
|
+
* @param mutableMessage - op message received
|
|
21
|
+
*/
|
|
22
|
+
export function ensureContentsDeserialized(mutableMessage: ISequencedDocumentMessage): void {
|
|
23
|
+
// This should become unconditional once Loader LTS reaches 2.4 or later.
|
|
24
|
+
// There will be a long time of needing both cases, until LTS advances to that point.
|
|
25
|
+
if (typeof mutableMessage.contents === "string" && mutableMessage.contents !== "") {
|
|
26
|
+
mutableMessage.contents = JSON.parse(mutableMessage.contents);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Before submitting an op to the Outbox, its contents must be serialized using this function.
|
|
32
|
+
* @remarks - The deserialization on process happens via the function {@link ensureContentsDeserialized}.
|
|
33
|
+
*/
|
|
34
|
+
export function serializeOp(op: LocalContainerRuntimeMessage): string {
|
|
35
|
+
return JSON.stringify(
|
|
36
|
+
op,
|
|
37
|
+
// replacer:
|
|
38
|
+
(key, value: unknown) => {
|
|
39
|
+
// If 'value' is an IFluidHandle return its encoded form.
|
|
40
|
+
if (isFluidHandle(value)) {
|
|
41
|
+
return encodeHandleForSerialization(toFluidHandleInternal(value));
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
}
|