@fluidframework/container-runtime 2.0.0-internal.3.0.5 → 2.0.0-internal.3.1.1
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/.eslintrc.js +19 -19
- package/.mocharc.js +2 -2
- package/api-extractor.json +2 -2
- package/dist/batchTracker.d.ts.map +1 -1
- package/dist/batchTracker.js +2 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +9 -2
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +80 -33
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +11 -9
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerHandleContext.d.ts.map +1 -1
- package/dist/containerHandleContext.js +3 -1
- package/dist/containerHandleContext.js.map +1 -1
- package/dist/containerRuntime.d.ts +11 -1
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +116 -72
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +11 -9
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +18 -13
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +68 -55
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +7 -3
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +3 -1
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/dataStores.d.ts +26 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +103 -18
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaScheduler.d.ts.map +1 -1
- package/dist/deltaScheduler.js +8 -3
- package/dist/deltaScheduler.js.map +1 -1
- package/dist/garbageCollection.d.ts +33 -14
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +178 -92
- package/dist/garbageCollection.js.map +1 -1
- package/dist/garbageCollectionConstants.d.ts +1 -0
- package/dist/garbageCollectionConstants.d.ts.map +1 -1
- package/dist/garbageCollectionConstants.js +4 -1
- package/dist/garbageCollectionConstants.js.map +1 -1
- package/dist/garbageCollectionHelpers.d.ts +26 -0
- package/dist/garbageCollectionHelpers.d.ts.map +1 -0
- package/dist/garbageCollectionHelpers.js +45 -0
- package/dist/garbageCollectionHelpers.js.map +1 -0
- package/dist/gcSweepReadyUsageDetection.d.ts +5 -5
- package/dist/gcSweepReadyUsageDetection.d.ts.map +1 -1
- package/dist/gcSweepReadyUsageDetection.js +14 -10
- package/dist/gcSweepReadyUsageDetection.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +5 -5
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +19 -12
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts +0 -4
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +7 -43
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +4 -1
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +20 -19
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/dist/opProperties.d.ts.map +1 -1
- package/dist/opProperties.js +1 -3
- package/dist/opProperties.js.map +1 -1
- package/dist/orderedClientElection.d.ts.map +1 -1
- package/dist/orderedClientElection.js +10 -4
- package/dist/orderedClientElection.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +7 -0
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +7 -4
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/runningSummarizer.d.ts.map +1 -1
- package/dist/runningSummarizer.js +34 -21
- package/dist/runningSummarizer.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +3 -2
- package/dist/scheduleManager.js.map +1 -1
- package/dist/serializedSnapshotStorage.d.ts +2 -2
- package/dist/serializedSnapshotStorage.d.ts.map +1 -1
- package/dist/serializedSnapshotStorage.js +5 -3
- package/dist/serializedSnapshotStorage.js.map +1 -1
- package/dist/summarizer.d.ts +2 -2
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +37 -17
- package/dist/summarizer.js.map +1 -1
- package/dist/summarizerClientElection.d.ts.map +1 -1
- package/dist/summarizerClientElection.js.map +1 -1
- package/dist/summarizerHandle.d.ts.map +1 -1
- package/dist/summarizerHandle.js.map +1 -1
- package/dist/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summarizerHeuristics.js +6 -9
- package/dist/summarizerHeuristics.js.map +1 -1
- package/dist/summarizerTypes.d.ts +21 -21
- package/dist/summarizerTypes.d.ts.map +1 -1
- package/dist/summarizerTypes.js.map +1 -1
- package/dist/summaryCollection.d.ts.map +1 -1
- package/dist/summaryCollection.js +18 -8
- package/dist/summaryCollection.js.map +1 -1
- package/dist/summaryFormat.d.ts +5 -2
- package/dist/summaryFormat.d.ts.map +1 -1
- package/dist/summaryFormat.js +18 -10
- package/dist/summaryFormat.js.map +1 -1
- package/dist/summaryGenerator.d.ts.map +1 -1
- package/dist/summaryGenerator.js +35 -16
- package/dist/summaryGenerator.js.map +1 -1
- package/dist/summaryManager.d.ts.map +1 -1
- package/dist/summaryManager.js +21 -9
- package/dist/summaryManager.js.map +1 -1
- package/dist/throttler.d.ts +2 -2
- package/dist/throttler.d.ts.map +1 -1
- package/dist/throttler.js +4 -4
- package/dist/throttler.js.map +1 -1
- package/garbageCollection.md +15 -2
- package/lib/batchTracker.d.ts.map +1 -1
- package/lib/batchTracker.js +2 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +9 -2
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +82 -35
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +11 -9
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerHandleContext.d.ts.map +1 -1
- package/lib/containerHandleContext.js +3 -1
- package/lib/containerHandleContext.js.map +1 -1
- package/lib/containerRuntime.d.ts +11 -1
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +122 -78
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +11 -9
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +18 -13
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +71 -58
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +7 -3
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js +3 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/dataStores.d.ts +26 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +109 -24
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaScheduler.d.ts.map +1 -1
- package/lib/deltaScheduler.js +9 -4
- package/lib/deltaScheduler.js.map +1 -1
- package/lib/garbageCollection.d.ts +33 -14
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +180 -94
- package/lib/garbageCollection.js.map +1 -1
- package/lib/garbageCollectionConstants.d.ts +1 -0
- package/lib/garbageCollectionConstants.d.ts.map +1 -1
- package/lib/garbageCollectionConstants.js +3 -0
- package/lib/garbageCollectionConstants.js.map +1 -1
- package/lib/garbageCollectionHelpers.d.ts +26 -0
- package/lib/garbageCollectionHelpers.d.ts.map +1 -0
- package/lib/garbageCollectionHelpers.js +40 -0
- package/lib/garbageCollectionHelpers.js.map +1 -0
- package/lib/gcSweepReadyUsageDetection.d.ts +5 -5
- package/lib/gcSweepReadyUsageDetection.d.ts.map +1 -1
- package/lib/gcSweepReadyUsageDetection.js +14 -10
- package/lib/gcSweepReadyUsageDetection.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +5 -5
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +19 -12
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts +0 -4
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +7 -43
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +5 -2
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +20 -19
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
- package/lib/opProperties.d.ts.map +1 -1
- package/lib/opProperties.js +1 -3
- package/lib/opProperties.js.map +1 -1
- package/lib/orderedClientElection.d.ts.map +1 -1
- package/lib/orderedClientElection.js +10 -4
- package/lib/orderedClientElection.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +7 -0
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +7 -4
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/runningSummarizer.d.ts.map +1 -1
- package/lib/runningSummarizer.js +35 -22
- package/lib/runningSummarizer.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +3 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/serializedSnapshotStorage.d.ts +2 -2
- package/lib/serializedSnapshotStorage.d.ts.map +1 -1
- package/lib/serializedSnapshotStorage.js +5 -3
- package/lib/serializedSnapshotStorage.js.map +1 -1
- package/lib/summarizer.d.ts +2 -2
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +37 -17
- package/lib/summarizer.js.map +1 -1
- package/lib/summarizerClientElection.d.ts.map +1 -1
- package/lib/summarizerClientElection.js.map +1 -1
- package/lib/summarizerHandle.d.ts.map +1 -1
- package/lib/summarizerHandle.js.map +1 -1
- package/lib/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summarizerHeuristics.js +6 -9
- package/lib/summarizerHeuristics.js.map +1 -1
- package/lib/summarizerTypes.d.ts +21 -21
- package/lib/summarizerTypes.d.ts.map +1 -1
- package/lib/summarizerTypes.js.map +1 -1
- package/lib/summaryCollection.d.ts.map +1 -1
- package/lib/summaryCollection.js +18 -8
- package/lib/summaryCollection.js.map +1 -1
- package/lib/summaryFormat.d.ts +5 -2
- package/lib/summaryFormat.d.ts.map +1 -1
- package/lib/summaryFormat.js +20 -12
- package/lib/summaryFormat.js.map +1 -1
- package/lib/summaryGenerator.d.ts.map +1 -1
- package/lib/summaryGenerator.js +35 -16
- package/lib/summaryGenerator.js.map +1 -1
- package/lib/summaryManager.d.ts.map +1 -1
- package/lib/summaryManager.js +21 -9
- package/lib/summaryManager.js.map +1 -1
- package/lib/throttler.d.ts +2 -2
- package/lib/throttler.d.ts.map +1 -1
- package/lib/throttler.js +4 -4
- package/lib/throttler.js.map +1 -1
- package/package.json +121 -115
- package/prettier.config.cjs +1 -1
- package/src/batchTracker.ts +54 -49
- package/src/blobManager.ts +793 -672
- package/src/connectionTelemetry.ts +280 -249
- package/src/containerHandleContext.ts +27 -29
- package/src/containerRuntime.ts +3168 -2988
- package/src/dataStore.ts +172 -159
- package/src/dataStoreContext.ts +1098 -1055
- package/src/dataStoreContexts.ts +178 -161
- package/src/dataStoreRegistry.ts +25 -20
- package/src/dataStores.ts +884 -728
- package/src/deltaScheduler.ts +158 -150
- package/src/garbageCollection.ts +1860 -1688
- package/src/garbageCollectionConstants.ts +3 -0
- package/src/garbageCollectionHelpers.ts +61 -0
- package/src/gcSweepReadyUsageDetection.ts +89 -83
- package/src/index.ts +67 -66
- package/src/opLifecycle/README.md +152 -0
- package/src/opLifecycle/batchManager.ts +145 -141
- package/src/opLifecycle/definitions.ts +29 -29
- package/src/opLifecycle/index.ts +5 -5
- package/src/opLifecycle/opCompressor.ts +54 -53
- package/src/opLifecycle/opDecompressor.ts +100 -128
- package/src/opLifecycle/opSplitter.ts +214 -188
- package/src/opLifecycle/outbox.ts +204 -195
- package/src/opLifecycle/remoteMessageProcessor.ts +62 -62
- package/src/opProperties.ts +11 -9
- package/src/orderedClientElection.ts +489 -457
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +384 -338
- package/src/runWhileConnectedCoordinator.ts +78 -71
- package/src/runningSummarizer.ts +619 -581
- package/src/scheduleManager.ts +299 -269
- package/src/serializedSnapshotStorage.ts +126 -112
- package/src/summarizer.ts +417 -381
- package/src/summarizerClientElection.ts +107 -100
- package/src/summarizerHandle.ts +11 -9
- package/src/summarizerHeuristics.ts +183 -186
- package/src/summarizerTypes.ts +344 -330
- package/src/summaryCollection.ts +378 -349
- package/src/summaryFormat.ts +165 -143
- package/src/summaryGenerator.ts +465 -410
- package/src/summaryManager.ts +377 -348
- package/src/throttler.ts +131 -122
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +9 -13
- package/dist/garbageCollectionTombstoneUtils.d.ts +0 -14
- package/dist/garbageCollectionTombstoneUtils.d.ts.map +0 -1
- package/dist/garbageCollectionTombstoneUtils.js +0 -23
- package/dist/garbageCollectionTombstoneUtils.js.map +0 -1
- package/lib/garbageCollectionTombstoneUtils.d.ts +0 -14
- package/lib/garbageCollectionTombstoneUtils.d.ts.map +0 -1
- package/lib/garbageCollectionTombstoneUtils.js +0 -19
- package/lib/garbageCollectionTombstoneUtils.js.map +0 -1
- package/src/garbageCollectionTombstoneUtils.ts +0 -28
|
@@ -10,154 +10,158 @@ import { ICompressionRuntimeOptions } from "../containerRuntime";
|
|
|
10
10
|
import { BatchMessage, IBatch, IBatchCheckpoint } from "./definitions";
|
|
11
11
|
|
|
12
12
|
export interface IBatchManagerOptions {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
readonly enableOpReentryCheck?: boolean;
|
|
14
|
+
readonly hardLimit: number;
|
|
15
|
+
readonly softLimit?: number;
|
|
16
|
+
readonly compressionOptions?: ICompressionRuntimeOptions;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Helper class that manages partial batch & rollback.
|
|
21
21
|
*/
|
|
22
22
|
export class BatchManager {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
23
|
+
private readonly logger;
|
|
24
|
+
private pendingBatch: BatchMessage[] = [];
|
|
25
|
+
private batchContentSize = 0;
|
|
26
|
+
/**
|
|
27
|
+
* Track the number of ops which were detected to have a mismatched
|
|
28
|
+
* reference sequence number, in order to self-throttle the telemetry events.
|
|
29
|
+
*
|
|
30
|
+
* This should be removed as part of ADO:2322
|
|
31
|
+
*/
|
|
32
|
+
private readonly maxMismatchedOpsToReport = 5;
|
|
33
|
+
private mismatchedOpsReported = 0;
|
|
34
|
+
|
|
35
|
+
public get length() {
|
|
36
|
+
return this.pendingBatch.length;
|
|
37
|
+
}
|
|
38
|
+
public get contentSizeInBytes() {
|
|
39
|
+
return this.batchContentSize;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
constructor(public readonly options: IBatchManagerOptions, logger: ITelemetryLogger) {
|
|
43
|
+
this.logger = ChildLogger.create(logger, "BatchManager");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
public push(message: BatchMessage): boolean {
|
|
47
|
+
this.checkReferenceSequenceNumber(message);
|
|
48
|
+
|
|
49
|
+
const contentSize = this.batchContentSize + (message.contents?.length ?? 0);
|
|
50
|
+
const opCount = this.pendingBatch.length;
|
|
51
|
+
|
|
52
|
+
// Attempt to estimate batch size, aka socket message size.
|
|
53
|
+
// Each op has pretty large envelope, estimating to be 200 bytes.
|
|
54
|
+
// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.
|
|
55
|
+
// Not taking it into account, as compression work should help there - compressed payload will be
|
|
56
|
+
// initially stored as base64, and that requires only 2 extra escape characters.
|
|
57
|
+
const socketMessageSize = contentSize + 200 * opCount;
|
|
58
|
+
|
|
59
|
+
// If we were provided soft limit, check for exceeding it.
|
|
60
|
+
// But only if we have any ops, as the intention here is to flush existing ops (on exceeding this limit)
|
|
61
|
+
// and start over. That's not an option if we have no ops.
|
|
62
|
+
// If compression is enabled, the soft and hard limit are ignored and the message will be pushed anyways.
|
|
63
|
+
// Cases where the message is still too large will be handled by the maxConsecutiveReconnects path.
|
|
64
|
+
if (
|
|
65
|
+
this.options.softLimit !== undefined &&
|
|
66
|
+
this.length > 0 &&
|
|
67
|
+
socketMessageSize >= this.options.softLimit
|
|
68
|
+
) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (socketMessageSize >= this.options.hardLimit) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.batchContentSize = contentSize;
|
|
77
|
+
this.pendingBatch.push(message);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public get empty() {
|
|
82
|
+
return this.pendingBatch.length === 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public popBatch(): IBatch {
|
|
86
|
+
const batch: IBatch = {
|
|
87
|
+
content: this.pendingBatch,
|
|
88
|
+
contentSizeInBytes: this.batchContentSize,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
this.pendingBatch = [];
|
|
92
|
+
this.batchContentSize = 0;
|
|
93
|
+
|
|
94
|
+
return addBatchMetadata(batch);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Capture the pending state at this point
|
|
99
|
+
*/
|
|
100
|
+
public checkpoint(): IBatchCheckpoint {
|
|
101
|
+
const startPoint = this.pendingBatch.length;
|
|
102
|
+
return {
|
|
103
|
+
rollback: (process: (message: BatchMessage) => void) => {
|
|
104
|
+
for (let i = this.pendingBatch.length; i > startPoint; ) {
|
|
105
|
+
i--;
|
|
106
|
+
const message = this.pendingBatch[i];
|
|
107
|
+
this.batchContentSize -= message.contents?.length ?? 0;
|
|
108
|
+
process(message);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this.pendingBatch.length = startPoint;
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private checkReferenceSequenceNumber(message: BatchMessage) {
|
|
117
|
+
if (
|
|
118
|
+
this.pendingBatch.length === 0 ||
|
|
119
|
+
message.referenceSequenceNumber === this.pendingBatch[0].referenceSequenceNumber
|
|
120
|
+
) {
|
|
121
|
+
// The reference sequence numbers are stable
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const telemetryProperties = {
|
|
126
|
+
referenceSequenceNumber: this.pendingBatch[0].referenceSequenceNumber,
|
|
127
|
+
messageReferenceSequenceNumber: message.referenceSequenceNumber,
|
|
128
|
+
type: message.deserializedContent.type,
|
|
129
|
+
length: this.pendingBatch.length,
|
|
130
|
+
enableOpReentryCheck: this.options.enableOpReentryCheck === true,
|
|
131
|
+
};
|
|
132
|
+
const error = new UsageError("Submission of an out of order message");
|
|
133
|
+
const eventName = "ReferenceSequenceNumberMismatch";
|
|
134
|
+
|
|
135
|
+
if (this.options.enableOpReentryCheck === true) {
|
|
136
|
+
this.logger.sendErrorEvent({ eventName, ...telemetryProperties }, error);
|
|
137
|
+
throw error;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {
|
|
141
|
+
this.logger.sendErrorEvent(
|
|
142
|
+
{
|
|
143
|
+
eventName,
|
|
144
|
+
...telemetryProperties,
|
|
145
|
+
ops: this.mismatchedOpsReported,
|
|
146
|
+
maxOps: this.maxMismatchedOpsToReport,
|
|
147
|
+
},
|
|
148
|
+
error,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
148
152
|
}
|
|
149
153
|
|
|
150
154
|
const addBatchMetadata = (batch: IBatch): IBatch => {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
155
|
+
if (batch.content.length > 1) {
|
|
156
|
+
batch.content[0].metadata = {
|
|
157
|
+
...batch.content[0].metadata,
|
|
158
|
+
batch: true,
|
|
159
|
+
};
|
|
160
|
+
batch.content[batch.content.length - 1].metadata = {
|
|
161
|
+
...batch.content[batch.content.length - 1].metadata,
|
|
162
|
+
batch: false,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return batch;
|
|
163
167
|
};
|
|
@@ -11,38 +11,38 @@ import { CompressionAlgorithms, ContainerMessageType, ContainerRuntimeMessage }
|
|
|
11
11
|
* Batch message type used internally by the runtime
|
|
12
12
|
*/
|
|
13
13
|
export type BatchMessage = IBatchMessage & {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
localOpMetadata: unknown;
|
|
15
|
+
deserializedContent: ContainerRuntimeMessage;
|
|
16
|
+
referenceSequenceNumber: number;
|
|
17
|
+
compression?: CompressionAlgorithms;
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Batch interface used internally by the runtime.
|
|
22
22
|
*/
|
|
23
23
|
export interface IBatch {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Sum of the in-memory content sizes of all messages in the batch.
|
|
26
|
+
* If the batch is compressed, this number reflects the post-compression size.
|
|
27
|
+
*/
|
|
28
|
+
readonly contentSizeInBytes: number;
|
|
29
|
+
/**
|
|
30
|
+
* All the messages in the batch
|
|
31
|
+
*/
|
|
32
|
+
readonly content: BatchMessage[];
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export interface IBatchCheckpoint {
|
|
36
|
-
|
|
36
|
+
rollback: (action: (message: BatchMessage) => void) => void;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export interface IChunkedOp {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
chunkId: number;
|
|
41
|
+
totalChunks: number;
|
|
42
|
+
contents: string;
|
|
43
|
+
originalType: MessageType | ContainerMessageType;
|
|
44
|
+
originalMetadata?: Record<string, unknown>;
|
|
45
|
+
originalCompression?: string;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/**
|
|
@@ -58,13 +58,13 @@ export type ProcessingState = "Processed" | "Skipped" | "Accepted";
|
|
|
58
58
|
* Return type for functions which process remote messages
|
|
59
59
|
*/
|
|
60
60
|
export interface IMessageProcessingResult {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
/**
|
|
62
|
+
* A shallow copy of the input message if processing happened, or
|
|
63
|
+
* the original message otherwise
|
|
64
|
+
*/
|
|
65
|
+
readonly message: ISequencedDocumentMessage;
|
|
66
|
+
/**
|
|
67
|
+
* Processing result of the input message.
|
|
68
|
+
*/
|
|
69
|
+
readonly state: ProcessingState;
|
|
70
70
|
}
|
package/src/opLifecycle/index.ts
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
export { BatchManager } from "./batchManager";
|
|
7
7
|
export {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
BatchMessage,
|
|
9
|
+
IBatch,
|
|
10
|
+
IBatchCheckpoint,
|
|
11
|
+
IChunkedOp,
|
|
12
|
+
IMessageProcessingResult,
|
|
13
13
|
} from "./definitions";
|
|
14
14
|
export { Outbox } from "./outbox";
|
|
15
15
|
export { OpCompressor } from "./opCompressor";
|
|
@@ -17,65 +17,66 @@ import { IBatch, BatchMessage } from "./definitions";
|
|
|
17
17
|
* op to reserve sequence numbers.
|
|
18
18
|
*/
|
|
19
19
|
export class OpCompressor {
|
|
20
|
-
|
|
20
|
+
private readonly logger;
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
constructor(logger: ITelemetryLogger) {
|
|
23
|
+
this.logger = ChildLogger.create(logger, "OpCompressor");
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
public compressBatch(batch: IBatch): IBatch {
|
|
27
|
+
const compressionStart = Date.now();
|
|
28
|
+
const contentsAsBuffer = new TextEncoder().encode(this.serializeBatch(batch));
|
|
29
|
+
const compressedContents = compress(contentsAsBuffer);
|
|
30
|
+
const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
|
|
31
|
+
const duration = Date.now() - compressionStart;
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
if (batch.contentSizeInBytes > 200000) {
|
|
34
|
+
this.logger.sendPerformanceEvent({
|
|
35
|
+
eventName: "CompressedBatch",
|
|
36
|
+
duration,
|
|
37
|
+
sizeBeforeCompression: batch.contentSizeInBytes,
|
|
38
|
+
sizeAfterCompression: compressedContent.length,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
const messages: BatchMessage[] = [];
|
|
43
|
+
messages.push({
|
|
44
|
+
...batch.content[0],
|
|
45
|
+
contents: JSON.stringify({ packedContents: compressedContent }),
|
|
46
|
+
metadata: batch.content[0].metadata,
|
|
47
|
+
compression: CompressionAlgorithms.lz4,
|
|
48
|
+
});
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
for (const message of batch.content.slice(1)) {
|
|
51
|
+
messages.push({ ...message, contents: undefined });
|
|
52
|
+
}
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
return {
|
|
55
|
+
contentSizeInBytes: compressedContent.length,
|
|
56
|
+
content: messages,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
60
|
+
private serializeBatch(batch: IBatch): string {
|
|
61
|
+
try {
|
|
62
|
+
return JSON.stringify(batch.content.map((message) => message.deserializedContent));
|
|
63
|
+
} catch (e: any) {
|
|
64
|
+
if (e.message === "Invalid string length") {
|
|
65
|
+
// This is how JSON.stringify signals that
|
|
66
|
+
// the content size exceeds its capacity
|
|
67
|
+
const error = new UsageError("Payload too large");
|
|
68
|
+
this.logger.sendErrorEvent(
|
|
69
|
+
{
|
|
70
|
+
eventName: "BatchTooLarge",
|
|
71
|
+
size: batch.contentSizeInBytes,
|
|
72
|
+
length: batch.content.length,
|
|
73
|
+
},
|
|
74
|
+
error,
|
|
75
|
+
);
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
throw e;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
81
82
|
}
|