@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/dist/messageTypes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messageTypes.js","sourceRoot":"","sources":["../src/messageTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAeH;;;GAGG;AACH,IAAY,oBAoCX;AApCD,WAAY,oBAAoB;IAC/B,iCAAiC;IACjC,sDAA8B,CAAA;IAE9B,sBAAsB;IACtB,yCAAiB,CAAA;IAEjB,qBAAqB;IACrB,+CAAuB,CAAA;IAEvB,yFAAyF;IACzF,iDAAyB,CAAA;IAEzB,oDAAoD;IACpD,yCAAiB,CAAA;IAEjB,sCAAsC;IACtC,uCAAe,CAAA;IAEf;;;;OAIG;IACH,qDAA6B,CAAA;IAE7B;;OAEG;IACH,uDAA+B,CAAA;IAE/B;;;OAGG;IACH,iCAAS,CAAA;AACV,CAAC,EApCW,oBAAoB,oCAApB,oBAAoB,QAoC/B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IdCreationRange } from \"@fluidframework/id-compressor/internal\";\nimport {\n\tIAttachMessage,\n\tIEnvelope,\n\tInboundAttachMessage,\n} from \"@fluidframework/runtime-definitions/internal\";\n\nimport { IDataStoreAliasMessage } from \"./dataStore.js\";\nimport { GarbageCollectionMessage } from \"./gc/index.js\";\nimport { IChunkedOp } from \"./opLifecycle/index.js\";\nimport { IDocumentSchemaChangeMessage } from \"./summary/index.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport enum ContainerMessageType {\n\t// An op to be delivered to store\n\tFluidDataStoreOp = \"component\",\n\n\t// Creates a new store\n\tAttach = \"attach\",\n\n\t// Chunked operation.\n\tChunkedOp = \"chunkedOp\",\n\n\t// Signifies that a blob has been attached and should not be garbage collected by storage\n\tBlobAttach = \"blobAttach\",\n\n\t// Ties our new clientId to our old one on reconnect\n\tRejoin = \"rejoin\",\n\n\t// Sets the alias of a root data store\n\tAlias = \"alias\",\n\n\t/**\n\t * An op containing an IdRange of Ids allocated using the runtime's IdCompressor since\n\t * the last allocation op was sent.\n\t * See the [IdCompressor README](./id-compressor/README.md) for more details.\n\t */\n\tIdAllocation = \"idAllocation\",\n\n\t/**\n\t * An op that changes document schema\n\t */\n\tDocumentSchemaChange = \"schema\",\n\n\t/**\n\t * Garbage collection specific op. This is sent by the summarizer client when GC runs. It's used to synchronize GC\n\t * state across all clients.\n\t */\n\tGC = \"GC\",\n}\n\n/**\n * The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime.\n * Message type are differentiated via a `type` string and contain different contents depending on their type.\n *\n * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.\n * This way stringified values can be compared.\n */\ninterface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> {\n\t/**\n\t * Type of the op, within the ContainerRuntime's domain\n\t */\n\ttype: TType;\n\t/**\n\t * Domain-specific contents, interpreted according to the type\n\t */\n\tcontents: TContents;\n}\n\nexport type ContainerRuntimeDataStoreOpMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.FluidDataStoreOp,\n\tIEnvelope\n>;\nexport type InboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Attach,\n\tInboundAttachMessage\n>;\nexport type OutboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Attach,\n\tIAttachMessage\n>;\nexport type ContainerRuntimeChunkedOpMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.ChunkedOp,\n\tIChunkedOp\n>;\nexport type ContainerRuntimeBlobAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.BlobAttach,\n\tundefined\n>;\nexport type ContainerRuntimeRejoinMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Rejoin,\n\tundefined\n>;\nexport type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Alias,\n\tIDataStoreAliasMessage\n>;\nexport type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.IdAllocation,\n\tIdCreationRange\n>;\nexport type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.GC,\n\tGarbageCollectionMessage\n>;\nexport type ContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.DocumentSchemaChange,\n\tIDocumentSchemaChangeMessage\n>;\n\n/**\n * Represents an unrecognized TypedContainerRuntimeMessage, e.g. a message from a future version of the container runtime.\n * @internal\n */\nexport interface UnknownContainerRuntimeMessage {\n\t/**\n\t * Invalid type of the op, within the ContainerRuntime's domain. This value should never exist at runtime.\n\t * This is useful for type narrowing but should never be used as an actual message type at runtime.\n\t * Actual value will not be \"__unknown...\", but the type `Exclude<string, ContainerMessageType>` is not supported.\n\t */\n\ttype: \"__unknown_container_message_type__never_use_as_value__\";\n\n\t/**\n\t * Domain-specific contents, but not decipherable by an unknown op.\n\t */\n\tcontents: unknown;\n}\n\n/**\n * A {@link TypedContainerRuntimeMessage} that is received from the server and will be processed by the container runtime.\n */\nexport type InboundContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| InboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeChunkedOpMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t// Inbound messages may include unknown types from other clients, so we include that as a special case here\n\t| UnknownContainerRuntimeMessage
|
|
1
|
+
{"version":3,"file":"messageTypes.js","sourceRoot":"","sources":["../src/messageTypes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAeH;;;GAGG;AACH,IAAY,oBAoCX;AApCD,WAAY,oBAAoB;IAC/B,iCAAiC;IACjC,sDAA8B,CAAA;IAE9B,sBAAsB;IACtB,yCAAiB,CAAA;IAEjB,qBAAqB;IACrB,+CAAuB,CAAA;IAEvB,yFAAyF;IACzF,iDAAyB,CAAA;IAEzB,oDAAoD;IACpD,yCAAiB,CAAA;IAEjB,sCAAsC;IACtC,uCAAe,CAAA;IAEf;;;;OAIG;IACH,qDAA6B,CAAA;IAE7B;;OAEG;IACH,uDAA+B,CAAA;IAE/B;;;OAGG;IACH,iCAAS,CAAA;AACV,CAAC,EApCW,oBAAoB,oCAApB,oBAAoB,QAoC/B","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport type { IdCreationRange } from \"@fluidframework/id-compressor/internal\";\nimport {\n\tIAttachMessage,\n\tIEnvelope,\n\tInboundAttachMessage,\n} from \"@fluidframework/runtime-definitions/internal\";\n\nimport { IDataStoreAliasMessage } from \"./dataStore.js\";\nimport { GarbageCollectionMessage } from \"./gc/index.js\";\nimport { IChunkedOp } from \"./opLifecycle/index.js\";\nimport { IDocumentSchemaChangeMessage } from \"./summary/index.js\";\n\n/**\n * @legacy\n * @alpha\n */\nexport enum ContainerMessageType {\n\t// An op to be delivered to store\n\tFluidDataStoreOp = \"component\",\n\n\t// Creates a new store\n\tAttach = \"attach\",\n\n\t// Chunked operation.\n\tChunkedOp = \"chunkedOp\",\n\n\t// Signifies that a blob has been attached and should not be garbage collected by storage\n\tBlobAttach = \"blobAttach\",\n\n\t// Ties our new clientId to our old one on reconnect\n\tRejoin = \"rejoin\",\n\n\t// Sets the alias of a root data store\n\tAlias = \"alias\",\n\n\t/**\n\t * An op containing an IdRange of Ids allocated using the runtime's IdCompressor since\n\t * the last allocation op was sent.\n\t * See the [IdCompressor README](./id-compressor/README.md) for more details.\n\t */\n\tIdAllocation = \"idAllocation\",\n\n\t/**\n\t * An op that changes document schema\n\t */\n\tDocumentSchemaChange = \"schema\",\n\n\t/**\n\t * Garbage collection specific op. This is sent by the summarizer client when GC runs. It's used to synchronize GC\n\t * state across all clients.\n\t */\n\tGC = \"GC\",\n}\n\n/**\n * The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime.\n * Message type are differentiated via a `type` string and contain different contents depending on their type.\n *\n * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.\n * This way stringified values can be compared.\n */\ninterface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> {\n\t/**\n\t * Type of the op, within the ContainerRuntime's domain\n\t */\n\ttype: TType;\n\t/**\n\t * Domain-specific contents, interpreted according to the type\n\t */\n\tcontents: TContents;\n}\n\nexport type ContainerRuntimeDataStoreOpMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.FluidDataStoreOp,\n\tIEnvelope\n>;\nexport type InboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Attach,\n\tInboundAttachMessage\n>;\nexport type OutboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Attach,\n\tIAttachMessage\n>;\nexport type ContainerRuntimeChunkedOpMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.ChunkedOp,\n\tIChunkedOp\n>;\nexport type ContainerRuntimeBlobAttachMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.BlobAttach,\n\tundefined\n>;\nexport type ContainerRuntimeRejoinMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Rejoin,\n\tundefined\n>;\nexport type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.Alias,\n\tIDataStoreAliasMessage\n>;\nexport type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.IdAllocation,\n\tIdCreationRange\n>;\nexport type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.GC,\n\tGarbageCollectionMessage\n>;\nexport type ContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage<\n\tContainerMessageType.DocumentSchemaChange,\n\tIDocumentSchemaChangeMessage\n>;\n\n/**\n * Represents an unrecognized TypedContainerRuntimeMessage, e.g. a message from a future version of the container runtime.\n * @internal\n */\nexport interface UnknownContainerRuntimeMessage {\n\t/**\n\t * Invalid type of the op, within the ContainerRuntime's domain. This value should never exist at runtime.\n\t * This is useful for type narrowing but should never be used as an actual message type at runtime.\n\t * Actual value will not be \"__unknown...\", but the type `Exclude<string, ContainerMessageType>` is not supported.\n\t */\n\ttype: \"__unknown_container_message_type__never_use_as_value__\";\n\n\t/**\n\t * Domain-specific contents, but not decipherable by an unknown op.\n\t */\n\tcontents: unknown;\n}\n\n/**\n * A {@link TypedContainerRuntimeMessage} that is received from the server and will be processed by the container runtime.\n */\nexport type InboundContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| InboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeChunkedOpMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t| ContainerRuntimeDocumentSchemaMessage\n\t// Inbound messages may include unknown types from other clients, so we include that as a special case here\n\t| UnknownContainerRuntimeMessage;\n\n/**\n * A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime, eventually to be sent to the ordering service.\n * These are messages generated by the local runtime, before the outbox's op virtualization step.\n */\nexport type LocalContainerRuntimeMessage =\n\t| ContainerRuntimeDataStoreOpMessage\n\t| OutboundContainerRuntimeAttachMessage\n\t| ContainerRuntimeBlobAttachMessage\n\t| ContainerRuntimeRejoinMessage\n\t| ContainerRuntimeAliasMessage\n\t| ContainerRuntimeIdAllocationMessage\n\t| ContainerRuntimeGCMessage\n\t| ContainerRuntimeDocumentSchemaMessage\n\t// In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type\n\t| UnknownContainerRuntimeMessage;\n\n/**\n * An unpacked ISequencedDocumentMessage with the inner TypedContainerRuntimeMessage type/contents/etc\n * promoted up to the outer object\n */\nexport type InboundSequencedContainerRuntimeMessage = Omit<\n\tISequencedDocumentMessage,\n\t\"type\" | \"contents\"\n> &\n\tInboundContainerRuntimeMessage;\n"]}
|
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { ICompressionRuntimeOptions } from "../containerRuntime.js";
|
|
6
6
|
import type { IPendingMessage } from "../pendingStateManager.js";
|
|
7
|
-
import {
|
|
7
|
+
import { LocalBatchMessage, IBatchCheckpoint, type LocalBatch } from "./definitions.js";
|
|
8
8
|
import type { BatchStartInfo } from "./remoteMessageProcessor.js";
|
|
9
9
|
export interface IBatchManagerOptions {
|
|
10
|
-
readonly hardLimit: number;
|
|
11
10
|
readonly compressionOptions?: ICompressionRuntimeOptions;
|
|
12
11
|
/**
|
|
13
12
|
* If true, the outbox is allowed to rebase the batch during flushing.
|
|
@@ -43,10 +42,8 @@ export declare function getEffectiveBatchId(pendingMessageOrBatchStartInfo: IPen
|
|
|
43
42
|
export declare class BatchManager {
|
|
44
43
|
readonly options: IBatchManagerOptions;
|
|
45
44
|
private pendingBatch;
|
|
46
|
-
private batchContentSize;
|
|
47
45
|
private hasReentrantOps;
|
|
48
46
|
get length(): number;
|
|
49
|
-
get contentSizeInBytes(): number;
|
|
50
47
|
get sequenceNumbers(): BatchSequenceNumbers;
|
|
51
48
|
private get referenceSequenceNumber();
|
|
52
49
|
/**
|
|
@@ -55,25 +52,16 @@ export declare class BatchManager {
|
|
|
55
52
|
*/
|
|
56
53
|
private clientSequenceNumber;
|
|
57
54
|
constructor(options: IBatchManagerOptions);
|
|
58
|
-
push(message:
|
|
55
|
+
push(message: LocalBatchMessage, reentrant: boolean, currentClientSequenceNumber?: number): void;
|
|
59
56
|
get empty(): boolean;
|
|
60
57
|
/**
|
|
61
58
|
* Gets the pending batch and clears state for the next batch.
|
|
62
59
|
*/
|
|
63
|
-
popBatch(batchId?: BatchId):
|
|
60
|
+
popBatch(batchId?: BatchId): LocalBatch;
|
|
64
61
|
/**
|
|
65
62
|
* Capture the pending state at this point
|
|
66
63
|
*/
|
|
67
64
|
checkpoint(): IBatchCheckpoint;
|
|
68
65
|
}
|
|
69
|
-
/**
|
|
70
|
-
* Estimates the real size in bytes on the socket for a given batch. It assumes that
|
|
71
|
-
* the envelope size (and the size of an empty op) is 200 bytes, taking into account
|
|
72
|
-
* extra overhead from stringification.
|
|
73
|
-
*
|
|
74
|
-
* @param batch - the batch to inspect
|
|
75
|
-
* @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
|
|
76
|
-
*/
|
|
77
|
-
export declare const estimateSocketSize: (batch: IBatch) => number;
|
|
78
66
|
export declare const sequenceNumbersMatch: (seqNums: BatchSequenceNumbers, otherSeqNums: BatchSequenceNumbers) => boolean;
|
|
79
67
|
//# sourceMappingURL=batchManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batchManager.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"batchManager.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;IAEzD;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACpC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B;;GAEG;AACH,wBAAgB,eAAe,CAAC,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAExF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,8BAA8B,EAAE,eAAe,GAAG,cAAc,GAC9D,MAAM,CAcR;AAED;;GAEG;AACH,qBAAa,YAAY;aA4BI,OAAO,EAAE,oBAAoB;IA3BzD,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,eAAe,CAAS;IAEhC,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,eAAe,IAAI,oBAAoB,CAKjD;IAED,OAAO,KAAK,uBAAuB,GAKlC;IAED;;;OAGG;IACH,OAAO,CAAC,oBAAoB,CAAqB;gBAErB,OAAO,EAAE,oBAAoB;IAElD,IAAI,CACV,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,OAAO,EAClB,2BAA2B,CAAC,EAAE,MAAM,GAClC,IAAI;IAUP,IAAW,KAAK,IAAI,OAAO,CAE1B;IAED;;OAEG;IACI,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU;IAc9C;;OAEG;IACI,UAAU,IAAI,gBAAgB;CAwBrC;AAgCD,eAAO,MAAM,oBAAoB,YACvB,oBAAoB,gBACf,oBAAoB,KAChC,OASF,CAAC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.sequenceNumbersMatch = exports.
|
|
7
|
+
exports.sequenceNumbersMatch = exports.BatchManager = exports.getEffectiveBatchId = exports.generateBatchId = void 0;
|
|
8
8
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
9
9
|
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
10
10
|
const metadata_js_1 = require("../metadata.js");
|
|
@@ -31,11 +31,6 @@ function getEffectiveBatchId(pendingMessageOrBatchStartInfo) {
|
|
|
31
31
|
return batchStart.batchId ?? generateBatchId(batchStart.clientId, batchStart.batchStartCsn);
|
|
32
32
|
}
|
|
33
33
|
exports.getEffectiveBatchId = getEffectiveBatchId;
|
|
34
|
-
/**
|
|
35
|
-
* Estimated size of the stringification overhead for an op accumulated
|
|
36
|
-
* from runtime to loader to the service.
|
|
37
|
-
*/
|
|
38
|
-
const opOverhead = 200;
|
|
39
34
|
/**
|
|
40
35
|
* Helper class that manages partial batch & rollback.
|
|
41
36
|
*/
|
|
@@ -43,9 +38,6 @@ class BatchManager {
|
|
|
43
38
|
get length() {
|
|
44
39
|
return this.pendingBatch.length;
|
|
45
40
|
}
|
|
46
|
-
get contentSizeInBytes() {
|
|
47
|
-
return this.batchContentSize;
|
|
48
|
-
}
|
|
49
41
|
get sequenceNumbers() {
|
|
50
42
|
return {
|
|
51
43
|
referenceSequenceNumber: this.referenceSequenceNumber,
|
|
@@ -61,28 +53,14 @@ class BatchManager {
|
|
|
61
53
|
constructor(options) {
|
|
62
54
|
this.options = options;
|
|
63
55
|
this.pendingBatch = [];
|
|
64
|
-
this.batchContentSize = 0;
|
|
65
56
|
this.hasReentrantOps = false;
|
|
66
57
|
}
|
|
67
58
|
push(message, reentrant, currentClientSequenceNumber) {
|
|
68
|
-
const contentSize = this.batchContentSize + (message.contents?.length ?? 0);
|
|
69
|
-
const opCount = this.pendingBatch.length;
|
|
70
59
|
this.hasReentrantOps = this.hasReentrantOps || reentrant;
|
|
71
|
-
// Attempt to estimate batch size, aka socket message size.
|
|
72
|
-
// Each op has pretty large envelope, estimating to be 200 bytes.
|
|
73
|
-
// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.
|
|
74
|
-
// Not taking it into account, as compression work should help there - compressed payload will be
|
|
75
|
-
// initially stored as base64, and that requires only 2 extra escape characters.
|
|
76
|
-
const socketMessageSize = contentSize + opOverhead * opCount;
|
|
77
|
-
if (socketMessageSize >= this.options.hardLimit) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
60
|
if (this.pendingBatch.length === 0) {
|
|
81
61
|
this.clientSequenceNumber = currentClientSequenceNumber;
|
|
82
62
|
}
|
|
83
|
-
this.batchContentSize = contentSize;
|
|
84
63
|
this.pendingBatch.push(message);
|
|
85
|
-
return true;
|
|
86
64
|
}
|
|
87
65
|
get empty() {
|
|
88
66
|
return this.pendingBatch.length === 0;
|
|
@@ -93,12 +71,10 @@ class BatchManager {
|
|
|
93
71
|
popBatch(batchId) {
|
|
94
72
|
const batch = {
|
|
95
73
|
messages: this.pendingBatch,
|
|
96
|
-
contentSizeInBytes: this.batchContentSize,
|
|
97
74
|
referenceSequenceNumber: this.referenceSequenceNumber,
|
|
98
75
|
hasReentrantOps: this.hasReentrantOps,
|
|
99
76
|
};
|
|
100
77
|
this.pendingBatch = [];
|
|
101
|
-
this.batchContentSize = 0;
|
|
102
78
|
this.clientSequenceNumber = undefined;
|
|
103
79
|
this.hasReentrantOps = false;
|
|
104
80
|
return addBatchMetadata(batch, batchId);
|
|
@@ -114,15 +90,14 @@ class BatchManager {
|
|
|
114
90
|
this.clientSequenceNumber = startSequenceNumber;
|
|
115
91
|
const rollbackOpsLifo = this.pendingBatch.splice(startPoint).reverse();
|
|
116
92
|
for (const message of rollbackOpsLifo) {
|
|
117
|
-
this.batchContentSize -= message.contents?.length ?? 0;
|
|
118
93
|
process(message);
|
|
119
94
|
}
|
|
120
95
|
const count = this.pendingBatch.length - startPoint;
|
|
121
96
|
if (count !== 0) {
|
|
122
|
-
throw new internal_2.LoggingError("Ops generated
|
|
97
|
+
throw new internal_2.LoggingError("Ops generated during rollback", {
|
|
123
98
|
count,
|
|
124
99
|
...(0, internal_2.tagData)(internal_2.TelemetryDataTag.UserData, {
|
|
125
|
-
ops: JSON.stringify(this.pendingBatch.slice(startPoint).map((b) => b.
|
|
100
|
+
ops: JSON.stringify(this.pendingBatch.slice(startPoint).map((b) => b.serializedOp)),
|
|
126
101
|
}),
|
|
127
102
|
});
|
|
128
103
|
}
|
|
@@ -152,18 +127,6 @@ const addBatchMetadata = (batch, batchId) => {
|
|
|
152
127
|
}
|
|
153
128
|
return batch;
|
|
154
129
|
};
|
|
155
|
-
/**
|
|
156
|
-
* Estimates the real size in bytes on the socket for a given batch. It assumes that
|
|
157
|
-
* the envelope size (and the size of an empty op) is 200 bytes, taking into account
|
|
158
|
-
* extra overhead from stringification.
|
|
159
|
-
*
|
|
160
|
-
* @param batch - the batch to inspect
|
|
161
|
-
* @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
|
|
162
|
-
*/
|
|
163
|
-
const estimateSocketSize = (batch) => {
|
|
164
|
-
return batch.contentSizeInBytes + opOverhead * batch.messages.length;
|
|
165
|
-
};
|
|
166
|
-
exports.estimateSocketSize = estimateSocketSize;
|
|
167
130
|
const sequenceNumbersMatch = (seqNums, otherSeqNums) => {
|
|
168
131
|
return ((seqNums.referenceSequenceNumber === undefined ||
|
|
169
132
|
otherSeqNums.referenceSequenceNumber === undefined ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batchManager.js","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tLoggingError,\n\ttagData,\n\tTelemetryDataTag,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { ICompressionRuntimeOptions } from \"../containerRuntime.js\";\nimport { asBatchMetadata, type IBatchMetadata } from \"../metadata.js\";\nimport type { IPendingMessage } from \"../pendingStateManager.js\";\n\nimport { BatchMessage, IBatch, IBatchCheckpoint } from \"./definitions.js\";\nimport type { BatchStartInfo } from \"./remoteMessageProcessor.js\";\n\nexport interface IBatchManagerOptions {\n\treadonly hardLimit: number;\n\treadonly compressionOptions?: ICompressionRuntimeOptions;\n\n\t/**\n\t * If true, the outbox is allowed to rebase the batch during flushing.\n\t */\n\treadonly canRebase: boolean;\n\n\t/**\n\t * If true, don't compare batchID of incoming batches to this. e.g. ID Allocation Batch IDs should be ignored\n\t */\n\treadonly ignoreBatchId?: boolean;\n}\n\nexport interface BatchSequenceNumbers {\n\treferenceSequenceNumber?: number;\n\tclientSequenceNumber?: number;\n}\n\n/**\n * Type alias for the batchId stored in batch metadata\n */\nexport type BatchId = string;\n\n/**\n * Compose original client ID and client sequence number into BatchId to stamp on the message during reconnect\n */\nexport function generateBatchId(originalClientId: string, batchStartCsn: number): BatchId {\n\treturn `${originalClientId}_[${batchStartCsn}]`;\n}\n\n/**\n * Get the effective batch ID for the input argument.\n * Supports either an IPendingMessage or BatchStartInfo.\n * If the batch ID is explicitly present, return it.\n * Otherwise, generate a new batch ID using the client ID and batch start CSN.\n */\nexport function getEffectiveBatchId(\n\tpendingMessageOrBatchStartInfo: IPendingMessage | BatchStartInfo,\n): string {\n\tif (\"localOpMetadata\" in pendingMessageOrBatchStartInfo) {\n\t\tconst pendingMessage: IPendingMessage = pendingMessageOrBatchStartInfo;\n\t\treturn (\n\t\t\tasBatchMetadata(pendingMessage.opMetadata)?.batchId ??\n\t\t\tgenerateBatchId(\n\t\t\t\tpendingMessage.batchInfo.clientId,\n\t\t\t\tpendingMessage.batchInfo.batchStartCsn,\n\t\t\t)\n\t\t);\n\t}\n\n\tconst batchStart: BatchStartInfo = pendingMessageOrBatchStartInfo;\n\treturn batchStart.batchId ?? generateBatchId(batchStart.clientId, batchStart.batchStartCsn);\n}\n\n/**\n * Estimated size of the stringification overhead for an op accumulated\n * from runtime to loader to the service.\n */\nconst opOverhead = 200;\n\n/**\n * Helper class that manages partial batch & rollback.\n */\nexport class BatchManager {\n\tprivate pendingBatch: BatchMessage[] = [];\n\tprivate batchContentSize = 0;\n\tprivate hasReentrantOps = false;\n\n\tpublic get length(): number {\n\t\treturn this.pendingBatch.length;\n\t}\n\tpublic get contentSizeInBytes(): number {\n\t\treturn this.batchContentSize;\n\t}\n\n\tpublic get sequenceNumbers(): BatchSequenceNumbers {\n\t\treturn {\n\t\t\treferenceSequenceNumber: this.referenceSequenceNumber,\n\t\t\tclientSequenceNumber: this.clientSequenceNumber,\n\t\t};\n\t}\n\n\tprivate get referenceSequenceNumber(): number | undefined {\n\t\treturn this.pendingBatch.length === 0\n\t\t\t? undefined\n\t\t\t: // NOTE: In case of reentrant ops, there could be multiple reference sequence numbers, but we will rebase before submitting.\n\t\t\t\tthis.pendingBatch[this.pendingBatch.length - 1].referenceSequenceNumber;\n\t}\n\n\t/**\n\t * The last-processed CSN when this batch started.\n\t * This is used to ensure that while the batch is open, no incoming ops are processed.\n\t */\n\tprivate clientSequenceNumber: number | undefined;\n\n\tconstructor(public readonly options: IBatchManagerOptions) {}\n\n\tpublic push(\n\t\tmessage: BatchMessage,\n\t\treentrant: boolean,\n\t\tcurrentClientSequenceNumber?: number,\n\t): boolean {\n\t\tconst contentSize = this.batchContentSize + (message.contents?.length ?? 0);\n\t\tconst opCount = this.pendingBatch.length;\n\t\tthis.hasReentrantOps = this.hasReentrantOps || reentrant;\n\n\t\t// Attempt to estimate batch size, aka socket message size.\n\t\t// Each op has pretty large envelope, estimating to be 200 bytes.\n\t\t// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.\n\t\t// Not taking it into account, as compression work should help there - compressed payload will be\n\t\t// initially stored as base64, and that requires only 2 extra escape characters.\n\t\tconst socketMessageSize = contentSize + opOverhead * opCount;\n\n\t\tif (socketMessageSize >= this.options.hardLimit) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.pendingBatch.length === 0) {\n\t\t\tthis.clientSequenceNumber = currentClientSequenceNumber;\n\t\t}\n\n\t\tthis.batchContentSize = contentSize;\n\t\tthis.pendingBatch.push(message);\n\t\treturn true;\n\t}\n\n\tpublic get empty(): boolean {\n\t\treturn this.pendingBatch.length === 0;\n\t}\n\n\t/**\n\t * Gets the pending batch and clears state for the next batch.\n\t */\n\tpublic popBatch(batchId?: BatchId): IBatch {\n\t\tconst batch: IBatch = {\n\t\t\tmessages: this.pendingBatch,\n\t\t\tcontentSizeInBytes: this.batchContentSize,\n\t\t\treferenceSequenceNumber: this.referenceSequenceNumber,\n\t\t\thasReentrantOps: this.hasReentrantOps,\n\t\t};\n\n\t\tthis.pendingBatch = [];\n\t\tthis.batchContentSize = 0;\n\t\tthis.clientSequenceNumber = undefined;\n\t\tthis.hasReentrantOps = false;\n\n\t\treturn addBatchMetadata(batch, batchId);\n\t}\n\n\t/**\n\t * Capture the pending state at this point\n\t */\n\tpublic checkpoint(): IBatchCheckpoint {\n\t\tconst startSequenceNumber = this.clientSequenceNumber;\n\t\tconst startPoint = this.pendingBatch.length;\n\t\treturn {\n\t\t\trollback: (process: (message: BatchMessage) => void) => {\n\t\t\t\tthis.clientSequenceNumber = startSequenceNumber;\n\t\t\t\tconst rollbackOpsLifo = this.pendingBatch.splice(startPoint).reverse();\n\t\t\t\tfor (const message of rollbackOpsLifo) {\n\t\t\t\t\tthis.batchContentSize -= message.contents?.length ?? 0;\n\t\t\t\t\tprocess(message);\n\t\t\t\t}\n\t\t\t\tconst count = this.pendingBatch.length - startPoint;\n\t\t\t\tif (count !== 0) {\n\t\t\t\t\tthrow new LoggingError(\"Ops generated durning rollback\", {\n\t\t\t\t\t\tcount,\n\t\t\t\t\t\t...tagData(TelemetryDataTag.UserData, {\n\t\t\t\t\t\t\tops: JSON.stringify(this.pendingBatch.slice(startPoint).map((b) => b.contents)),\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n}\n\nconst addBatchMetadata = (batch: IBatch, batchId?: BatchId): IBatch => {\n\tconst batchEnd = batch.messages.length - 1;\n\n\tconst firstMsg = batch.messages[0];\n\tconst lastMsg = batch.messages[batchEnd];\n\tassert(\n\t\tfirstMsg !== undefined && lastMsg !== undefined,\n\t\t0x9d1 /* expected non-empty batch */,\n\t);\n\n\tconst firstMetadata: Partial<IBatchMetadata> = firstMsg.metadata ?? {};\n\tconst lastMetadata: Partial<IBatchMetadata> = lastMsg.metadata ?? {};\n\n\t// Multi-message batches: mark the first and last messages with the \"batch\" flag indicating batch start/end\n\tif (batch.messages.length > 1) {\n\t\tfirstMetadata.batch = true;\n\t\tlastMetadata.batch = false;\n\t\tfirstMsg.metadata = firstMetadata;\n\t\tlastMsg.metadata = lastMetadata;\n\t}\n\n\t// If batchId is provided (e.g. in case of resubmit): stamp it on the first message\n\tif (batchId !== undefined) {\n\t\tfirstMetadata.batchId = batchId;\n\t\tfirstMsg.metadata = firstMetadata;\n\t}\n\n\treturn batch;\n};\n\n/**\n * Estimates the real size in bytes on the socket for a given batch. It assumes that\n * the envelope size (and the size of an empty op) is 200 bytes, taking into account\n * extra overhead from stringification.\n *\n * @param batch - the batch to inspect\n * @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire\n */\nexport const estimateSocketSize = (batch: IBatch): number => {\n\treturn batch.contentSizeInBytes + opOverhead * batch.messages.length;\n};\n\nexport const sequenceNumbersMatch = (\n\tseqNums: BatchSequenceNumbers,\n\totherSeqNums: BatchSequenceNumbers,\n): boolean => {\n\treturn (\n\t\t(seqNums.referenceSequenceNumber === undefined ||\n\t\t\totherSeqNums.referenceSequenceNumber === undefined ||\n\t\t\tseqNums.referenceSequenceNumber === otherSeqNums.referenceSequenceNumber) &&\n\t\t(seqNums.clientSequenceNumber === undefined ||\n\t\t\totherSeqNums.clientSequenceNumber === undefined ||\n\t\t\tseqNums.clientSequenceNumber === otherSeqNums.clientSequenceNumber)\n\t);\n};\n"]}
|
|
1
|
+
{"version":3,"file":"batchManager.js","sourceRoot":"","sources":["../../src/opLifecycle/batchManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport {\n\tLoggingError,\n\ttagData,\n\tTelemetryDataTag,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { ICompressionRuntimeOptions } from \"../containerRuntime.js\";\nimport { asBatchMetadata, type IBatchMetadata } from \"../metadata.js\";\nimport type { IPendingMessage } from \"../pendingStateManager.js\";\n\nimport { LocalBatchMessage, IBatchCheckpoint, type LocalBatch } from \"./definitions.js\";\nimport type { BatchStartInfo } from \"./remoteMessageProcessor.js\";\n\nexport interface IBatchManagerOptions {\n\treadonly compressionOptions?: ICompressionRuntimeOptions;\n\n\t/**\n\t * If true, the outbox is allowed to rebase the batch during flushing.\n\t */\n\treadonly canRebase: boolean;\n\n\t/**\n\t * If true, don't compare batchID of incoming batches to this. e.g. ID Allocation Batch IDs should be ignored\n\t */\n\treadonly ignoreBatchId?: boolean;\n}\n\nexport interface BatchSequenceNumbers {\n\treferenceSequenceNumber?: number;\n\tclientSequenceNumber?: number;\n}\n\n/**\n * Type alias for the batchId stored in batch metadata\n */\nexport type BatchId = string;\n\n/**\n * Compose original client ID and client sequence number into BatchId to stamp on the message during reconnect\n */\nexport function generateBatchId(originalClientId: string, batchStartCsn: number): BatchId {\n\treturn `${originalClientId}_[${batchStartCsn}]`;\n}\n\n/**\n * Get the effective batch ID for the input argument.\n * Supports either an IPendingMessage or BatchStartInfo.\n * If the batch ID is explicitly present, return it.\n * Otherwise, generate a new batch ID using the client ID and batch start CSN.\n */\nexport function getEffectiveBatchId(\n\tpendingMessageOrBatchStartInfo: IPendingMessage | BatchStartInfo,\n): string {\n\tif (\"localOpMetadata\" in pendingMessageOrBatchStartInfo) {\n\t\tconst pendingMessage: IPendingMessage = pendingMessageOrBatchStartInfo;\n\t\treturn (\n\t\t\tasBatchMetadata(pendingMessage.opMetadata)?.batchId ??\n\t\t\tgenerateBatchId(\n\t\t\t\tpendingMessage.batchInfo.clientId,\n\t\t\t\tpendingMessage.batchInfo.batchStartCsn,\n\t\t\t)\n\t\t);\n\t}\n\n\tconst batchStart: BatchStartInfo = pendingMessageOrBatchStartInfo;\n\treturn batchStart.batchId ?? generateBatchId(batchStart.clientId, batchStart.batchStartCsn);\n}\n\n/**\n * Helper class that manages partial batch & rollback.\n */\nexport class BatchManager {\n\tprivate pendingBatch: LocalBatchMessage[] = [];\n\tprivate hasReentrantOps = false;\n\n\tpublic get length(): number {\n\t\treturn this.pendingBatch.length;\n\t}\n\n\tpublic get sequenceNumbers(): BatchSequenceNumbers {\n\t\treturn {\n\t\t\treferenceSequenceNumber: this.referenceSequenceNumber,\n\t\t\tclientSequenceNumber: this.clientSequenceNumber,\n\t\t};\n\t}\n\n\tprivate get referenceSequenceNumber(): number | undefined {\n\t\treturn this.pendingBatch.length === 0\n\t\t\t? undefined\n\t\t\t: // NOTE: In case of reentrant ops, there could be multiple reference sequence numbers, but we will rebase before submitting.\n\t\t\t\tthis.pendingBatch[this.pendingBatch.length - 1].referenceSequenceNumber;\n\t}\n\n\t/**\n\t * The last-processed CSN when this batch started.\n\t * This is used to ensure that while the batch is open, no incoming ops are processed.\n\t */\n\tprivate clientSequenceNumber: number | undefined;\n\n\tconstructor(public readonly options: IBatchManagerOptions) {}\n\n\tpublic push(\n\t\tmessage: LocalBatchMessage,\n\t\treentrant: boolean,\n\t\tcurrentClientSequenceNumber?: number,\n\t): void {\n\t\tthis.hasReentrantOps = this.hasReentrantOps || reentrant;\n\n\t\tif (this.pendingBatch.length === 0) {\n\t\t\tthis.clientSequenceNumber = currentClientSequenceNumber;\n\t\t}\n\n\t\tthis.pendingBatch.push(message);\n\t}\n\n\tpublic get empty(): boolean {\n\t\treturn this.pendingBatch.length === 0;\n\t}\n\n\t/**\n\t * Gets the pending batch and clears state for the next batch.\n\t */\n\tpublic popBatch(batchId?: BatchId): LocalBatch {\n\t\tconst batch: LocalBatch = {\n\t\t\tmessages: this.pendingBatch,\n\t\t\treferenceSequenceNumber: this.referenceSequenceNumber,\n\t\t\thasReentrantOps: this.hasReentrantOps,\n\t\t};\n\n\t\tthis.pendingBatch = [];\n\t\tthis.clientSequenceNumber = undefined;\n\t\tthis.hasReentrantOps = false;\n\n\t\treturn addBatchMetadata(batch, batchId);\n\t}\n\n\t/**\n\t * Capture the pending state at this point\n\t */\n\tpublic checkpoint(): IBatchCheckpoint {\n\t\tconst startSequenceNumber = this.clientSequenceNumber;\n\t\tconst startPoint = this.pendingBatch.length;\n\t\treturn {\n\t\t\trollback: (process: (message: LocalBatchMessage) => void) => {\n\t\t\t\tthis.clientSequenceNumber = startSequenceNumber;\n\t\t\t\tconst rollbackOpsLifo = this.pendingBatch.splice(startPoint).reverse();\n\t\t\t\tfor (const message of rollbackOpsLifo) {\n\t\t\t\t\tprocess(message);\n\t\t\t\t}\n\t\t\t\tconst count = this.pendingBatch.length - startPoint;\n\t\t\t\tif (count !== 0) {\n\t\t\t\t\tthrow new LoggingError(\"Ops generated during rollback\", {\n\t\t\t\t\t\tcount,\n\t\t\t\t\t\t...tagData(TelemetryDataTag.UserData, {\n\t\t\t\t\t\t\tops: JSON.stringify(\n\t\t\t\t\t\t\t\tthis.pendingBatch.slice(startPoint).map((b) => b.serializedOp),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t}\n}\n\nconst addBatchMetadata = (batch: LocalBatch, batchId?: BatchId): LocalBatch => {\n\tconst batchEnd = batch.messages.length - 1;\n\n\tconst firstMsg = batch.messages[0];\n\tconst lastMsg = batch.messages[batchEnd];\n\tassert(\n\t\tfirstMsg !== undefined && lastMsg !== undefined,\n\t\t0x9d1 /* expected non-empty batch */,\n\t);\n\n\tconst firstMetadata: Partial<IBatchMetadata> = firstMsg.metadata ?? {};\n\tconst lastMetadata: Partial<IBatchMetadata> = lastMsg.metadata ?? {};\n\n\t// Multi-message batches: mark the first and last messages with the \"batch\" flag indicating batch start/end\n\tif (batch.messages.length > 1) {\n\t\tfirstMetadata.batch = true;\n\t\tlastMetadata.batch = false;\n\t\tfirstMsg.metadata = firstMetadata;\n\t\tlastMsg.metadata = lastMetadata;\n\t}\n\n\t// If batchId is provided (e.g. in case of resubmit): stamp it on the first message\n\tif (batchId !== undefined) {\n\t\tfirstMetadata.batchId = batchId;\n\t\tfirstMsg.metadata = firstMetadata;\n\t}\n\n\treturn batch;\n};\n\nexport const sequenceNumbersMatch = (\n\tseqNums: BatchSequenceNumbers,\n\totherSeqNums: BatchSequenceNumbers,\n): boolean => {\n\treturn (\n\t\t(seqNums.referenceSequenceNumber === undefined ||\n\t\t\totherSeqNums.referenceSequenceNumber === undefined ||\n\t\t\tseqNums.referenceSequenceNumber === otherSeqNums.referenceSequenceNumber) &&\n\t\t(seqNums.clientSequenceNumber === undefined ||\n\t\t\totherSeqNums.clientSequenceNumber === undefined ||\n\t\t\tseqNums.clientSequenceNumber === otherSeqNums.clientSequenceNumber)\n\t);\n};\n"]}
|
|
@@ -2,25 +2,60 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { IBatchMessage } from "@fluidframework/container-definitions/internal";
|
|
5
|
+
import type { IBatchMessage } from "@fluidframework/container-definitions/internal";
|
|
6
6
|
import { CompressionAlgorithms } from "../containerRuntime.js";
|
|
7
7
|
/**
|
|
8
|
-
* Batch message
|
|
8
|
+
* Local Batch message, before it is virtualized and sent to the ordering service
|
|
9
9
|
*/
|
|
10
|
-
export
|
|
10
|
+
export interface LocalBatchMessage {
|
|
11
|
+
serializedOp: string;
|
|
12
|
+
metadata?: Record<string, unknown>;
|
|
11
13
|
localOpMetadata?: unknown;
|
|
12
14
|
referenceSequenceNumber: number;
|
|
13
15
|
compression?: CompressionAlgorithms;
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Use serializedOp
|
|
18
|
+
*/
|
|
19
|
+
contents?: never;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Virtualized Batch message, on its way out the door to the ordering service
|
|
23
|
+
*/
|
|
24
|
+
export type OutboundBatchMessage = IBatchMessage & {
|
|
25
|
+
localOpMetadata?: unknown;
|
|
26
|
+
referenceSequenceNumber: number;
|
|
27
|
+
compression?: CompressionAlgorithms;
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated Use contents
|
|
30
|
+
*/
|
|
31
|
+
serializedOp?: never;
|
|
14
32
|
};
|
|
15
33
|
/**
|
|
16
|
-
*
|
|
34
|
+
* A batch of messages we have accumulated locally, but haven't sent to the ordering service yet.
|
|
35
|
+
*/
|
|
36
|
+
export type LocalBatch = IBatch<LocalBatchMessage[]>;
|
|
37
|
+
/**
|
|
38
|
+
* A batch of messages that has been virtualized as needed (grouped, compressed, chunked)
|
|
39
|
+
* and is ready to be sent to the ordering service.
|
|
40
|
+
* At the very least, the op contents have been serialized to string.
|
|
17
41
|
*/
|
|
18
|
-
export interface
|
|
42
|
+
export interface OutboundBatch<TMessages extends OutboundBatchMessage[] = OutboundBatchMessage[]> extends IBatch<TMessages> {
|
|
19
43
|
/**
|
|
20
44
|
* Sum of the in-memory content sizes of all messages in the batch.
|
|
21
45
|
* If the batch is compressed, this number reflects the post-compression size.
|
|
22
46
|
*/
|
|
23
47
|
readonly contentSizeInBytes: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* An {@link OutboundBatch} with exactly one message
|
|
51
|
+
* This type is helpful as Grouping yields this kind of batch, and Compression only operates on this type of batch.
|
|
52
|
+
*/
|
|
53
|
+
export type OutboundSingletonBatch = OutboundBatch<[OutboundBatchMessage]>;
|
|
54
|
+
/**
|
|
55
|
+
* Base batch interface used internally by the runtime.
|
|
56
|
+
* See {@link LocalBatch} and {@link OutboundBatch} for the concrete types.
|
|
57
|
+
*/
|
|
58
|
+
interface IBatch<TMessages extends LocalBatchMessage[] | OutboundBatchMessage[]> {
|
|
24
59
|
/**
|
|
25
60
|
* All the messages in the batch
|
|
26
61
|
*/
|
|
@@ -42,7 +77,7 @@ export interface IBatch<TMessages extends BatchMessage[] = BatchMessage[]> {
|
|
|
42
77
|
readonly hasReentrantOps?: boolean;
|
|
43
78
|
}
|
|
44
79
|
export interface IBatchCheckpoint {
|
|
45
|
-
rollback: (action: (message:
|
|
80
|
+
rollback: (action: (message: LocalBatchMessage) => void) => void;
|
|
46
81
|
}
|
|
47
82
|
/**
|
|
48
83
|
* @internal
|
|
@@ -62,4 +97,5 @@ export interface IChunkedOp {
|
|
|
62
97
|
* will make the processor return `Processed`.
|
|
63
98
|
*/
|
|
64
99
|
export type ProcessingState = "Processed" | "Skipped" | "Accepted";
|
|
100
|
+
export {};
|
|
65
101
|
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAC;AAEpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,qBAAqB,CAAC;IAEpC;;OAEG;IACH,QAAQ,CAAC,EAAE,KAAK,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,CAAC,EAAE,qBAAqB,CAAC;IAEpC;;OAEG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,aAAa,CAC7B,SAAS,SAAS,oBAAoB,EAAE,GAAG,oBAAoB,EAAE,CAChE,SAAQ,MAAM,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,aAAa,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAE3E;;;GAGG;AACH,UAAU,MAAM,CAAC,SAAS,SAAS,iBAAiB,EAAE,GAAG,oBAAoB,EAAE;IAC9E;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrD;;;;;;;;;OASG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,KAAK,IAAI,CAAC;CACjE;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IBatchMessage } from \"@fluidframework/container-definitions/internal\";\n\nimport { CompressionAlgorithms } from \"../containerRuntime.js\";\n\n/**\n * Batch message
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/opLifecycle/definitions.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IBatchMessage } from \"@fluidframework/container-definitions/internal\";\n\nimport { CompressionAlgorithms } from \"../containerRuntime.js\";\n\n/**\n * Local Batch message, before it is virtualized and sent to the ordering service\n */\nexport interface LocalBatchMessage {\n\tserializedOp: string;\n\tmetadata?: Record<string, unknown>;\n\tlocalOpMetadata?: unknown;\n\treferenceSequenceNumber: number;\n\tcompression?: CompressionAlgorithms;\n\n\t/**\n\t * @deprecated Use serializedOp\n\t */\n\tcontents?: never; // To ensure we don't leave this one when converting from OutboundBatchMessage\n}\n\n/**\n * Virtualized Batch message, on its way out the door to the ordering service\n */\nexport type OutboundBatchMessage = IBatchMessage & {\n\tlocalOpMetadata?: unknown;\n\treferenceSequenceNumber: number;\n\tcompression?: CompressionAlgorithms;\n\n\t/**\n\t * @deprecated Use contents\n\t */\n\tserializedOp?: never; // To ensure we don't leave this one when converting from LocalBatchMessage\n};\n\n/**\n * A batch of messages we have accumulated locally, but haven't sent to the ordering service yet.\n */\nexport type LocalBatch = IBatch<LocalBatchMessage[]>;\n\n/**\n * A batch of messages that has been virtualized as needed (grouped, compressed, chunked)\n * and is ready to be sent to the ordering service.\n * At the very least, the op contents have been serialized to string.\n */\nexport interface OutboundBatch<\n\tTMessages extends OutboundBatchMessage[] = OutboundBatchMessage[],\n> extends IBatch<TMessages> {\n\t/**\n\t * Sum of the in-memory content sizes of all messages in the batch.\n\t * If the batch is compressed, this number reflects the post-compression size.\n\t */\n\treadonly contentSizeInBytes: number;\n}\n\n/**\n * An {@link OutboundBatch} with exactly one message\n * This type is helpful as Grouping yields this kind of batch, and Compression only operates on this type of batch.\n */\nexport type OutboundSingletonBatch = OutboundBatch<[OutboundBatchMessage]>;\n\n/**\n * Base batch interface used internally by the runtime.\n * See {@link LocalBatch} and {@link OutboundBatch} for the concrete types.\n */\ninterface IBatch<TMessages extends LocalBatchMessage[] | OutboundBatchMessage[]> {\n\t/**\n\t * All the messages in the batch\n\t */\n\treadonly messages: TMessages;\n\t/**\n\t * The reference sequence number for the batch\n\t */\n\treadonly referenceSequenceNumber: number | undefined;\n\t/**\n\t * Wether or not the batch contains at least one op which was produced as the result\n\t * of processing another op. This means that the batch must be rebased before\n\t * submitted, to ensure that all ops have the same reference sequence numbers and a\n\t * consistent view of the data model. This happens when the op is created within a\n\t * 'changed' event handler of a DDS and will have a different reference sequence number\n\t * than the rest of the ops in the batch, meaning that it has a different view of the\n\t * state of the data model, therefore all ops must be resubmitted and rebased to the current\n\t * reference sequence number to be in agreement about the data model state.\n\t */\n\treadonly hasReentrantOps?: boolean;\n}\n\nexport interface IBatchCheckpoint {\n\trollback: (action: (message: LocalBatchMessage) => void) => void;\n}\n\n/**\n * @internal\n */\nexport interface IChunkedOp {\n\tchunkId: number;\n\ttotalChunks: number;\n\tcontents: string;\n\toriginalMetadata?: Record<string, unknown>;\n\toriginalCompression?: string;\n}\n\n/**\n * The state of remote message processing:\n * `Processed` - the message can be considered processed\n * `Skipped` - the message was ignored by the processor\n * `Accepted` - the message was processed partially. Eventually, a message\n * will make the processor return `Processed`.\n */\nexport type ProcessingState = \"Processed\" | \"Skipped\" | \"Accepted\";\n"]}
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
export { BatchId, BatchManager, BatchSequenceNumbers,
|
|
6
|
-
export {
|
|
5
|
+
export { BatchId, BatchManager, BatchSequenceNumbers, getEffectiveBatchId, generateBatchId, IBatchManagerOptions, } from "./batchManager.js";
|
|
6
|
+
export { LocalBatch, LocalBatchMessage, OutboundBatch, OutboundBatchMessage, OutboundSingletonBatch, IBatchCheckpoint, IChunkedOp, } from "./definitions.js";
|
|
7
7
|
export { DuplicateBatchDetector } from "./duplicateBatchDetector.js";
|
|
8
|
-
export {
|
|
8
|
+
export { serializeOp, ensureContentsDeserialized, } from "./opSerialization.js";
|
|
9
|
+
export { estimateSocketSize, localBatchToOutboundBatch, Outbox, getLongStack, } from "./outbox.js";
|
|
9
10
|
export { OpCompressor } from "./opCompressor.js";
|
|
10
11
|
export { OpDecompressor } from "./opDecompressor.js";
|
|
11
12
|
export { OpSplitter, splitOp, isChunkedMessage } from "./opSplitter.js";
|
|
12
|
-
export {
|
|
13
|
+
export { InboundMessageResult, BatchStartInfo, RemoteMessageProcessor, unpackRuntimeMessage, } from "./remoteMessageProcessor.js";
|
|
13
14
|
export { OpGroupingManager, OpGroupingManagerConfig, isGroupedBatch, } from "./opGroupingManager.js";
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,OAAO,EACP,YAAY,EACZ,oBAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,OAAO,EACP,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,UAAU,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACN,WAAW,EACX,0BAA0B,GAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACN,kBAAkB,EAClB,yBAAyB,EACzB,MAAM,EACN,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACN,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,oBAAoB,GACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACN,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,GACd,MAAM,wBAAwB,CAAC"}
|
|
@@ -4,18 +4,21 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.isGroupedBatch = exports.OpGroupingManager = exports.unpackRuntimeMessage = exports.RemoteMessageProcessor = exports.
|
|
7
|
+
exports.isGroupedBatch = exports.OpGroupingManager = exports.unpackRuntimeMessage = exports.RemoteMessageProcessor = exports.isChunkedMessage = exports.splitOp = exports.OpSplitter = exports.OpDecompressor = exports.OpCompressor = exports.getLongStack = exports.Outbox = exports.localBatchToOutboundBatch = exports.estimateSocketSize = exports.ensureContentsDeserialized = exports.serializeOp = exports.DuplicateBatchDetector = exports.generateBatchId = exports.getEffectiveBatchId = exports.BatchManager = void 0;
|
|
8
8
|
var batchManager_js_1 = require("./batchManager.js");
|
|
9
9
|
Object.defineProperty(exports, "BatchManager", { enumerable: true, get: function () { return batchManager_js_1.BatchManager; } });
|
|
10
|
-
Object.defineProperty(exports, "estimateSocketSize", { enumerable: true, get: function () { return batchManager_js_1.estimateSocketSize; } });
|
|
11
10
|
Object.defineProperty(exports, "getEffectiveBatchId", { enumerable: true, get: function () { return batchManager_js_1.getEffectiveBatchId; } });
|
|
12
11
|
Object.defineProperty(exports, "generateBatchId", { enumerable: true, get: function () { return batchManager_js_1.generateBatchId; } });
|
|
13
12
|
var duplicateBatchDetector_js_1 = require("./duplicateBatchDetector.js");
|
|
14
13
|
Object.defineProperty(exports, "DuplicateBatchDetector", { enumerable: true, get: function () { return duplicateBatchDetector_js_1.DuplicateBatchDetector; } });
|
|
14
|
+
var opSerialization_js_1 = require("./opSerialization.js");
|
|
15
|
+
Object.defineProperty(exports, "serializeOp", { enumerable: true, get: function () { return opSerialization_js_1.serializeOp; } });
|
|
16
|
+
Object.defineProperty(exports, "ensureContentsDeserialized", { enumerable: true, get: function () { return opSerialization_js_1.ensureContentsDeserialized; } });
|
|
15
17
|
var outbox_js_1 = require("./outbox.js");
|
|
18
|
+
Object.defineProperty(exports, "estimateSocketSize", { enumerable: true, get: function () { return outbox_js_1.estimateSocketSize; } });
|
|
19
|
+
Object.defineProperty(exports, "localBatchToOutboundBatch", { enumerable: true, get: function () { return outbox_js_1.localBatchToOutboundBatch; } });
|
|
16
20
|
Object.defineProperty(exports, "Outbox", { enumerable: true, get: function () { return outbox_js_1.Outbox; } });
|
|
17
21
|
Object.defineProperty(exports, "getLongStack", { enumerable: true, get: function () { return outbox_js_1.getLongStack; } });
|
|
18
|
-
Object.defineProperty(exports, "serializeOpContents", { enumerable: true, get: function () { return outbox_js_1.serializeOpContents; } });
|
|
19
22
|
var opCompressor_js_1 = require("./opCompressor.js");
|
|
20
23
|
Object.defineProperty(exports, "OpCompressor", { enumerable: true, get: function () { return opCompressor_js_1.OpCompressor; } });
|
|
21
24
|
var opDecompressor_js_1 = require("./opDecompressor.js");
|
|
@@ -25,7 +28,6 @@ Object.defineProperty(exports, "OpSplitter", { enumerable: true, get: function (
|
|
|
25
28
|
Object.defineProperty(exports, "splitOp", { enumerable: true, get: function () { return opSplitter_js_1.splitOp; } });
|
|
26
29
|
Object.defineProperty(exports, "isChunkedMessage", { enumerable: true, get: function () { return opSplitter_js_1.isChunkedMessage; } });
|
|
27
30
|
var remoteMessageProcessor_js_1 = require("./remoteMessageProcessor.js");
|
|
28
|
-
Object.defineProperty(exports, "ensureContentsDeserialized", { enumerable: true, get: function () { return remoteMessageProcessor_js_1.ensureContentsDeserialized; } });
|
|
29
31
|
Object.defineProperty(exports, "RemoteMessageProcessor", { enumerable: true, get: function () { return remoteMessageProcessor_js_1.RemoteMessageProcessor; } });
|
|
30
32
|
Object.defineProperty(exports, "unpackRuntimeMessage", { enumerable: true, get: function () { return remoteMessageProcessor_js_1.unpackRuntimeMessage; } });
|
|
31
33
|
var opGroupingManager_js_1 = require("./opGroupingManager.js");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/opLifecycle/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,qDAO2B;AAL1B,+GAAA,YAAY,OAAA;AAEZ,sHAAA,mBAAmB,OAAA;AACnB,kHAAA,eAAe,OAAA;AAYhB,yEAAqE;AAA5D,mIAAA,sBAAsB,OAAA;AAC/B,2DAG8B;AAF7B,iHAAA,WAAW,OAAA;AACX,gIAAA,0BAA0B,OAAA;AAE3B,yCAKqB;AAJpB,+GAAA,kBAAkB,OAAA;AAClB,sHAAA,yBAAyB,OAAA;AACzB,mGAAA,MAAM,OAAA;AACN,yGAAA,YAAY,OAAA;AAEb,qDAAiD;AAAxC,+GAAA,YAAY,OAAA;AACrB,yDAAqD;AAA5C,mHAAA,cAAc,OAAA;AACvB,iDAAwE;AAA/D,2GAAA,UAAU,OAAA;AAAE,wGAAA,OAAO,OAAA;AAAE,iHAAA,gBAAgB,OAAA;AAC9C,yEAKqC;AAFpC,mIAAA,sBAAsB,OAAA;AACtB,iIAAA,oBAAoB,OAAA;AAErB,+DAIgC;AAH/B,yHAAA,iBAAiB,OAAA;AAEjB,sHAAA,cAAc,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tBatchId,\n\tBatchManager,\n\tBatchSequenceNumbers,\n\tgetEffectiveBatchId,\n\tgenerateBatchId,\n\tIBatchManagerOptions,\n} from \"./batchManager.js\";\nexport {\n\tLocalBatch,\n\tLocalBatchMessage,\n\tOutboundBatch,\n\tOutboundBatchMessage,\n\tOutboundSingletonBatch,\n\tIBatchCheckpoint,\n\tIChunkedOp,\n} from \"./definitions.js\";\nexport { DuplicateBatchDetector } from \"./duplicateBatchDetector.js\";\nexport {\n\tserializeOp,\n\tensureContentsDeserialized,\n} from \"./opSerialization.js\";\nexport {\n\testimateSocketSize,\n\tlocalBatchToOutboundBatch,\n\tOutbox,\n\tgetLongStack,\n} from \"./outbox.js\";\nexport { OpCompressor } from \"./opCompressor.js\";\nexport { OpDecompressor } from \"./opDecompressor.js\";\nexport { OpSplitter, splitOp, isChunkedMessage } from \"./opSplitter.js\";\nexport {\n\tInboundMessageResult,\n\tBatchStartInfo,\n\tRemoteMessageProcessor,\n\tunpackRuntimeMessage,\n} from \"./remoteMessageProcessor.js\";\nexport {\n\tOpGroupingManager,\n\tOpGroupingManagerConfig,\n\tisGroupedBatch,\n} from \"./opGroupingManager.js\";\n"]}
|
|
@@ -3,24 +3,23 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
6
|
-
import {
|
|
6
|
+
import { type OutboundSingletonBatch } from "./definitions.js";
|
|
7
7
|
/**
|
|
8
|
-
* Compresses batches of ops.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Compresses batches of ops.
|
|
9
|
+
*
|
|
10
|
+
* @remarks Only single-message batches are supported
|
|
11
|
+
* Use opGroupingManager to group a batch into a singleton batch suitable for compression.
|
|
11
12
|
*/
|
|
12
13
|
export declare class OpCompressor {
|
|
13
14
|
private readonly logger;
|
|
14
15
|
constructor(logger: ITelemetryBaseLogger);
|
|
15
16
|
/**
|
|
16
|
-
* Combines the contents of the batch into a single JSON string and compresses it, putting
|
|
17
|
-
* the resulting string as the
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* @param batch - The batch to compress
|
|
21
|
-
* @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders
|
|
17
|
+
* Combines the contents of the singleton batch into a single JSON string and compresses it, putting
|
|
18
|
+
* the resulting string as the message contents in place of the original uncompressed payload.
|
|
19
|
+
* @param batch - The batch to compress. Must have only 1 message
|
|
20
|
+
* @returns A singleton batch containing a single compressed message
|
|
22
21
|
*/
|
|
23
|
-
compressBatch(batch:
|
|
22
|
+
compressBatch(batch: OutboundSingletonBatch): OutboundSingletonBatch;
|
|
24
23
|
/**
|
|
25
24
|
* Combine the batch's content strings into a single JSON string (a serialized array)
|
|
26
25
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opCompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"opCompressor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAWvE,OAAO,EAA6B,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAG1F;;;;;GAKG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;gBAEjC,MAAM,EAAE,oBAAoB;IAIxC;;;;;OAKG;IACI,aAAa,CAAC,KAAK,EAAE,sBAAsB,GAAG,sBAAsB;IAyC3E;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAyB9B"}
|
|
@@ -10,23 +10,22 @@ const internal_1 = require("@fluidframework/core-utils/internal");
|
|
|
10
10
|
const internal_2 = require("@fluidframework/telemetry-utils/internal");
|
|
11
11
|
const lz4js_1 = require("lz4js");
|
|
12
12
|
const containerRuntime_js_1 = require("../containerRuntime.js");
|
|
13
|
-
const
|
|
13
|
+
const outbox_js_1 = require("./outbox.js");
|
|
14
14
|
/**
|
|
15
|
-
* Compresses batches of ops.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* Compresses batches of ops.
|
|
16
|
+
*
|
|
17
|
+
* @remarks Only single-message batches are supported
|
|
18
|
+
* Use opGroupingManager to group a batch into a singleton batch suitable for compression.
|
|
18
19
|
*/
|
|
19
20
|
class OpCompressor {
|
|
20
21
|
constructor(logger) {
|
|
21
22
|
this.logger = (0, internal_2.createChildLogger)({ logger, namespace: "OpCompressor" });
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
|
-
* Combines the contents of the batch into a single JSON string and compresses it, putting
|
|
25
|
-
* the resulting string as the
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @param batch - The batch to compress
|
|
29
|
-
* @returns A batch of the same length as the input batch, containing a single compressed message followed by empty placeholders
|
|
25
|
+
* Combines the contents of the singleton batch into a single JSON string and compresses it, putting
|
|
26
|
+
* the resulting string as the message contents in place of the original uncompressed payload.
|
|
27
|
+
* @param batch - The batch to compress. Must have only 1 message
|
|
28
|
+
* @returns A singleton batch containing a single compressed message
|
|
30
29
|
*/
|
|
31
30
|
compressBatch(batch) {
|
|
32
31
|
(0, internal_1.assert)(batch.contentSizeInBytes > 0 && batch.messages.length === 1, 0x5a4 /* Batch should not be empty and should contain a single message */);
|
|
@@ -55,7 +54,7 @@ class OpCompressor {
|
|
|
55
54
|
sizeBeforeCompression: batch.contentSizeInBytes,
|
|
56
55
|
sizeAfterCompression: compressedBatch.contentSizeInBytes,
|
|
57
56
|
opCount: compressedBatch.messages.length,
|
|
58
|
-
socketSize: (0,
|
|
57
|
+
socketSize: (0, outbox_js_1.estimateSocketSize)(compressedBatch),
|
|
59
58
|
});
|
|
60
59
|
}
|
|
61
60
|
return compressedBatch;
|
|
@@ -64,23 +63,25 @@ class OpCompressor {
|
|
|
64
63
|
* Combine the batch's content strings into a single JSON string (a serialized array)
|
|
65
64
|
*/
|
|
66
65
|
serializeBatchContents(batch) {
|
|
66
|
+
const [message, ...none] = batch.messages;
|
|
67
|
+
(0, internal_1.assert)(none.length === 0, 0xb78 /* Batch should only contain a single message */);
|
|
67
68
|
try {
|
|
68
|
-
//
|
|
69
|
-
return `[${
|
|
69
|
+
// This is expressed as a JSON array, for legacy reasons
|
|
70
|
+
return `[${message.contents}]`;
|
|
70
71
|
}
|
|
71
|
-
catch (
|
|
72
|
-
if (
|
|
73
|
-
// This is how
|
|
72
|
+
catch (error) {
|
|
73
|
+
if (error.message === "Invalid string length") {
|
|
74
|
+
// This is how string interpolation signals that
|
|
74
75
|
// the content size exceeds its capacity
|
|
75
|
-
const
|
|
76
|
+
const dpe = internal_2.DataProcessingError.create("Payload too large", "OpCompressor");
|
|
76
77
|
this.logger.sendErrorEvent({
|
|
77
78
|
eventName: "BatchTooLarge",
|
|
78
79
|
size: batch.contentSizeInBytes,
|
|
79
80
|
length: batch.messages.length,
|
|
80
|
-
},
|
|
81
|
-
throw
|
|
81
|
+
}, dpe);
|
|
82
|
+
throw dpe;
|
|
82
83
|
}
|
|
83
|
-
throw
|
|
84
|
+
throw error;
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
}
|