@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
|
@@ -16,8 +16,12 @@ import {
|
|
|
16
16
|
|
|
17
17
|
import { ContainerMessageType, ContainerRuntimeChunkedOpMessage } from "../messageTypes.js";
|
|
18
18
|
|
|
19
|
-
import {
|
|
20
|
-
|
|
19
|
+
import {
|
|
20
|
+
IChunkedOp,
|
|
21
|
+
type OutboundBatchMessage,
|
|
22
|
+
type OutboundSingletonBatch,
|
|
23
|
+
} from "./definitions.js";
|
|
24
|
+
import { estimateSocketSize } from "./outbox.js";
|
|
21
25
|
|
|
22
26
|
export function isChunkedMessage(message: ISequencedDocumentMessage): boolean {
|
|
23
27
|
return isChunkedContents(message.contents);
|
|
@@ -96,8 +100,8 @@ export class OpSplitter {
|
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
103
|
+
* Takes a singleton batch, and splits the interior message into chunks, sending the chunks separately and
|
|
104
|
+
* returning a new singleton batch containing the last chunk.
|
|
101
105
|
*
|
|
102
106
|
* A compressed batch is formed by one large op at the first position.
|
|
103
107
|
*
|
|
@@ -108,21 +112,20 @@ export class OpSplitter {
|
|
|
108
112
|
* This will ensure that the batch semantics of the original (non-compressed) batch are preserved, as the original chunked op
|
|
109
113
|
* will be unrolled by the runtime when the first message in the batch is processed (as it is the last chunk).
|
|
110
114
|
*
|
|
111
|
-
* To handle legacy compressed batches with empty placeholders this method can attach the empty placeholder ops at the end
|
|
112
|
-
* of the result batch, ensuring that the batch semantics are preserved.
|
|
113
|
-
*
|
|
114
115
|
* To illustrate the current functionality, if the input is `[largeOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
|
|
115
116
|
* `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4]` will be returned.
|
|
116
117
|
*
|
|
117
|
-
* With the legacy code, if the input is `[largeOp, emptyOp, emptyOp]`, `largeOp` will be split into `[chunk1, chunk2, chunk3, chunk4]`.
|
|
118
|
-
* `chunk1`, `chunk2` and `chunk3` will be sent individually and `[chunk4, emptyOp, emptyOp]` will be returned.
|
|
119
|
-
*
|
|
120
118
|
* @remarks - A side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
|
|
121
119
|
*
|
|
122
|
-
* @
|
|
123
|
-
*
|
|
120
|
+
* @privateRemarks
|
|
121
|
+
* This maintains support for splitting a compressed batch with multiple messages (empty placeholders after the first),
|
|
122
|
+
* but this is only used for Unit Tests so the typing has been updated to preclude that.
|
|
123
|
+
* That code should be moved out of this function into a test helper.
|
|
124
|
+
*
|
|
125
|
+
* @param batch - the compressed batch which needs to be split into chunks before being sent over the wire
|
|
126
|
+
* @returns A batch with the last chunk in place of the original complete compressed content
|
|
124
127
|
*/
|
|
125
|
-
public
|
|
128
|
+
public splitSingletonBatchMessage(batch: OutboundSingletonBatch): OutboundSingletonBatch {
|
|
126
129
|
assert(this.isBatchChunkingEnabled, 0x513 /* Chunking needs to be enabled */);
|
|
127
130
|
assert(
|
|
128
131
|
batch.contentSizeInBytes > 0 && batch.messages.length > 0,
|
|
@@ -138,13 +141,14 @@ export class OpSplitter {
|
|
|
138
141
|
0x516 /* Chunk size needs to be smaller than the max batch size */,
|
|
139
142
|
);
|
|
140
143
|
|
|
141
|
-
|
|
144
|
+
// first message is the large compressed op to split, and we expect restOfMessages to be empty
|
|
145
|
+
// (but we keep it here to support a legacy test case, wherein it contains empty placeholder messages)
|
|
146
|
+
const [firstMessage, ...restOfMessages] = batch.messages;
|
|
142
147
|
assert(
|
|
143
148
|
(firstMessage.contents?.length ?? 0) >= this.chunkSizeInBytes,
|
|
144
149
|
0x518 /* First message in the batch needs to be chunkable */,
|
|
145
150
|
);
|
|
146
151
|
|
|
147
|
-
const restOfMessages = batch.messages.slice(1); // we expect these to be empty ops, created to reserve sequence numbers
|
|
148
152
|
const socketSize = estimateSocketSize(batch);
|
|
149
153
|
const chunks = splitOp(
|
|
150
154
|
firstMessage,
|
|
@@ -243,7 +247,7 @@ const chunkToBatchMessage = (
|
|
|
243
247
|
chunk: IChunkedOp,
|
|
244
248
|
referenceSequenceNumber: number,
|
|
245
249
|
metadata: Record<string, unknown> | undefined = undefined,
|
|
246
|
-
):
|
|
250
|
+
): OutboundBatchMessage => {
|
|
247
251
|
const payload: ContainerRuntimeChunkedOpMessage = {
|
|
248
252
|
type: ContainerMessageType.ChunkedOp,
|
|
249
253
|
contents: chunk,
|
|
@@ -268,7 +272,7 @@ const chunkToBatchMessage = (
|
|
|
268
272
|
* @returns an array of chunked ops
|
|
269
273
|
*/
|
|
270
274
|
export const splitOp = (
|
|
271
|
-
op:
|
|
275
|
+
op: OutboundBatchMessage,
|
|
272
276
|
chunkSizeInBytes: number,
|
|
273
277
|
extraOp: boolean = false,
|
|
274
278
|
): IChunkedOp[] => {
|
|
@@ -3,35 +3,40 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
7
6
|
import { IBatchMessage } from "@fluidframework/container-definitions/internal";
|
|
8
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
ITelemetryBaseLogger,
|
|
9
|
+
type ITelemetryBaseProperties,
|
|
10
|
+
} from "@fluidframework/core-interfaces";
|
|
9
11
|
import { assert, Lazy } from "@fluidframework/core-utils/internal";
|
|
10
12
|
import {
|
|
11
13
|
DataProcessingError,
|
|
12
|
-
GenericError,
|
|
13
14
|
UsageError,
|
|
14
15
|
createChildLogger,
|
|
16
|
+
type IFluidErrorBase,
|
|
15
17
|
type ITelemetryLoggerExt,
|
|
16
18
|
} from "@fluidframework/telemetry-utils/internal";
|
|
17
19
|
|
|
18
20
|
import { ICompressionRuntimeOptions } from "../containerRuntime.js";
|
|
19
|
-
import { OutboundContainerRuntimeMessage } from "../messageTypes.js";
|
|
20
21
|
import { PendingMessageResubmitData, PendingStateManager } from "../pendingStateManager.js";
|
|
21
22
|
|
|
22
23
|
import {
|
|
23
24
|
BatchManager,
|
|
24
25
|
BatchSequenceNumbers,
|
|
25
|
-
estimateSocketSize,
|
|
26
26
|
sequenceNumbersMatch,
|
|
27
27
|
type BatchId,
|
|
28
28
|
} from "./batchManager.js";
|
|
29
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
LocalBatchMessage,
|
|
31
|
+
IBatchCheckpoint,
|
|
32
|
+
type OutboundBatchMessage,
|
|
33
|
+
type OutboundSingletonBatch,
|
|
34
|
+
type LocalBatch,
|
|
35
|
+
type OutboundBatch,
|
|
36
|
+
} from "./definitions.js";
|
|
30
37
|
import { OpCompressor } from "./opCompressor.js";
|
|
31
38
|
import { OpGroupingManager } from "./opGroupingManager.js";
|
|
32
39
|
import { OpSplitter } from "./opSplitter.js";
|
|
33
|
-
// eslint-disable-next-line unused-imports/no-unused-imports -- Used by "@link" comment annotation below
|
|
34
|
-
import { ensureContentsDeserialized } from "./remoteMessageProcessor.js";
|
|
35
40
|
|
|
36
41
|
export interface IOutboxConfig {
|
|
37
42
|
readonly compressionOptions: ICompressionRuntimeOptions;
|
|
@@ -53,7 +58,7 @@ export interface IOutboxParameters {
|
|
|
53
58
|
readonly submitBatchFn:
|
|
54
59
|
| ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)
|
|
55
60
|
| undefined;
|
|
56
|
-
readonly legacySendBatchFn: (batch:
|
|
61
|
+
readonly legacySendBatchFn: (batch: OutboundBatch) => number;
|
|
57
62
|
readonly config: IOutboxConfig;
|
|
58
63
|
readonly compressor: OpCompressor;
|
|
59
64
|
readonly splitter: OpSplitter;
|
|
@@ -62,15 +67,6 @@ export interface IOutboxParameters {
|
|
|
62
67
|
readonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;
|
|
63
68
|
readonly reSubmit: (message: PendingMessageResubmitData) => void;
|
|
64
69
|
readonly opReentrancy: () => boolean;
|
|
65
|
-
readonly closeContainer: (error?: ICriticalContainerError) => void;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Before submitting an op to the Outbox, its contents must be serialized using this function.
|
|
70
|
-
* @remarks - The deserialization on process happens via the function {@link ensureContentsDeserialized}.
|
|
71
|
-
*/
|
|
72
|
-
export function serializeOpContents(contents: OutboundContainerRuntimeMessage): string {
|
|
73
|
-
return JSON.stringify(contents);
|
|
74
70
|
}
|
|
75
71
|
|
|
76
72
|
/**
|
|
@@ -112,6 +108,55 @@ export function getLongStack<T>(action: () => T, length: number = 50): T {
|
|
|
112
108
|
}
|
|
113
109
|
}
|
|
114
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Convert from local batch to outbound batch, including computing contentSizeInBytes.
|
|
113
|
+
*/
|
|
114
|
+
export function localBatchToOutboundBatch(localBatch: LocalBatch): OutboundBatch {
|
|
115
|
+
// Shallow copy each message as we switch types
|
|
116
|
+
const outboundMessages = localBatch.messages.map<OutboundBatchMessage>(
|
|
117
|
+
({ serializedOp, ...message }) => ({
|
|
118
|
+
contents: serializedOp,
|
|
119
|
+
...message,
|
|
120
|
+
}),
|
|
121
|
+
);
|
|
122
|
+
const contentSizeInBytes = outboundMessages.reduce(
|
|
123
|
+
(acc, message) => acc + (message.contents?.length ?? 0),
|
|
124
|
+
0,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// Shallow copy the local batch, updating the messages to be outbound messages and adding contentSizeInBytes
|
|
128
|
+
const outboundBatch: OutboundBatch = {
|
|
129
|
+
...localBatch,
|
|
130
|
+
messages: outboundMessages,
|
|
131
|
+
contentSizeInBytes,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
return outboundBatch;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Estimated size of the stringification overhead for an op accumulated
|
|
139
|
+
* from runtime to loader to the service.
|
|
140
|
+
*/
|
|
141
|
+
const opOverhead = 200;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Estimates the real size in bytes on the socket for a given batch. It assumes that
|
|
145
|
+
* the envelope size (and the size of an empty op) is 200 bytes, taking into account
|
|
146
|
+
* extra overhead from stringification.
|
|
147
|
+
*
|
|
148
|
+
* @remarks
|
|
149
|
+
* Also content will be stringified, and that adds a lot of overhead due to a lot of escape characters.
|
|
150
|
+
* Not taking it into account, as compression work should help there - compressed payload will be
|
|
151
|
+
* initially stored as base64, and that requires only 2 extra escape characters.
|
|
152
|
+
*
|
|
153
|
+
* @param batch - the batch to inspect
|
|
154
|
+
* @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
|
|
155
|
+
*/
|
|
156
|
+
export const estimateSocketSize = (batch: OutboundBatch): number => {
|
|
157
|
+
return batch.contentSizeInBytes + opOverhead * batch.messages.length;
|
|
158
|
+
};
|
|
159
|
+
|
|
115
160
|
/**
|
|
116
161
|
* The Outbox collects messages submitted by the ContainerRuntime into a batch,
|
|
117
162
|
* and then flushes the batch when requested.
|
|
@@ -139,18 +184,9 @@ export class Outbox {
|
|
|
139
184
|
constructor(private readonly params: IOutboxParameters) {
|
|
140
185
|
this.logger = createChildLogger({ logger: params.logger, namespace: "Outbox" });
|
|
141
186
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
Number.POSITIVE_INFINITY;
|
|
145
|
-
// We need to allow infinite size batches if we enable compression
|
|
146
|
-
const hardLimit = isCompressionEnabled
|
|
147
|
-
? Number.POSITIVE_INFINITY
|
|
148
|
-
: this.params.config.maxBatchSizeInBytes;
|
|
149
|
-
|
|
150
|
-
this.mainBatch = new BatchManager({ hardLimit, canRebase: true });
|
|
151
|
-
this.blobAttachBatch = new BatchManager({ hardLimit, canRebase: true });
|
|
187
|
+
this.mainBatch = new BatchManager({ canRebase: true });
|
|
188
|
+
this.blobAttachBatch = new BatchManager({ canRebase: true });
|
|
152
189
|
this.idAllocationBatch = new BatchManager({
|
|
153
|
-
hardLimit,
|
|
154
190
|
canRebase: false,
|
|
155
191
|
ignoreBatchId: true,
|
|
156
192
|
});
|
|
@@ -258,53 +294,48 @@ export class Outbox {
|
|
|
258
294
|
throw errorWrapper.value;
|
|
259
295
|
}
|
|
260
296
|
|
|
261
|
-
public submit(message:
|
|
297
|
+
public submit(message: LocalBatchMessage): void {
|
|
262
298
|
this.maybeFlushPartialBatch();
|
|
263
299
|
|
|
264
300
|
this.addMessageToBatchManager(this.mainBatch, message);
|
|
265
301
|
}
|
|
266
302
|
|
|
267
|
-
public submitBlobAttach(message:
|
|
303
|
+
public submitBlobAttach(message: LocalBatchMessage): void {
|
|
268
304
|
this.maybeFlushPartialBatch();
|
|
269
305
|
|
|
270
306
|
this.addMessageToBatchManager(this.blobAttachBatch, message);
|
|
271
307
|
}
|
|
272
308
|
|
|
273
|
-
public submitIdAllocation(message:
|
|
309
|
+
public submitIdAllocation(message: LocalBatchMessage): void {
|
|
274
310
|
this.maybeFlushPartialBatch();
|
|
275
311
|
|
|
276
312
|
this.addMessageToBatchManager(this.idAllocationBatch, message);
|
|
277
313
|
}
|
|
278
314
|
|
|
279
|
-
private addMessageToBatchManager(
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
opSize: message.contents?.length ?? 0,
|
|
289
|
-
batchSize: batchManager.contentSizeInBytes,
|
|
290
|
-
count: batchManager.length,
|
|
291
|
-
limit: batchManager.options.hardLimit,
|
|
292
|
-
});
|
|
293
|
-
}
|
|
315
|
+
private addMessageToBatchManager(
|
|
316
|
+
batchManager: BatchManager,
|
|
317
|
+
message: LocalBatchMessage,
|
|
318
|
+
): void {
|
|
319
|
+
batchManager.push(
|
|
320
|
+
message,
|
|
321
|
+
this.isContextReentrant(),
|
|
322
|
+
this.params.getCurrentSequenceNumbers().clientSequenceNumber,
|
|
323
|
+
);
|
|
294
324
|
}
|
|
295
325
|
|
|
296
326
|
/**
|
|
297
327
|
* Flush all the batches to the ordering service.
|
|
298
328
|
* This method is expected to be called at the end of a batch.
|
|
329
|
+
*
|
|
330
|
+
* @throws If called from a reentrant context, or if the batch being flushed is too large.
|
|
299
331
|
* @param resubmittingBatchId - If defined, indicates this is a resubmission of a batch
|
|
300
332
|
* with the given Batch ID, which must be preserved
|
|
301
333
|
*/
|
|
302
334
|
public flush(resubmittingBatchId?: BatchId): void {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}
|
|
335
|
+
assert(
|
|
336
|
+
!this.isContextReentrant(),
|
|
337
|
+
0xb7b /* Flushing must not happen while incoming changes are being processed */,
|
|
338
|
+
);
|
|
308
339
|
|
|
309
340
|
this.flushAll(resubmittingBatchId);
|
|
310
341
|
}
|
|
@@ -346,16 +377,19 @@ export class Outbox {
|
|
|
346
377
|
referenceSequenceNumber !== undefined,
|
|
347
378
|
0xa01 /* reference sequence number should be defined */,
|
|
348
379
|
);
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
380
|
+
const { outboundBatch, placeholderMessage } =
|
|
381
|
+
this.params.groupingManager.createEmptyGroupedBatch(
|
|
382
|
+
resubmittingBatchId,
|
|
383
|
+
referenceSequenceNumber,
|
|
384
|
+
);
|
|
353
385
|
let clientSequenceNumber: number | undefined;
|
|
354
386
|
if (this.params.shouldSend()) {
|
|
355
|
-
clientSequenceNumber = this.sendBatch(
|
|
387
|
+
clientSequenceNumber = this.sendBatch(outboundBatch);
|
|
356
388
|
}
|
|
389
|
+
|
|
390
|
+
// Push the empty batch placeholder to the PendingStateManager
|
|
357
391
|
this.params.pendingStateManager.onFlushBatch(
|
|
358
|
-
|
|
392
|
+
[{ ...placeholderMessage, serializedOp: "", contents: undefined }], // placeholder message - serializedOp will never be used
|
|
359
393
|
clientSequenceNumber,
|
|
360
394
|
);
|
|
361
395
|
return;
|
|
@@ -371,9 +405,16 @@ export class Outbox {
|
|
|
371
405
|
}
|
|
372
406
|
|
|
373
407
|
const rawBatch = batchManager.popBatch(resubmittingBatchId);
|
|
374
|
-
const
|
|
375
|
-
!disableGroupedBatching && this.params.groupingManager.
|
|
376
|
-
if (
|
|
408
|
+
const groupingEnabled =
|
|
409
|
+
!disableGroupedBatching && this.params.groupingManager.groupedBatchingEnabled();
|
|
410
|
+
if (
|
|
411
|
+
batchManager.options.canRebase &&
|
|
412
|
+
rawBatch.hasReentrantOps === true &&
|
|
413
|
+
// NOTE: This is too restrictive. We should rebase for any reentrant op, not just if it's going to be a grouped batch
|
|
414
|
+
// However there is some test that is depending on this behavior so we haven't removed these conditions yet. See AB#33427
|
|
415
|
+
groupingEnabled &&
|
|
416
|
+
rawBatch.messages.length > 1
|
|
417
|
+
) {
|
|
377
418
|
assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
|
|
378
419
|
// If a batch contains reentrant ops (ops created as a result from processing another op)
|
|
379
420
|
// it needs to be rebased so that we can ensure consistent reference sequence numbers
|
|
@@ -387,12 +428,9 @@ export class Outbox {
|
|
|
387
428
|
// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.
|
|
388
429
|
// Because flush() is a task that executes async (on clean stack), we can get here in disconnected state.
|
|
389
430
|
if (this.params.shouldSend()) {
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
shouldGroup ? this.params.groupingManager.groupBatch(rawBatch) : rawBatch,
|
|
394
|
-
);
|
|
395
|
-
clientSequenceNumber = this.sendBatch(processedBatch);
|
|
431
|
+
const virtualizedBatch = this.virtualizeBatch(rawBatch, groupingEnabled);
|
|
432
|
+
|
|
433
|
+
clientSequenceNumber = this.sendBatch(virtualizedBatch);
|
|
396
434
|
assert(
|
|
397
435
|
clientSequenceNumber === undefined || clientSequenceNumber >= 0,
|
|
398
436
|
0x9d2 /* unexpected negative clientSequenceNumber (empty batch should yield undefined) */,
|
|
@@ -412,15 +450,14 @@ export class Outbox {
|
|
|
412
450
|
*
|
|
413
451
|
* @param rawBatch - the batch to be rebased
|
|
414
452
|
*/
|
|
415
|
-
private rebase(rawBatch:
|
|
453
|
+
private rebase(rawBatch: LocalBatch, batchManager: BatchManager): void {
|
|
416
454
|
assert(!this.rebasing, 0x6fb /* Reentrancy */);
|
|
417
455
|
assert(batchManager.options.canRebase, 0x9a7 /* BatchManager does not support rebase */);
|
|
418
456
|
|
|
419
457
|
this.rebasing = true;
|
|
420
458
|
for (const message of rawBatch.messages) {
|
|
421
459
|
this.params.reSubmit({
|
|
422
|
-
|
|
423
|
-
content: message.contents!,
|
|
460
|
+
content: message.serializedOp,
|
|
424
461
|
localOpMetadata: message.localOpMetadata,
|
|
425
462
|
opMetadata: message.metadata,
|
|
426
463
|
});
|
|
@@ -447,44 +484,56 @@ export class Outbox {
|
|
|
447
484
|
}
|
|
448
485
|
|
|
449
486
|
/**
|
|
450
|
-
* As necessary and enabled, compresses
|
|
487
|
+
* As necessary and enabled, groups / compresses / chunks the given batch.
|
|
451
488
|
*
|
|
452
489
|
* @remarks - If chunking happens, a side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
|
|
453
490
|
*
|
|
454
|
-
* @param
|
|
455
|
-
* @
|
|
456
|
-
*
|
|
491
|
+
* @param localBatch - Local Batch to be virtualized - i.e. transformed into an Outbound Batch
|
|
492
|
+
* @param groupingEnabled - If true, Grouped batching is enabled.
|
|
493
|
+
* @returns One of the following:
|
|
494
|
+
* - (A) The original batch (Based on what's enabled)
|
|
495
|
+
* - (B) A grouped batch (it's a singleton batch)
|
|
496
|
+
* - (C) A compressed singleton batch
|
|
497
|
+
* - (D) A singleton batch containing the last chunk.
|
|
457
498
|
*/
|
|
458
|
-
private
|
|
499
|
+
private virtualizeBatch(localBatch: LocalBatch, groupingEnabled: boolean): OutboundBatch {
|
|
500
|
+
// Shallow copy the local batch, updating the messages to be outbound messages
|
|
501
|
+
const originalBatch = localBatchToOutboundBatch(localBatch);
|
|
502
|
+
|
|
503
|
+
const originalOrGroupedBatch = groupingEnabled
|
|
504
|
+
? this.params.groupingManager.groupBatch(originalBatch)
|
|
505
|
+
: originalBatch;
|
|
506
|
+
|
|
507
|
+
if (originalOrGroupedBatch.messages.length !== 1) {
|
|
508
|
+
// Compression requires a single message, so return early otherwise.
|
|
509
|
+
return originalOrGroupedBatch;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// Regardless of whether we grouped or not, we now have a batch with a single message.
|
|
513
|
+
// Now proceed to compress/chunk it if necessary.
|
|
514
|
+
const singletonBatch = originalOrGroupedBatch as OutboundSingletonBatch;
|
|
515
|
+
|
|
459
516
|
if (
|
|
460
|
-
batch.messages.length === 0 ||
|
|
461
|
-
this.params.config.compressionOptions === undefined ||
|
|
462
517
|
this.params.config.compressionOptions.minimumBatchSizeInBytes >
|
|
463
|
-
|
|
464
|
-
this.params.submitBatchFn === undefined
|
|
465
|
-
!this.params.groupingManager.groupedBatchingEnabled()
|
|
518
|
+
singletonBatch.contentSizeInBytes ||
|
|
519
|
+
this.params.submitBatchFn === undefined
|
|
466
520
|
) {
|
|
467
|
-
// Nothing to do if
|
|
468
|
-
return
|
|
521
|
+
// Nothing to do if compression is disabled, unnecessary or unsupported.
|
|
522
|
+
return singletonBatch;
|
|
469
523
|
}
|
|
470
524
|
|
|
471
|
-
const compressedBatch = this.params.compressor.compressBatch(
|
|
525
|
+
const compressedBatch = this.params.compressor.compressBatch(singletonBatch);
|
|
472
526
|
|
|
473
527
|
if (this.params.splitter.isBatchChunkingEnabled) {
|
|
474
528
|
return compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes
|
|
475
529
|
? compressedBatch
|
|
476
|
-
: this.params.splitter.
|
|
530
|
+
: this.params.splitter.splitSingletonBatchMessage(compressedBatch);
|
|
477
531
|
}
|
|
478
532
|
|
|
533
|
+
// We want to distinguish this "BatchTooLarge" case from the generic "BatchTooLarge" case in sendBatch
|
|
479
534
|
if (compressedBatch.contentSizeInBytes >= this.params.config.maxBatchSizeInBytes) {
|
|
480
|
-
throw
|
|
481
|
-
|
|
482
|
-
compressedBatchSize: compressedBatch.contentSizeInBytes,
|
|
483
|
-
count: compressedBatch.messages.length,
|
|
484
|
-
limit: this.params.config.maxBatchSizeInBytes,
|
|
485
|
-
chunkingEnabled: this.params.splitter.isBatchChunkingEnabled,
|
|
486
|
-
compressionOptions: JSON.stringify(this.params.config.compressionOptions),
|
|
487
|
-
socketSize: estimateSocketSize(batch),
|
|
535
|
+
throw this.makeBatchTooLargeError(compressedBatch, "CompressionInsufficient", {
|
|
536
|
+
uncompressedSizeInBytes: singletonBatch.contentSizeInBytes,
|
|
488
537
|
});
|
|
489
538
|
}
|
|
490
539
|
|
|
@@ -497,7 +546,7 @@ export class Outbox {
|
|
|
497
546
|
* @param batch - batch to be sent
|
|
498
547
|
* @returns the clientSequenceNumber of the start of the batch, or undefined if nothing was sent
|
|
499
548
|
*/
|
|
500
|
-
private sendBatch(batch:
|
|
549
|
+
private sendBatch(batch: OutboundBatch): number | undefined {
|
|
501
550
|
const length = batch.messages.length;
|
|
502
551
|
if (length === 0) {
|
|
503
552
|
return undefined; // Nothing submitted
|
|
@@ -505,12 +554,7 @@ export class Outbox {
|
|
|
505
554
|
|
|
506
555
|
const socketSize = estimateSocketSize(batch);
|
|
507
556
|
if (socketSize >= this.params.config.maxBatchSizeInBytes) {
|
|
508
|
-
this.
|
|
509
|
-
eventName: "LargeBatch",
|
|
510
|
-
length: batch.messages.length,
|
|
511
|
-
sizeInBytes: batch.contentSizeInBytes,
|
|
512
|
-
socketSize,
|
|
513
|
-
});
|
|
557
|
+
throw this.makeBatchTooLargeError(batch, "CannotSend");
|
|
514
558
|
}
|
|
515
559
|
|
|
516
560
|
let clientSequenceNumber: number;
|
|
@@ -542,6 +586,31 @@ export class Outbox {
|
|
|
542
586
|
return clientSequenceNumber;
|
|
543
587
|
}
|
|
544
588
|
|
|
589
|
+
private makeBatchTooLargeError(
|
|
590
|
+
batch: OutboundBatch,
|
|
591
|
+
codepath: string,
|
|
592
|
+
moreDetails?: ITelemetryBaseProperties,
|
|
593
|
+
): IFluidErrorBase {
|
|
594
|
+
return DataProcessingError.create(
|
|
595
|
+
"BatchTooLarge",
|
|
596
|
+
codepath,
|
|
597
|
+
/* sequencedMessage */ undefined,
|
|
598
|
+
{
|
|
599
|
+
errorDetails: {
|
|
600
|
+
opCount: batch.messages.length,
|
|
601
|
+
contentSizeInBytes: batch.contentSizeInBytes,
|
|
602
|
+
socketSize: estimateSocketSize(batch),
|
|
603
|
+
maxBatchSizeInBytes: this.params.config.maxBatchSizeInBytes,
|
|
604
|
+
groupedBatchingEnabled: this.params.groupingManager.groupedBatchingEnabled(),
|
|
605
|
+
compressionOptions: JSON.stringify(this.params.config.compressionOptions),
|
|
606
|
+
chunkingEnabled: this.params.splitter.isBatchChunkingEnabled,
|
|
607
|
+
chunkSizeInBytes: this.params.splitter.chunkSizeInBytes,
|
|
608
|
+
...moreDetails,
|
|
609
|
+
},
|
|
610
|
+
},
|
|
611
|
+
);
|
|
612
|
+
}
|
|
613
|
+
|
|
545
614
|
/**
|
|
546
615
|
* Gets a checkpoint object per batch that facilitates iterating over the batch messages when rolling back.
|
|
547
616
|
*/
|
|
@@ -19,9 +19,6 @@ import { asBatchMetadata } from "../metadata.js";
|
|
|
19
19
|
import { OpDecompressor } from "./opDecompressor.js";
|
|
20
20
|
import { OpGroupingManager, isGroupedBatch } from "./opGroupingManager.js";
|
|
21
21
|
import { OpSplitter, isChunkedMessage } from "./opSplitter.js";
|
|
22
|
-
// eslint-disable-next-line unused-imports/no-unused-imports -- Used by "@link" comment annotation below
|
|
23
|
-
import { serializeOpContents } from "./outbox.js";
|
|
24
|
-
|
|
25
22
|
/**
|
|
26
23
|
* Info about the batch we learn when we process the first message
|
|
27
24
|
*/
|
|
@@ -247,20 +244,6 @@ export class RemoteMessageProcessor {
|
|
|
247
244
|
}
|
|
248
245
|
}
|
|
249
246
|
|
|
250
|
-
/**
|
|
251
|
-
* Takes an incoming runtime message JSON.parse's its contents in place, if needed (old Loader does this for us).
|
|
252
|
-
* Only to be used for runtine messages.
|
|
253
|
-
* @remarks - Serialization during submit happens via {@link serializeOpContents}
|
|
254
|
-
* @param mutableMessage - op message received
|
|
255
|
-
*/
|
|
256
|
-
export function ensureContentsDeserialized(mutableMessage: ISequencedDocumentMessage): void {
|
|
257
|
-
// This should become unconditional once Loader LTS reaches 2.4 or later.
|
|
258
|
-
// There will be a long time of needing both cases, until LTS advances to that point.
|
|
259
|
-
if (typeof mutableMessage.contents === "string" && mutableMessage.contents !== "") {
|
|
260
|
-
mutableMessage.contents = JSON.parse(mutableMessage.contents);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
247
|
/**
|
|
265
248
|
* For a given message, it moves the nested InboundContainerRuntimeMessage props one level up.
|
|
266
249
|
*
|
package/src/packageVersion.ts
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
import { asBatchMetadata, asEmptyBatchLocalOpMetadata } from "./metadata.js";
|
|
24
24
|
import {
|
|
25
25
|
BatchId,
|
|
26
|
-
|
|
26
|
+
LocalBatchMessage,
|
|
27
27
|
getEffectiveBatchId,
|
|
28
28
|
BatchStartInfo,
|
|
29
29
|
InboundMessageResult,
|
|
@@ -305,7 +305,7 @@ export class PendingStateManager implements IDisposable {
|
|
|
305
305
|
* @param ignoreBatchId - Whether to ignore the batchId in the batchStartInfo
|
|
306
306
|
*/
|
|
307
307
|
public onFlushBatch(
|
|
308
|
-
batch:
|
|
308
|
+
batch: LocalBatchMessage[],
|
|
309
309
|
clientSequenceNumber: number | undefined,
|
|
310
310
|
ignoreBatchId?: boolean,
|
|
311
311
|
): void {
|
|
@@ -325,7 +325,7 @@ export class PendingStateManager implements IDisposable {
|
|
|
325
325
|
|
|
326
326
|
for (const message of batch) {
|
|
327
327
|
const {
|
|
328
|
-
|
|
328
|
+
serializedOp: content,
|
|
329
329
|
referenceSequenceNumber,
|
|
330
330
|
localOpMetadata,
|
|
331
331
|
metadata: opMetadata,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type ILayerCompatSupportRequirements,
|
|
10
10
|
} from "@fluid-internal/client-utils";
|
|
11
11
|
import type { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
12
|
+
import { encodeHandlesInContainerRuntime } from "@fluidframework/runtime-definitions/internal";
|
|
12
13
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
13
14
|
|
|
14
15
|
import { pkgVersion } from "./packageVersion.js";
|
|
@@ -63,9 +64,9 @@ export const loaderSupportRequirements: ILayerCompatSupportRequirements = {
|
|
|
63
64
|
export const runtimeCompatDetailsForDataStore: ILayerCompatDetails = {
|
|
64
65
|
...runtimeCoreCompatDetails,
|
|
65
66
|
/**
|
|
66
|
-
* The features supported by the Runtime layer across the Runtime /
|
|
67
|
+
* The features supported by the Runtime layer across the Runtime / DataStore boundary.
|
|
67
68
|
*/
|
|
68
|
-
supportedFeatures: new Set<string>(),
|
|
69
|
+
supportedFeatures: new Set<string>([encodeHandlesInContainerRuntime]),
|
|
69
70
|
};
|
|
70
71
|
|
|
71
72
|
/**
|