@fluidframework/container-runtime 2.32.0 → 2.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/api-report/container-runtime.legacy.alpha.api.md +71 -67
- package/container-runtime.test-files.tar +0 -0
- package/dist/blobManager/blobManager.d.ts +7 -4
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +38 -12
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +4 -0
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +24 -0
- package/dist/channelCollection.js.map +1 -1
- package/dist/compatUtils.d.ts +74 -0
- package/dist/compatUtils.d.ts.map +1 -0
- package/dist/compatUtils.js +151 -0
- package/dist/compatUtils.js.map +1 -0
- package/dist/compressionDefinitions.d.ts +39 -0
- package/dist/compressionDefinitions.d.ts.map +1 -0
- package/dist/compressionDefinitions.js +30 -0
- package/dist/compressionDefinitions.js.map +1 -0
- package/dist/containerRuntime.d.ts +78 -52
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +141 -54
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +3 -0
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +122 -66
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/deltaManagerProxies.d.ts +55 -12
- package/dist/deltaManagerProxies.d.ts.map +1 -1
- package/dist/deltaManagerProxies.js +63 -55
- package/dist/deltaManagerProxies.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +2 -0
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -0
- package/dist/opLifecycle/batchManager.d.ts +3 -15
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +5 -39
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +44 -11
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +3 -3
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +3 -2
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +4 -4
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +3 -3
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +2 -2
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +1 -2
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSerialization.d.ts +3 -1
- package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
- package/dist/opLifecycle/opSerialization.js +4 -2
- package/dist/opLifecycle/opSerialization.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +2 -2
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +25 -3
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +112 -61
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts +36 -7
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +83 -16
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runtimeLayerCompatState.d.ts.map +1 -1
- package/dist/runtimeLayerCompatState.js +1 -1
- package/dist/runtimeLayerCompatState.js.map +1 -1
- package/dist/summary/documentSchema.d.ts +1 -0
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +2 -0
- package/dist/summary/documentSchema.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts +7 -4
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +38 -12
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +4 -0
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +24 -0
- package/lib/channelCollection.js.map +1 -1
- package/lib/compatUtils.d.ts +74 -0
- package/lib/compatUtils.d.ts.map +1 -0
- package/lib/compatUtils.js +142 -0
- package/lib/compatUtils.js.map +1 -0
- package/lib/compressionDefinitions.d.ts +39 -0
- package/lib/compressionDefinitions.d.ts.map +1 -0
- package/lib/compressionDefinitions.js +27 -0
- package/lib/compressionDefinitions.js.map +1 -0
- package/lib/containerRuntime.d.ts +78 -52
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +143 -56
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +3 -0
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +57 -1
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/deltaManagerProxies.d.ts +55 -12
- package/lib/deltaManagerProxies.d.ts.map +1 -1
- package/lib/deltaManagerProxies.js +63 -55
- package/lib/deltaManagerProxies.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +2 -0
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/index.d.ts +4 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -0
- package/lib/opLifecycle/batchManager.d.ts +3 -15
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +4 -37
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +44 -11
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +3 -3
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +2 -2
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +2 -2
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +1 -1
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +2 -2
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +1 -2
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSerialization.d.ts +3 -1
- package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
- package/lib/opLifecycle/opSerialization.js +4 -2
- package/lib/opLifecycle/opSerialization.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +1 -1
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +25 -3
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +110 -61
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts +36 -7
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +84 -17
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/runtimeLayerCompatState.d.ts.map +1 -1
- package/lib/runtimeLayerCompatState.js +2 -2
- package/lib/runtimeLayerCompatState.js.map +1 -1
- package/lib/summary/documentSchema.d.ts +1 -0
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +2 -0
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/package.json +21 -20
- package/src/blobManager/blobManager.ts +48 -15
- package/src/channelCollection.ts +27 -0
- package/src/compatUtils.ts +211 -0
- package/src/compressionDefinitions.ts +47 -0
- package/src/containerRuntime.ts +259 -108
- package/src/dataStoreContext.ts +82 -2
- package/src/deltaManagerProxies.ts +132 -70
- package/src/gc/gcDefinitions.ts +2 -0
- package/src/index.ts +5 -3
- package/src/opLifecycle/batchManager.ts +7 -52
- package/src/opLifecycle/definitions.ts +45 -11
- package/src/opLifecycle/index.ts +7 -2
- package/src/opLifecycle/opCompressor.ts +2 -2
- package/src/opLifecycle/opDecompressor.ts +1 -1
- package/src/opLifecycle/opGroupingManager.ts +7 -5
- package/src/opLifecycle/opSerialization.ts +6 -2
- package/src/opLifecycle/opSplitter.ts +1 -1
- package/src/opLifecycle/outbox.ts +154 -85
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +135 -21
- package/src/runtimeLayerCompatState.ts +5 -2
- package/src/summary/documentSchema.ts +3 -0
package/src/dataStoreContext.ts
CHANGED
|
@@ -5,11 +5,17 @@
|
|
|
5
5
|
|
|
6
6
|
import { TypedEventEmitter, type ILayerCompatDetails } from "@fluid-internal/client-utils";
|
|
7
7
|
import { AttachState, IAudience } from "@fluidframework/container-definitions";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
IDeltaManager,
|
|
10
|
+
isIDeltaManagerFull,
|
|
11
|
+
type IDeltaManagerFull,
|
|
12
|
+
type ReadOnlyInfo,
|
|
13
|
+
} from "@fluidframework/container-definitions/internal";
|
|
9
14
|
import {
|
|
10
15
|
FluidObject,
|
|
11
16
|
IDisposable,
|
|
12
17
|
ITelemetryBaseProperties,
|
|
18
|
+
type IErrorBase,
|
|
13
19
|
type IEvent,
|
|
14
20
|
} from "@fluidframework/core-interfaces";
|
|
15
21
|
import {
|
|
@@ -75,6 +81,7 @@ import {
|
|
|
75
81
|
tagCodeArtifacts,
|
|
76
82
|
} from "@fluidframework/telemetry-utils/internal";
|
|
77
83
|
|
|
84
|
+
import { BaseDeltaManagerProxy } from "./deltaManagerProxies.js";
|
|
78
85
|
import {
|
|
79
86
|
runtimeCompatDetailsForDataStore,
|
|
80
87
|
validateDatastoreCompatibility,
|
|
@@ -188,6 +195,58 @@ export interface IFluidDataStoreContextEvents extends IEvent {
|
|
|
188
195
|
(event: "attaching" | "attached", listener: () => void);
|
|
189
196
|
}
|
|
190
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Eventually we should remove the delta manger from being exposed to Datastore runtimes via the context. However to remove that exposure we need to add new
|
|
200
|
+
* features, and those features themselves need forward and back compat. This proxy is here to enable that back compat. Each feature this proxy is used to
|
|
201
|
+
* support should be listed below, and as layer compat support goes away for those feature, we should also remove them from this proxy, with the eventual goal
|
|
202
|
+
* of completely removing this proxy.
|
|
203
|
+
*
|
|
204
|
+
* - Everything regarding readonly is to support older datastore runtimes which do not have the setReadonly function, so they must get their readonly state via the delta manager.
|
|
205
|
+
*
|
|
206
|
+
*/
|
|
207
|
+
class ContextDeltaManagerProxy extends BaseDeltaManagerProxy {
|
|
208
|
+
constructor(
|
|
209
|
+
base: IDeltaManagerFull,
|
|
210
|
+
private readonly isReadOnly: () => boolean,
|
|
211
|
+
) {
|
|
212
|
+
super(base, {
|
|
213
|
+
onReadonly: (): void => {
|
|
214
|
+
/* readonly is controlled from the context which calls setReadonly */
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
public get readOnlyInfo(): ReadOnlyInfo {
|
|
220
|
+
const readonly = this.isReadOnly();
|
|
221
|
+
if (readonly === this.deltaManager.readOnlyInfo.readonly) {
|
|
222
|
+
return this.deltaManager.readOnlyInfo;
|
|
223
|
+
} else {
|
|
224
|
+
return readonly === true
|
|
225
|
+
? {
|
|
226
|
+
readonly,
|
|
227
|
+
forced: false,
|
|
228
|
+
permissions: undefined,
|
|
229
|
+
storageOnly: false,
|
|
230
|
+
}
|
|
231
|
+
: { readonly };
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Called by the owning datastore context to configure the readonly
|
|
237
|
+
* state of the delta manger that is project down to the datastore
|
|
238
|
+
* runtime. This state may not align with that of the true delta
|
|
239
|
+
* manager if the context wishes to control the read only state
|
|
240
|
+
* differently than the delta manager itself.
|
|
241
|
+
*/
|
|
242
|
+
public setReadonly(
|
|
243
|
+
readonly: boolean,
|
|
244
|
+
readonlyConnectionReason?: { reason: string; error?: IErrorBase },
|
|
245
|
+
): void {
|
|
246
|
+
this.emit("readonly", readonly, readonlyConnectionReason);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
191
250
|
/**
|
|
192
251
|
* Represents the context for the store. This context is passed to the store runtime.
|
|
193
252
|
* @internal
|
|
@@ -217,10 +276,13 @@ export abstract class FluidDataStoreContext
|
|
|
217
276
|
return this.parentContext.baseLogger;
|
|
218
277
|
}
|
|
219
278
|
|
|
279
|
+
private readonly _contextDeltaManagerProxy: ContextDeltaManagerProxy;
|
|
220
280
|
public get deltaManager(): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage> {
|
|
221
|
-
return this.
|
|
281
|
+
return this._contextDeltaManagerProxy;
|
|
222
282
|
}
|
|
223
283
|
|
|
284
|
+
public isReadOnly = (): boolean => this.parentContext.isReadOnly?.() ?? false;
|
|
285
|
+
|
|
224
286
|
public get connected(): boolean {
|
|
225
287
|
return this.parentContext.connected;
|
|
226
288
|
}
|
|
@@ -420,6 +482,16 @@ export abstract class FluidDataStoreContext
|
|
|
420
482
|
// By default, a data store can log maximum 10 local changes telemetry in summarizer.
|
|
421
483
|
this.localChangesTelemetryCount =
|
|
422
484
|
this.mc.config.getNumber("Fluid.Telemetry.LocalChangesTelemetryCount") ?? 10;
|
|
485
|
+
|
|
486
|
+
assert(
|
|
487
|
+
isIDeltaManagerFull(this.parentContext.deltaManager),
|
|
488
|
+
0xb83 /* Invalid delta manager */,
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
this._contextDeltaManagerProxy = new ContextDeltaManagerProxy(
|
|
492
|
+
this.parentContext.deltaManager,
|
|
493
|
+
() => this.isReadOnly(),
|
|
494
|
+
);
|
|
423
495
|
}
|
|
424
496
|
|
|
425
497
|
public dispose(): void {
|
|
@@ -437,6 +509,7 @@ export abstract class FluidDataStoreContext
|
|
|
437
509
|
})
|
|
438
510
|
.catch((error) => {});
|
|
439
511
|
}
|
|
512
|
+
this._contextDeltaManagerProxy.dispose();
|
|
440
513
|
}
|
|
441
514
|
|
|
442
515
|
/**
|
|
@@ -615,6 +688,13 @@ export abstract class FluidDataStoreContext
|
|
|
615
688
|
this.channel!.setConnectionState(connected, clientId);
|
|
616
689
|
}
|
|
617
690
|
|
|
691
|
+
public notifyReadOnlyState(readonly: boolean): void {
|
|
692
|
+
this.verifyNotClosed("notifyReadOnlyState", false /* checkTombstone */);
|
|
693
|
+
|
|
694
|
+
this.channel?.notifyReadOnlyState?.(readonly);
|
|
695
|
+
this._contextDeltaManagerProxy.setReadonly(readonly);
|
|
696
|
+
}
|
|
697
|
+
|
|
618
698
|
/**
|
|
619
699
|
* Process messages for this data store. The messages here are contiguous messages for this data store in a batch.
|
|
620
700
|
* @param messageCollection - The collection of messages to process.
|
|
@@ -25,13 +25,68 @@ import {
|
|
|
25
25
|
import type { PendingStateManager } from "./pendingStateManager.js";
|
|
26
26
|
import { summarizerClientType } from "./summary/index.js";
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Interface defining event handlers for the BaseDeltaManagerProxy.
|
|
30
|
+
* These handlers allow customization of behavior for various DeltaManager events.
|
|
31
|
+
*/
|
|
32
|
+
export interface BaseDeltaManagerProxyEventHandlers {
|
|
33
|
+
/**
|
|
34
|
+
* Event handler triggered when the readonly state changes.
|
|
35
|
+
* @param readonly - Indicates if the connection is readonly.
|
|
36
|
+
* @param readonlyConnectionReason - Optional reason and error details for the readonly state.
|
|
37
|
+
*/
|
|
38
|
+
onReadonly: (
|
|
39
|
+
readonly: boolean,
|
|
40
|
+
readonlyConnectionReason?: { reason: string; error?: IErrorBase },
|
|
41
|
+
) => void;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Event handler triggered before sending a message.
|
|
45
|
+
* @param messageBuffer - The buffer of messages to be sent.
|
|
46
|
+
*/
|
|
47
|
+
onPrepareSend: (messageBuffer: unknown[]) => void;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Event handler triggered when an operation is submitted.
|
|
51
|
+
* @param message - The document message being submitted.
|
|
52
|
+
*/
|
|
53
|
+
onSubmitOp: (message: IDocumentMessage) => void;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Event handler triggered when an operation is received.
|
|
57
|
+
* @param message - The sequenced document message received.
|
|
58
|
+
* @param processingTime - The time taken to process the message.
|
|
59
|
+
*/
|
|
60
|
+
onOp: (message: ISequencedDocumentMessage, processingTime: number) => void;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Event handler triggered when a pong response is received.
|
|
64
|
+
* @param latency - The latency of the pong response.
|
|
65
|
+
*/
|
|
66
|
+
onPong: (latency: number) => void;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Event handler triggered when a connection is established.
|
|
70
|
+
* @param details - The connection details.
|
|
71
|
+
* @param opsBehind - Optional number of operations behind the latest state.
|
|
72
|
+
*/
|
|
73
|
+
onConnect: (details: IConnectionDetails, opsBehind?: number) => void;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Event handler triggered when a disconnection occurs.
|
|
77
|
+
* @param reason - The reason for the disconnection.
|
|
78
|
+
* @param error - Optional error details for the disconnection.
|
|
79
|
+
*/
|
|
80
|
+
onDisconnect: (reason: string, error?: IAnyDriverError) => void;
|
|
81
|
+
}
|
|
82
|
+
|
|
28
83
|
/**
|
|
29
84
|
* Base class for DeltaManager proxy that proxy's access to the real DeltaManager.
|
|
30
85
|
*
|
|
31
86
|
* This class allows us to build proxy functionality without actually having to implement all the methods
|
|
32
87
|
* of the DeltaManager.
|
|
33
88
|
*/
|
|
34
|
-
export
|
|
89
|
+
export class BaseDeltaManagerProxy
|
|
35
90
|
extends TypedEventEmitter<IDeltaManagerEvents>
|
|
36
91
|
implements IDeltaManagerFull
|
|
37
92
|
{
|
|
@@ -99,29 +154,64 @@ export abstract class BaseDeltaManagerProxy
|
|
|
99
154
|
return this.deltaManager.readOnlyInfo;
|
|
100
155
|
}
|
|
101
156
|
|
|
102
|
-
|
|
157
|
+
private readonly eventHandlers: BaseDeltaManagerProxyEventHandlers;
|
|
158
|
+
|
|
159
|
+
constructor(
|
|
160
|
+
protected readonly deltaManager: IDeltaManagerFull,
|
|
161
|
+
overrides?: Partial<BaseDeltaManagerProxyEventHandlers>,
|
|
162
|
+
) {
|
|
103
163
|
super();
|
|
104
164
|
|
|
165
|
+
this.eventHandlers = {
|
|
166
|
+
onPrepareSend: (messageBuffer: unknown[]): void => {
|
|
167
|
+
this.emit("prepareSend", messageBuffer);
|
|
168
|
+
},
|
|
169
|
+
onSubmitOp: (message: IDocumentMessage): void => {
|
|
170
|
+
this.emit("submitOp", message);
|
|
171
|
+
},
|
|
172
|
+
onOp: (message: ISequencedDocumentMessage, processingTime: number): void => {
|
|
173
|
+
this.emit("op", message, processingTime);
|
|
174
|
+
},
|
|
175
|
+
onPong: (latency: number): void => {
|
|
176
|
+
this.emit("pong", latency);
|
|
177
|
+
},
|
|
178
|
+
onConnect: (details: IConnectionDetails, opsBehind?: number): void => {
|
|
179
|
+
this.emit("connect", details, opsBehind);
|
|
180
|
+
},
|
|
181
|
+
onDisconnect: (reason: string, error?: IAnyDriverError): void => {
|
|
182
|
+
this.emit("disconnect", reason, error);
|
|
183
|
+
},
|
|
184
|
+
onReadonly: (
|
|
185
|
+
readonly: boolean,
|
|
186
|
+
readonlyConnectionReason?: { reason: string; error?: IErrorBase },
|
|
187
|
+
): void => {
|
|
188
|
+
this.emit("readonly", readonly, readonlyConnectionReason);
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
...overrides,
|
|
192
|
+
};
|
|
193
|
+
|
|
105
194
|
// We are expecting this class to have many listeners, so we suppress noisy "MaxListenersExceededWarning" logging.
|
|
106
195
|
super.setMaxListeners(0);
|
|
107
196
|
|
|
108
|
-
this.deltaManager.on("prepareSend", this.onPrepareSend);
|
|
109
|
-
this.deltaManager.on("submitOp", this.onSubmitOp);
|
|
110
|
-
this.deltaManager.on("op", this.onOp);
|
|
111
|
-
this.deltaManager.on("pong", this.onPong);
|
|
112
|
-
this.deltaManager.on("connect", this.onConnect);
|
|
113
|
-
this.deltaManager.on("disconnect", this.onDisconnect);
|
|
114
|
-
this.deltaManager.on("readonly", this.onReadonly);
|
|
197
|
+
this.deltaManager.on("prepareSend", this.eventHandlers.onPrepareSend);
|
|
198
|
+
this.deltaManager.on("submitOp", this.eventHandlers.onSubmitOp);
|
|
199
|
+
this.deltaManager.on("op", this.eventHandlers.onOp);
|
|
200
|
+
this.deltaManager.on("pong", this.eventHandlers.onPong);
|
|
201
|
+
this.deltaManager.on("connect", this.eventHandlers.onConnect);
|
|
202
|
+
this.deltaManager.on("disconnect", this.eventHandlers.onDisconnect);
|
|
203
|
+
this.deltaManager.on("readonly", this.eventHandlers.onReadonly);
|
|
115
204
|
}
|
|
116
205
|
|
|
117
206
|
public dispose(): void {
|
|
118
|
-
this.deltaManager.off("prepareSend", this.onPrepareSend);
|
|
119
|
-
this.deltaManager.off("submitOp", this.onSubmitOp);
|
|
120
|
-
this.deltaManager.off("op", this.onOp);
|
|
121
|
-
this.deltaManager.off("pong", this.onPong);
|
|
122
|
-
this.deltaManager.off("connect", this.onConnect);
|
|
123
|
-
this.deltaManager.off("disconnect", this.onDisconnect);
|
|
124
|
-
this.deltaManager.off("readonly", this.onReadonly);
|
|
207
|
+
this.deltaManager.off("prepareSend", this.eventHandlers.onPrepareSend);
|
|
208
|
+
this.deltaManager.off("submitOp", this.eventHandlers.onSubmitOp);
|
|
209
|
+
this.deltaManager.off("op", this.eventHandlers.onOp);
|
|
210
|
+
this.deltaManager.off("pong", this.eventHandlers.onPong);
|
|
211
|
+
this.deltaManager.off("connect", this.eventHandlers.onConnect);
|
|
212
|
+
this.deltaManager.off("disconnect", this.eventHandlers.onDisconnect);
|
|
213
|
+
this.deltaManager.off("readonly", this.eventHandlers.onReadonly);
|
|
214
|
+
this.removeAllListeners();
|
|
125
215
|
}
|
|
126
216
|
|
|
127
217
|
public submitSignal(content: string, targetClientId?: string): void {
|
|
@@ -131,34 +221,6 @@ export abstract class BaseDeltaManagerProxy
|
|
|
131
221
|
public flush(): void {
|
|
132
222
|
return this.deltaManager.flush();
|
|
133
223
|
}
|
|
134
|
-
|
|
135
|
-
private readonly onPrepareSend = (messageBuffer: unknown[]): void => {
|
|
136
|
-
this.emit("prepareSend", messageBuffer);
|
|
137
|
-
};
|
|
138
|
-
private readonly onSubmitOp = (message: IDocumentMessage): void => {
|
|
139
|
-
this.emit("submitOp", message);
|
|
140
|
-
};
|
|
141
|
-
protected readonly onOp = (
|
|
142
|
-
message: ISequencedDocumentMessage,
|
|
143
|
-
processingTime: number,
|
|
144
|
-
): void => {
|
|
145
|
-
this.emit("op", message, processingTime);
|
|
146
|
-
};
|
|
147
|
-
private readonly onPong = (latency: number): void => {
|
|
148
|
-
this.emit("pong", latency);
|
|
149
|
-
};
|
|
150
|
-
private readonly onConnect = (details: IConnectionDetails, opsBehind?: number): void => {
|
|
151
|
-
this.emit("connect", details, opsBehind);
|
|
152
|
-
};
|
|
153
|
-
private readonly onDisconnect = (reason: string, error?: IAnyDriverError): void => {
|
|
154
|
-
this.emit("disconnect", reason, error);
|
|
155
|
-
};
|
|
156
|
-
private readonly onReadonly = (
|
|
157
|
-
readonly: boolean,
|
|
158
|
-
readonlyConnectionReason?: { reason: string; error?: IErrorBase },
|
|
159
|
-
): void => {
|
|
160
|
-
this.emit("readonly", readonly, readonlyConnectionReason);
|
|
161
|
-
};
|
|
162
224
|
}
|
|
163
225
|
|
|
164
226
|
/**
|
|
@@ -167,31 +229,34 @@ export abstract class BaseDeltaManagerProxy
|
|
|
167
229
|
* - Summarizer client should not be active to layers below the container runtime to restrict local changes.
|
|
168
230
|
*/
|
|
169
231
|
export class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
|
|
232
|
+
public static wrapIfSummarizer(deltaManager: IDeltaManagerFull): IDeltaManagerFull {
|
|
233
|
+
if (deltaManager.clientDetails.type === summarizerClientType) {
|
|
234
|
+
return new DeltaManagerSummarizerProxy(deltaManager);
|
|
235
|
+
}
|
|
236
|
+
return deltaManager;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// eslint-disable-next-line @typescript-eslint/class-literal-property-style
|
|
170
240
|
public get active(): boolean {
|
|
171
241
|
// Summarize clients should not be active. There shouldn't be any local changes (writes) in the summarizer
|
|
172
242
|
// except for the SummarizeOp which is generated by the runtime.
|
|
173
|
-
return
|
|
243
|
+
return false;
|
|
174
244
|
}
|
|
175
245
|
|
|
176
246
|
public get readOnlyInfo(): ReadOnlyInfo {
|
|
177
247
|
// Summarizer clients should be read-only as far as the runtime and layers below are concerned. There shouldn't
|
|
178
248
|
// be any local changes (writes) in the summarizer except for the summarize op which is generated by the runtime.
|
|
179
|
-
if (this.isSummarizerClient) {
|
|
180
|
-
return {
|
|
181
|
-
readonly: true,
|
|
182
|
-
forced: false,
|
|
183
|
-
permissions: undefined,
|
|
184
|
-
storageOnly: false,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
return this.deltaManager.readOnlyInfo;
|
|
188
|
-
}
|
|
189
249
|
|
|
190
|
-
|
|
250
|
+
return {
|
|
251
|
+
readonly: true,
|
|
252
|
+
forced: false,
|
|
253
|
+
permissions: undefined,
|
|
254
|
+
storageOnly: false,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
191
257
|
|
|
192
258
|
constructor(protected readonly deltaManager: IDeltaManagerFull) {
|
|
193
|
-
super(deltaManager);
|
|
194
|
-
this.isSummarizerClient = this.deltaManager.clientDetails.type === summarizerClientType;
|
|
259
|
+
super(deltaManager, { onReadonly: () => {} });
|
|
195
260
|
}
|
|
196
261
|
}
|
|
197
262
|
|
|
@@ -228,17 +293,6 @@ export class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {
|
|
|
228
293
|
};
|
|
229
294
|
}
|
|
230
295
|
|
|
231
|
-
protected readonly onOp = (
|
|
232
|
-
message: ISequencedDocumentMessage,
|
|
233
|
-
processingTime: number,
|
|
234
|
-
): void => {
|
|
235
|
-
const messageIntercept = {
|
|
236
|
-
...message,
|
|
237
|
-
minimumSequenceNumber: this.minimumSequenceNumber,
|
|
238
|
-
};
|
|
239
|
-
this.emit("op", messageIntercept, processingTime);
|
|
240
|
-
};
|
|
241
|
-
|
|
242
296
|
constructor(
|
|
243
297
|
protected readonly deltaManager: IDeltaManagerFull,
|
|
244
298
|
private readonly pendingStateManager: Pick<
|
|
@@ -246,6 +300,14 @@ export class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {
|
|
|
246
300
|
"minimumPendingMessageSequenceNumber"
|
|
247
301
|
>,
|
|
248
302
|
) {
|
|
249
|
-
super(deltaManager
|
|
303
|
+
super(deltaManager, {
|
|
304
|
+
onOp: (message: ISequencedDocumentMessage, processingTime: number): void => {
|
|
305
|
+
const messageIntercept = {
|
|
306
|
+
...message,
|
|
307
|
+
minimumSequenceNumber: this.minimumSequenceNumber,
|
|
308
|
+
};
|
|
309
|
+
this.emit("op", messageIntercept, processingTime);
|
|
310
|
+
},
|
|
311
|
+
});
|
|
250
312
|
}
|
|
251
313
|
}
|
package/src/gc/gcDefinitions.ts
CHANGED
|
@@ -333,6 +333,8 @@ export type GarbageCollectionMessage = ISweepMessage | ITombstoneLoadedMessage;
|
|
|
333
333
|
|
|
334
334
|
/**
|
|
335
335
|
* Defines the APIs for the runtime object to be passed to the garbage collector.
|
|
336
|
+
*
|
|
337
|
+
* @internal
|
|
336
338
|
*/
|
|
337
339
|
export interface IGarbageCollectionRuntime {
|
|
338
340
|
/**
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
export {
|
|
7
|
+
ContainerRuntimeOptions,
|
|
8
|
+
ContainerRuntimeOptionsInternal,
|
|
7
9
|
ISummaryRuntimeOptions,
|
|
8
10
|
IContainerRuntimeOptions,
|
|
9
11
|
IContainerRuntimeOptionsInternal,
|
|
@@ -14,11 +16,10 @@ export {
|
|
|
14
16
|
DeletedResponseHeaderKey,
|
|
15
17
|
TombstoneResponseHeaderKey,
|
|
16
18
|
InactiveResponseHeaderKey,
|
|
17
|
-
ICompressionRuntimeOptions,
|
|
18
|
-
CompressionAlgorithms,
|
|
19
19
|
RuntimeHeaderData,
|
|
20
|
-
disabledCompressionConfig,
|
|
21
20
|
} from "./containerRuntime.js";
|
|
21
|
+
export type { ICompressionRuntimeOptions } from "./compressionDefinitions.js";
|
|
22
|
+
export { CompressionAlgorithms, disabledCompressionConfig } from "./compressionDefinitions.js";
|
|
22
23
|
export {
|
|
23
24
|
ContainerMessageType,
|
|
24
25
|
UnknownContainerRuntimeMessage,
|
|
@@ -35,6 +36,7 @@ export {
|
|
|
35
36
|
IGCMetadata,
|
|
36
37
|
GCFeatureMatrix,
|
|
37
38
|
GCVersion,
|
|
39
|
+
IGarbageCollectionRuntime,
|
|
38
40
|
IGCRuntimeOptions,
|
|
39
41
|
IMarkPhaseStats,
|
|
40
42
|
ISweepPhaseStats,
|
|
@@ -10,20 +10,15 @@ import {
|
|
|
10
10
|
TelemetryDataTag,
|
|
11
11
|
} from "@fluidframework/telemetry-utils/internal";
|
|
12
12
|
|
|
13
|
-
import { ICompressionRuntimeOptions } from "../
|
|
13
|
+
import { ICompressionRuntimeOptions } from "../compressionDefinitions.js";
|
|
14
14
|
import { asBatchMetadata, type IBatchMetadata } from "../metadata.js";
|
|
15
15
|
import type { IPendingMessage } from "../pendingStateManager.js";
|
|
16
16
|
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
IBatchCheckpoint,
|
|
20
|
-
type LocalBatch,
|
|
21
|
-
type OutboundBatch,
|
|
22
|
-
} from "./definitions.js";
|
|
17
|
+
import { LocalBatchMessage, IBatchCheckpoint, type LocalBatch } from "./definitions.js";
|
|
18
|
+
import { serializeOp } from "./opSerialization.js";
|
|
23
19
|
import type { BatchStartInfo } from "./remoteMessageProcessor.js";
|
|
24
20
|
|
|
25
21
|
export interface IBatchManagerOptions {
|
|
26
|
-
readonly hardLimit: number;
|
|
27
22
|
readonly compressionOptions?: ICompressionRuntimeOptions;
|
|
28
23
|
|
|
29
24
|
/**
|
|
@@ -78,26 +73,16 @@ export function getEffectiveBatchId(
|
|
|
78
73
|
return batchStart.batchId ?? generateBatchId(batchStart.clientId, batchStart.batchStartCsn);
|
|
79
74
|
}
|
|
80
75
|
|
|
81
|
-
/**
|
|
82
|
-
* Estimated size of the stringification overhead for an op accumulated
|
|
83
|
-
* from runtime to loader to the service.
|
|
84
|
-
*/
|
|
85
|
-
const opOverhead = 200;
|
|
86
|
-
|
|
87
76
|
/**
|
|
88
77
|
* Helper class that manages partial batch & rollback.
|
|
89
78
|
*/
|
|
90
79
|
export class BatchManager {
|
|
91
80
|
private pendingBatch: LocalBatchMessage[] = [];
|
|
92
|
-
private batchContentSize = 0;
|
|
93
81
|
private hasReentrantOps = false;
|
|
94
82
|
|
|
95
83
|
public get length(): number {
|
|
96
84
|
return this.pendingBatch.length;
|
|
97
85
|
}
|
|
98
|
-
public get contentSizeInBytes(): number {
|
|
99
|
-
return this.batchContentSize;
|
|
100
|
-
}
|
|
101
86
|
|
|
102
87
|
public get sequenceNumbers(): BatchSequenceNumbers {
|
|
103
88
|
return {
|
|
@@ -125,29 +110,14 @@ export class BatchManager {
|
|
|
125
110
|
message: LocalBatchMessage,
|
|
126
111
|
reentrant: boolean,
|
|
127
112
|
currentClientSequenceNumber?: number,
|
|
128
|
-
):
|
|
129
|
-
const contentSize = this.batchContentSize + (message.serializedOp?.length ?? 0);
|
|
130
|
-
const opCount = this.pendingBatch.length;
|
|
113
|
+
): void {
|
|
131
114
|
this.hasReentrantOps = this.hasReentrantOps || reentrant;
|
|
132
115
|
|
|
133
|
-
// Attempt to estimate batch size, aka socket message size.
|
|
134
|
-
// Each op has pretty large envelope, estimating to be 200 bytes.
|
|
135
|
-
// Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.
|
|
136
|
-
// Not taking it into account, as compression work should help there - compressed payload will be
|
|
137
|
-
// initially stored as base64, and that requires only 2 extra escape characters.
|
|
138
|
-
const socketMessageSize = contentSize + opOverhead * opCount;
|
|
139
|
-
|
|
140
|
-
if (socketMessageSize >= this.options.hardLimit) {
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
116
|
if (this.pendingBatch.length === 0) {
|
|
145
117
|
this.clientSequenceNumber = currentClientSequenceNumber;
|
|
146
118
|
}
|
|
147
119
|
|
|
148
|
-
this.batchContentSize = contentSize;
|
|
149
120
|
this.pendingBatch.push(message);
|
|
150
|
-
return true;
|
|
151
121
|
}
|
|
152
122
|
|
|
153
123
|
public get empty(): boolean {
|
|
@@ -158,15 +128,15 @@ export class BatchManager {
|
|
|
158
128
|
* Gets the pending batch and clears state for the next batch.
|
|
159
129
|
*/
|
|
160
130
|
public popBatch(batchId?: BatchId): LocalBatch {
|
|
131
|
+
assert(this.pendingBatch[0] !== undefined, 0xb8a /* expected non-empty batch */);
|
|
161
132
|
const batch: LocalBatch = {
|
|
162
133
|
messages: this.pendingBatch,
|
|
163
|
-
contentSizeInBytes: this.batchContentSize,
|
|
164
134
|
referenceSequenceNumber: this.referenceSequenceNumber,
|
|
165
135
|
hasReentrantOps: this.hasReentrantOps,
|
|
136
|
+
staged: this.pendingBatch[0].staged,
|
|
166
137
|
};
|
|
167
138
|
|
|
168
139
|
this.pendingBatch = [];
|
|
169
|
-
this.batchContentSize = 0;
|
|
170
140
|
this.clientSequenceNumber = undefined;
|
|
171
141
|
this.hasReentrantOps = false;
|
|
172
142
|
|
|
@@ -184,7 +154,6 @@ export class BatchManager {
|
|
|
184
154
|
this.clientSequenceNumber = startSequenceNumber;
|
|
185
155
|
const rollbackOpsLifo = this.pendingBatch.splice(startPoint).reverse();
|
|
186
156
|
for (const message of rollbackOpsLifo) {
|
|
187
|
-
this.batchContentSize -= message.serializedOp?.length ?? 0;
|
|
188
157
|
process(message);
|
|
189
158
|
}
|
|
190
159
|
const count = this.pendingBatch.length - startPoint;
|
|
@@ -192,9 +161,7 @@ export class BatchManager {
|
|
|
192
161
|
throw new LoggingError("Ops generated during rollback", {
|
|
193
162
|
count,
|
|
194
163
|
...tagData(TelemetryDataTag.UserData, {
|
|
195
|
-
ops:
|
|
196
|
-
this.pendingBatch.slice(startPoint).map((b) => b.serializedOp),
|
|
197
|
-
),
|
|
164
|
+
ops: serializeOp(this.pendingBatch.slice(startPoint).map((b) => b.runtimeOp)),
|
|
198
165
|
}),
|
|
199
166
|
});
|
|
200
167
|
}
|
|
@@ -233,18 +200,6 @@ const addBatchMetadata = (batch: LocalBatch, batchId?: BatchId): LocalBatch => {
|
|
|
233
200
|
return batch;
|
|
234
201
|
};
|
|
235
202
|
|
|
236
|
-
/**
|
|
237
|
-
* Estimates the real size in bytes on the socket for a given batch. It assumes that
|
|
238
|
-
* the envelope size (and the size of an empty op) is 200 bytes, taking into account
|
|
239
|
-
* extra overhead from stringification.
|
|
240
|
-
*
|
|
241
|
-
* @param batch - the batch to inspect
|
|
242
|
-
* @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
|
|
243
|
-
*/
|
|
244
|
-
export const estimateSocketSize = (batch: OutboundBatch): number => {
|
|
245
|
-
return batch.contentSizeInBytes + opOverhead * batch.messages.length;
|
|
246
|
-
};
|
|
247
|
-
|
|
248
203
|
export const sequenceNumbersMatch = (
|
|
249
204
|
seqNums: BatchSequenceNumbers,
|
|
250
205
|
otherSeqNums: BatchSequenceNumbers,
|
|
@@ -5,17 +5,33 @@
|
|
|
5
5
|
|
|
6
6
|
import type { IBatchMessage } from "@fluidframework/container-definitions/internal";
|
|
7
7
|
|
|
8
|
-
import { CompressionAlgorithms } from "../
|
|
8
|
+
import { CompressionAlgorithms } from "../compressionDefinitions.js";
|
|
9
|
+
import type { LocalContainerRuntimeMessage } from "../messageTypes.js";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Local Batch message, before it is virtualized and sent to the ordering service
|
|
12
13
|
*/
|
|
13
14
|
export interface LocalBatchMessage {
|
|
14
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The original local op
|
|
17
|
+
*/
|
|
18
|
+
runtimeOp: LocalContainerRuntimeMessage;
|
|
19
|
+
/**
|
|
20
|
+
* Optional metadata which is not to be serialized with the op, and is visible to the ordering service
|
|
21
|
+
*/
|
|
15
22
|
metadata?: Record<string, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* Metadata used by this local client in flows such as rebase
|
|
25
|
+
*/
|
|
16
26
|
localOpMetadata?: unknown;
|
|
27
|
+
/**
|
|
28
|
+
* Reference sequence number this op is based on
|
|
29
|
+
*/
|
|
17
30
|
referenceSequenceNumber: number;
|
|
18
|
-
|
|
31
|
+
/**
|
|
32
|
+
* If true, this op is not to be submitted to the ordering service yet, since it was submitted during Staging Mode
|
|
33
|
+
*/
|
|
34
|
+
staged?: boolean;
|
|
19
35
|
|
|
20
36
|
/**
|
|
21
37
|
* @deprecated Use serializedOp
|
|
@@ -23,6 +39,15 @@ export interface LocalBatchMessage {
|
|
|
23
39
|
contents?: never; // To ensure we don't leave this one when converting from OutboundBatchMessage
|
|
24
40
|
}
|
|
25
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Placeholder for an empty batch, for tracking the pending local empty batch
|
|
44
|
+
*/
|
|
45
|
+
export interface LocalEmptyBatchPlaceholder {
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
localOpMetadata: { emptyBatch: true };
|
|
48
|
+
referenceSequenceNumber: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
26
51
|
/**
|
|
27
52
|
* Virtualized Batch message, on its way out the door to the ordering service
|
|
28
53
|
*/
|
|
@@ -40,30 +65,39 @@ export type OutboundBatchMessage = IBatchMessage & {
|
|
|
40
65
|
/**
|
|
41
66
|
* A batch of messages we have accumulated locally, but haven't sent to the ordering service yet.
|
|
42
67
|
*/
|
|
43
|
-
export
|
|
68
|
+
export interface LocalBatch extends IBatch<LocalBatchMessage[]> {
|
|
69
|
+
/**
|
|
70
|
+
* If true, this batch is not to be submitted to the ordering service yet, since it was submitted during Staging Mode
|
|
71
|
+
*/
|
|
72
|
+
staged?: boolean;
|
|
73
|
+
}
|
|
44
74
|
|
|
45
75
|
/**
|
|
46
76
|
* A batch of messages that has been virtualized as needed (grouped, compressed, chunked)
|
|
47
77
|
* and is ready to be sent to the ordering service.
|
|
78
|
+
* At the very least, the op contents have been serialized to string.
|
|
48
79
|
*/
|
|
49
|
-
export
|
|
80
|
+
export interface OutboundBatch<
|
|
81
|
+
TMessages extends OutboundBatchMessage[] = OutboundBatchMessage[],
|
|
82
|
+
> extends IBatch<TMessages> {
|
|
83
|
+
/**
|
|
84
|
+
* Sum of the in-memory content sizes of all messages in the batch.
|
|
85
|
+
* If the batch is compressed, this number reflects the post-compression size.
|
|
86
|
+
*/
|
|
87
|
+
readonly contentSizeInBytes: number;
|
|
88
|
+
}
|
|
50
89
|
|
|
51
90
|
/**
|
|
52
91
|
* An {@link OutboundBatch} with exactly one message
|
|
53
92
|
* This type is helpful as Grouping yields this kind of batch, and Compression only operates on this type of batch.
|
|
54
93
|
*/
|
|
55
|
-
export type OutboundSingletonBatch =
|
|
94
|
+
export type OutboundSingletonBatch = OutboundBatch<[OutboundBatchMessage]>;
|
|
56
95
|
|
|
57
96
|
/**
|
|
58
97
|
* Base batch interface used internally by the runtime.
|
|
59
98
|
* See {@link LocalBatch} and {@link OutboundBatch} for the concrete types.
|
|
60
99
|
*/
|
|
61
100
|
interface IBatch<TMessages extends LocalBatchMessage[] | OutboundBatchMessage[]> {
|
|
62
|
-
/**
|
|
63
|
-
* Sum of the in-memory content sizes of all messages in the batch.
|
|
64
|
-
* If the batch is compressed, this number reflects the post-compression size.
|
|
65
|
-
*/
|
|
66
|
-
readonly contentSizeInBytes: number;
|
|
67
101
|
/**
|
|
68
102
|
* All the messages in the batch
|
|
69
103
|
*/
|