@fluidframework/container-runtime 2.0.0-internal.7.0.0 → 2.0.0-internal.7.2.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 +12 -0
- package/api-extractor.json +1 -1
- package/api-report/container-runtime.api.md +864 -0
- package/dist/blobManager.d.ts +4 -6
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +42 -56
- package/dist/blobManager.js.map +1 -1
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js +75 -42
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +90 -36
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +125 -59
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.js +2 -2
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +8 -2
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +15 -8
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreRegistry.d.ts +3 -0
- package/dist/dataStoreRegistry.d.ts.map +1 -1
- package/dist/dataStoreRegistry.js +3 -0
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/dataStores.d.ts +0 -2
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +2 -7
- package/dist/dataStores.js.map +1 -1
- package/dist/deltaManagerProxyBase.d.ts +1 -1
- package/dist/deltaManagerProxyBase.d.ts.map +1 -1
- package/dist/deltaManagerProxyBase.js +2 -2
- package/dist/deltaManagerProxyBase.js.map +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +6 -0
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +16 -3
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts +1 -0
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +12 -2
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +42 -11
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +4 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
- package/dist/gc/gcSummaryDefinitions.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +2 -3
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +7 -8
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/index.d.ts +2 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +1 -5
- package/dist/gc/index.js.map +1 -1
- package/dist/id-compressor/utilities.d.ts +3 -0
- package/dist/id-compressor/utilities.d.ts.map +1 -1
- package/dist/id-compressor/utilities.js +3 -0
- package/dist/id-compressor/utilities.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +4 -1
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.js +3 -0
- package/dist/messageTypes.js.map +1 -1
- package/dist/opLifecycle/definitions.d.ts +3 -0
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +7 -2
- 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.map +1 -1
- package/dist/pendingStateManager.js +3 -1
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.js +6 -2
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +4 -1
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts +5 -0
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +1 -0
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/summarizer.d.ts +2 -0
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +15 -7
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +94 -10
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +16 -0
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js +2 -0
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +10 -1
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +2 -2
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +3 -3
- package/dist/summary/summaryManager.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/blobManager.d.ts +4 -6
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +44 -58
- package/lib/blobManager.js.map +1 -1
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js +76 -43
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +90 -36
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +125 -62
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.js +2 -2
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +8 -2
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +16 -9
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreRegistry.d.ts +3 -0
- package/lib/dataStoreRegistry.d.ts.map +1 -1
- package/lib/dataStoreRegistry.js +3 -0
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/dataStores.d.ts +0 -2
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +3 -8
- package/lib/dataStores.js.map +1 -1
- package/lib/deltaManagerProxyBase.d.ts +1 -1
- package/lib/deltaManagerProxyBase.d.ts.map +1 -1
- package/lib/deltaManagerProxyBase.js +2 -2
- package/lib/deltaManagerProxyBase.js.map +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +6 -0
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +16 -3
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts +1 -0
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +14 -4
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +42 -11
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +4 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
- package/lib/gc/gcSummaryDefinitions.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +2 -3
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +7 -8
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/index.d.ts +2 -2
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +2 -2
- package/lib/gc/index.js.map +1 -1
- package/lib/id-compressor/utilities.d.ts +3 -0
- package/lib/id-compressor/utilities.d.ts.map +1 -1
- package/lib/id-compressor/utilities.js +3 -0
- package/lib/id-compressor/utilities.js.map +1 -1
- package/lib/index.d.ts +4 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +4 -1
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.js +3 -0
- package/lib/messageTypes.js.map +1 -1
- package/lib/opLifecycle/definitions.d.ts +3 -0
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +7 -2
- 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.map +1 -1
- package/lib/pendingStateManager.js +3 -1
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.js +6 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +4 -1
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts +5 -0
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +1 -0
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -0
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +16 -8
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +94 -10
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +16 -0
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js +2 -0
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +10 -1
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +2 -2
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +3 -3
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +26 -58
- package/src/blobManager.ts +61 -74
- package/src/connectionTelemetry.ts +97 -52
- package/src/containerRuntime.ts +173 -93
- package/src/dataStore.ts +2 -2
- package/src/dataStoreContext.ts +16 -9
- package/src/dataStoreRegistry.ts +3 -0
- package/src/dataStores.ts +4 -16
- package/src/deltaManagerProxyBase.ts +2 -2
- package/src/error.ts +4 -1
- package/src/gc/garbageCollection.ts +18 -3
- package/src/gc/gcConfigs.ts +22 -4
- package/src/gc/gcDefinitions.ts +43 -11
- package/src/gc/gcSummaryDefinitions.ts +1 -1
- package/src/gc/gcTelemetry.ts +8 -8
- package/src/gc/index.ts +0 -4
- package/src/id-compressor/utilities.ts +3 -0
- package/src/index.ts +14 -1
- package/src/messageTypes.ts +4 -1
- package/src/opLifecycle/README.md +53 -28
- package/src/opLifecycle/definitions.ts +3 -0
- package/src/opLifecycle/outbox.ts +3 -0
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +1 -0
- package/src/scheduleManager.ts +2 -0
- package/src/summary/orderedClientElection.ts +4 -1
- package/src/summary/runWhileConnectedCoordinator.ts +5 -1
- package/src/summary/summarizer.ts +21 -9
- package/src/summary/summarizerTypes.ts +95 -11
- package/src/summary/summaryCollection.ts +19 -1
- package/src/summary/summaryFormat.ts +11 -1
- package/src/summary/summaryGenerator.ts +3 -3
- package/src/summary/summaryManager.ts +2 -2
- package/src/gc/gcEarlyAdoption.md +0 -145
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Configs and feature gates for solving the 1MB limit.
|
|
2
2
|
|
|
3
|
+
## Table of contents
|
|
4
|
+
|
|
5
|
+
- [Introduction](#introduction)
|
|
6
|
+
- [How batching works](#how-batching-works)
|
|
7
|
+
- [Compression](#compression)
|
|
8
|
+
- [Grouped batching](#grouped-batching)
|
|
9
|
+
- [Risks](#risks)
|
|
10
|
+
- [Chunking for compression](#chunking-for-compression)
|
|
11
|
+
- [Disabling in case of emergency](#disabling-in-case-of-emergency)
|
|
12
|
+
- [Example configs](#example-configs)
|
|
13
|
+
- [Note about performance and latency](#note-about-performance-and-latency)
|
|
14
|
+
- [How it works](#how-it-works)
|
|
15
|
+
- [How grouped batching works](#how-grouped-batching-works)
|
|
16
|
+
|
|
3
17
|
## Introduction
|
|
4
18
|
|
|
5
19
|
There is a current limitation regarding the size of the payload a Fluid client can send and receive. [The limit is 1MB per payload](https://github.com/microsoft/FluidFramework/issues/9023) and it is currently enforced explicitly with the `BatchTooLarge` error which closes the container.
|
|
@@ -8,17 +22,35 @@ There are two features which can be used to work around this size limit, batch c
|
|
|
8
22
|
|
|
9
23
|
By default, the runtime is configured with a max batch size of `716800` bytes, which is lower than the 1MB limit. The reason for the lower value is to account for possible overhead from the op envelope and metadata.
|
|
10
24
|
|
|
11
|
-
|
|
25
|
+
### How batching works
|
|
12
26
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
Batching in the context of Fluid ops is a way in which the framework accumulates and applies ops. A batch is a group of ops accumulated within a single JS turn, which will be broadcasted in the same order to all the other connected clients and applied synchronously. Additional logic and validation ensure that batches are never interleaved, nested or interrupted and they are processed in isolation without interleaving of ops from other clients.
|
|
28
|
+
|
|
29
|
+
The way batches are formed is governed by the `FlushMode` setting of the `ContainerRuntimeOptions` and it is immutable for the entire lifetime of the runtime and subsequently the container.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
export enum FlushMode {
|
|
33
|
+
/**
|
|
34
|
+
* In Immediate flush mode the runtime will immediately send all operations to the driver layer.
|
|
35
|
+
*/
|
|
36
|
+
Immediate,
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* When in TurnBased flush mode the runtime will buffer operations in the current turn and send them as a single
|
|
40
|
+
* batch at the end of the turn. The flush call on the runtime can be used to force send the current batch.
|
|
41
|
+
*/
|
|
42
|
+
TurnBased,
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
What this means is that `FlushMode.Immediate` will send each op in its own payload to the server, while `FlushMode.TurnBased` will accumulate all ops in a single JS turn and send them together in the same payload. Technically, `FlushMode.Immediate` can be simulated with `FlushMode.TurnBased` by interrupting the JS turn after producing only one op (for example by pausing the execution to wait on a promise). Therefore, for all intents and purposes, `FlushMode.Immediate` enables all batches to have only one op.
|
|
47
|
+
|
|
48
|
+
**By default, Fluid uses `FlushMode.TurnBased`** as:
|
|
49
|
+
|
|
50
|
+
- it is more efficient from an I/O perspective (batching ops overall decrease the number of payloads sent to the server)
|
|
51
|
+
- reduces concurrency related bugs, as it ensures that all ops generated within the same JS turn are also applied by all other clients within a single JS turn. Clients using the same pattern can safely assume ops will be applied exactly as they are observed locally. The alternative would be for ops to be both produced and applied with interruptions (which may involve processing input or rendering), invalidating the state based off which the changes were produced.
|
|
52
|
+
|
|
53
|
+
As `FlushMode.TurnBased` accumulates ops, it is the most vulnerable to run into the 1MB socket limit.
|
|
22
54
|
|
|
23
55
|
## Compression
|
|
24
56
|
|
|
@@ -29,6 +61,8 @@ By default, the runtime is configured with a max batch size of `716800` bytes, w
|
|
|
29
61
|
- `minimumBatchSizeInBytes` – the minimum size of the batch for which compression should kick in. If the payload is too small, compression may not yield too many benefits. To target the original 1MB issue, a good value here would be to match the default maxBatchSizeInBytes (972800), however, experimentally, a good lower value could be at around 614400 bytes. Setting this value to `Number.POSITIVE_INFINITY` will disable compression.
|
|
30
62
|
- `compressionAlgorithm` – currently, only `lz4` is supported.
|
|
31
63
|
|
|
64
|
+
Compression is relevant for both `FlushMode.TurnBased` and `FlushMode.Immediate` as it only targets the contents of the ops and not the number of ops in a batch. Compression is opaque to the server and implementations of the Fluid protocol do not need to alter their behavior to support this client feature.
|
|
65
|
+
|
|
32
66
|
## Grouped batching
|
|
33
67
|
|
|
34
68
|
**Note: This feature is currently considered experimental and is not ready for production usage.**
|
|
@@ -71,6 +105,8 @@ If all prerequisites in the previous section are met, enabling the feature can b
|
|
|
71
105
|
|
|
72
106
|
In case of emergency grouped batching can be disabled at runtime, using feature gates. If `"Fluid.ContainerRuntime.DisableGroupedBatching"` is set to `true`, it will disable grouped batching if enabled from `IContainerRuntimeOptions` in the code.
|
|
73
107
|
|
|
108
|
+
Grouped batching is only relevant for `FlushMode.TurnBased` as it only targets the number of ops in a batch. Grouped batching is opaque to the server and implementations of the Fluid protocol do not need to alter their behavior to support this client feature.
|
|
109
|
+
|
|
74
110
|
## Chunking for compression
|
|
75
111
|
|
|
76
112
|
**Op chunking for compression targets payloads which exceed the max batch size after compression.** So, only payloads which are already compressed. By default, the feature is enabled.
|
|
@@ -79,6 +115,8 @@ The `IContainerRuntimeOptions.chunkSizeInBytes` property is the only configurati
|
|
|
79
115
|
|
|
80
116
|
This config would govern chunking compressed batches only. We will not be enabling chunking across all types of ops/batches but **only when compression is enabled and when the batch is compressed**, and its payload size is more than `IContainerRuntimeOptions.chunkSizeInBytes`.
|
|
81
117
|
|
|
118
|
+
Chunking is relevant for both `FlushMode.TurnBased` and `FlushMode.Immediate` as it only targets the contents of the ops and not the number of ops in a batch. Chunking is opaque to the server and implementations of the Fluid protocol do not need to alter their behavior to support this client feature.
|
|
119
|
+
|
|
82
120
|
## Disabling in case of emergency
|
|
83
121
|
|
|
84
122
|
If the features are enabled using the configs, they can be disabled at runtime via feature gates as following:
|
|
@@ -102,32 +140,19 @@ By default, the runtime is configured with the following values related to compr
|
|
|
102
140
|
}
|
|
103
141
|
```
|
|
104
142
|
|
|
105
|
-
To use
|
|
143
|
+
To enable grouped batching, use the following property:
|
|
106
144
|
|
|
107
145
|
```
|
|
108
146
|
const runtimeOptions: IContainerRuntimeOptions = {
|
|
109
|
-
|
|
147
|
+
enableGroupedBatching: true,
|
|
110
148
|
}
|
|
111
149
|
```
|
|
112
150
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```
|
|
116
|
-
const runtimeOptions: IContainerRuntimeOptions = {
|
|
117
|
-
compressionOptions: {
|
|
118
|
-
minimumBatchSizeInBytes: Number.POSITIVE_INFINITY,
|
|
119
|
-
compressionAlgorithm: CompressionAlgorithms.lz4,
|
|
120
|
-
},
|
|
121
|
-
}
|
|
122
|
-
```
|
|
151
|
+
## Note about performance and latency
|
|
123
152
|
|
|
124
|
-
|
|
153
|
+
In terms of performance and impact on latency, the results greatly depend on payload size, payload structure, network speed and CPU speed. Therefore, customers must perform the required measurements and adjust the settings according to their scenarios.
|
|
125
154
|
|
|
126
|
-
|
|
127
|
-
const runtimeOptions: IContainerRuntimeOptions = {
|
|
128
|
-
enableGroupedBatching: true,
|
|
129
|
-
}
|
|
130
|
-
```
|
|
155
|
+
In general, compression offers a trade-off between higher compute costs, lower bandwidth consumption and lower storage requirements, while chunking slightly increases latency due to the overhead of splitting an op, sending the chunks and reconstructing them on each client. Grouped batching heavily decreases the number of ops observed by the server and slightly decreases the bandwidth requirements as it merges all the ops in a batch into a single op and also eliminates the op envelope overhead.
|
|
131
156
|
|
|
132
157
|
## How it works
|
|
133
158
|
|
|
@@ -65,10 +65,13 @@ export interface IOutboxParameters {
|
|
|
65
65
|
export function getLongStack<T>(action: () => T, length: number = 50): T {
|
|
66
66
|
const errorObj = Error as any;
|
|
67
67
|
if (
|
|
68
|
+
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
|
|
69
|
+
// ?? is not logically equivalent when the first clause returns false.
|
|
68
70
|
(
|
|
69
71
|
Object.getOwnPropertyDescriptor(errorObj, "stackTraceLimit") ||
|
|
70
72
|
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(errorObj), "stackTraceLimit")
|
|
71
73
|
)?.writable !== true
|
|
74
|
+
/* eslint-enable @typescript-eslint/prefer-nullish-coalescing */
|
|
72
75
|
) {
|
|
73
76
|
return action();
|
|
74
77
|
}
|
package/src/packageVersion.ts
CHANGED
|
@@ -318,6 +318,7 @@ export class PendingStateManager implements IDisposable {
|
|
|
318
318
|
{
|
|
319
319
|
runtimeVersion: pkgVersion,
|
|
320
320
|
batchClientId:
|
|
321
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
321
322
|
this.pendingBatchBeginMessage.clientId === null
|
|
322
323
|
? "null"
|
|
323
324
|
: this.pendingBatchBeginMessage.clientId,
|
package/src/scheduleManager.ts
CHANGED
|
@@ -271,6 +271,7 @@ class ScheduleManagerCore {
|
|
|
271
271
|
{
|
|
272
272
|
runtimeVersion: pkgVersion,
|
|
273
273
|
batchClientId:
|
|
274
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
274
275
|
this.currentBatchClientId === null ? "null" : this.currentBatchClientId,
|
|
275
276
|
pauseSequenceNumber: this.pauseSequenceNumber,
|
|
276
277
|
localBatch: this.currentBatchClientId === this.getClientId(),
|
|
@@ -306,6 +307,7 @@ class ScheduleManagerCore {
|
|
|
306
307
|
throw new DataCorruptionError("OpBatchIncomplete", {
|
|
307
308
|
runtimeVersion: pkgVersion,
|
|
308
309
|
batchClientId:
|
|
310
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
309
311
|
this.currentBatchClientId === null ? "null" : this.currentBatchClientId,
|
|
310
312
|
pauseSequenceNumber: this.pauseSequenceNumber,
|
|
311
313
|
localBatch: this.currentBatchClientId === this.getClientId(),
|
|
@@ -225,7 +225,10 @@ export interface IOrderedClientElectionEvents extends IEvent {
|
|
|
225
225
|
);
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
/**
|
|
228
|
+
/**
|
|
229
|
+
* Serialized state of IOrderedClientElection.
|
|
230
|
+
* @public
|
|
231
|
+
*/
|
|
229
232
|
export interface ISerializedElection {
|
|
230
233
|
/** Sequence number at the time of the latest election. */
|
|
231
234
|
readonly electionSequenceNumber: number;
|
|
@@ -10,7 +10,10 @@ import {
|
|
|
10
10
|
ISummaryCancellationToken,
|
|
11
11
|
} from "./summarizerTypes";
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Similar to AbortController, but using promise instead of events
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
14
17
|
export interface ICancellableSummarizerController extends ISummaryCancellationToken {
|
|
15
18
|
stop(reason: SummarizerStopReason): void;
|
|
16
19
|
}
|
|
@@ -18,6 +21,7 @@ export interface ICancellableSummarizerController extends ISummaryCancellationTo
|
|
|
18
21
|
/**
|
|
19
22
|
* Can be useful in testing as well as in places where caller does not use cancellation.
|
|
20
23
|
* This object implements ISummaryCancellationToken interface but cancellation is never leveraged.
|
|
24
|
+
* @public
|
|
21
25
|
*/
|
|
22
26
|
export const neverCancelledSummaryToken: ISummaryCancellationToken = {
|
|
23
27
|
cancelled: false,
|
|
@@ -15,9 +15,8 @@ import {
|
|
|
15
15
|
} from "@fluidframework/telemetry-utils";
|
|
16
16
|
import { ILoader, LoaderHeader } from "@fluidframework/container-definitions";
|
|
17
17
|
import { DriverHeader } from "@fluidframework/driver-definitions";
|
|
18
|
-
// eslint-disable-next-line import/no-deprecated
|
|
19
|
-
import { requestFluidObject } from "@fluidframework/runtime-utils";
|
|
20
18
|
import { FluidObject, IFluidHandleContext, IRequest } from "@fluidframework/core-interfaces";
|
|
19
|
+
import { responseToException } from "@fluidframework/runtime-utils";
|
|
21
20
|
import { ISummaryConfiguration } from "../containerRuntime";
|
|
22
21
|
import { ICancellableSummarizerController } from "./runWhileConnectedCoordinator";
|
|
23
22
|
import { summarizerClientType } from "./summarizerClientElection";
|
|
@@ -50,7 +49,10 @@ export class SummarizingWarning
|
|
|
50
49
|
readonly errorType = summarizingError;
|
|
51
50
|
readonly canRetry = true;
|
|
52
51
|
|
|
53
|
-
constructor(
|
|
52
|
+
constructor(
|
|
53
|
+
errorMessage: string,
|
|
54
|
+
readonly logged: boolean = false,
|
|
55
|
+
) {
|
|
54
56
|
super(errorMessage);
|
|
55
57
|
}
|
|
56
58
|
|
|
@@ -67,6 +69,7 @@ export const createSummarizingWarning = (errorMessage: string, logged: boolean)
|
|
|
67
69
|
* Summarizer is responsible for coordinating when to generate and send summaries.
|
|
68
70
|
* It is the main entry point for summary work.
|
|
69
71
|
* It is created only by summarizing container (i.e. one with clientType === "summarizer")
|
|
72
|
+
* @public
|
|
70
73
|
*/
|
|
71
74
|
export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements ISummarizer {
|
|
72
75
|
public get ISummarizer() {
|
|
@@ -108,6 +111,7 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
|
|
|
108
111
|
* interface will expect an absolute URL and will not handle "/".
|
|
109
112
|
* @param loader - the loader that resolves the request
|
|
110
113
|
* @param url - the URL used to resolve the container
|
|
114
|
+
* @deprecated Creating a summarizer is not a publicly supported API. Please remove all usage of this static method.
|
|
111
115
|
*/
|
|
112
116
|
public static async create(loader: ILoader, url: string): Promise<ISummarizer> {
|
|
113
117
|
const request: IRequest = {
|
|
@@ -124,12 +128,20 @@ export class Summarizer extends TypedEventEmitter<ISummarizerEvents> implements
|
|
|
124
128
|
};
|
|
125
129
|
|
|
126
130
|
const resolvedContainer = await loader.resolve(request);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
let fluidObject: FluidObject<ISummarizer> | undefined;
|
|
132
|
+
|
|
133
|
+
// Older containers may not have the "getEntryPoint" API
|
|
134
|
+
// ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
|
|
135
|
+
if (resolvedContainer.getEntryPoint !== undefined) {
|
|
136
|
+
fluidObject = await resolvedContainer.getEntryPoint();
|
|
137
|
+
} else {
|
|
138
|
+
const response = await resolvedContainer.request({ url: "_summarizer" });
|
|
139
|
+
if (response.status !== 200 || response.mimeType !== "fluid/object") {
|
|
140
|
+
throw responseToException(response, request);
|
|
141
|
+
}
|
|
142
|
+
fluidObject = response.value;
|
|
143
|
+
}
|
|
144
|
+
|
|
133
145
|
if (fluidObject?.ISummarizer === undefined) {
|
|
134
146
|
throw new UsageError("Fluid object does not implement ISummarizer");
|
|
135
147
|
}
|
|
@@ -19,6 +19,7 @@ import { SummarizeReason } from "./summaryGenerator";
|
|
|
19
19
|
/**
|
|
20
20
|
* Similar to AbortSignal, but using promise instead of events
|
|
21
21
|
* @param T - cancellation reason type
|
|
22
|
+
* @public
|
|
22
23
|
*/
|
|
23
24
|
export interface ICancellationToken<T> {
|
|
24
25
|
/** Tells if this cancellable token is cancelled */
|
|
@@ -30,11 +31,15 @@ export interface ICancellationToken<T> {
|
|
|
30
31
|
readonly waitCancelled: Promise<T>;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Similar to AbortSignal, but using promise instead of events
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
34
38
|
export type ISummaryCancellationToken = ICancellationToken<SummarizerStopReason>;
|
|
35
39
|
|
|
36
40
|
/**
|
|
37
41
|
* Data required to update internal tracking state after receiving a Summary Ack.
|
|
42
|
+
* @public
|
|
38
43
|
*/
|
|
39
44
|
export interface IRefreshSummaryAckOptions {
|
|
40
45
|
/** Handle from the ack's summary op. */
|
|
@@ -47,6 +52,9 @@ export interface IRefreshSummaryAckOptions {
|
|
|
47
52
|
readonly summaryLogger: ITelemetryLoggerExt;
|
|
48
53
|
}
|
|
49
54
|
|
|
55
|
+
/**
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
50
58
|
export interface ISummarizerInternalsProvider {
|
|
51
59
|
/** Encapsulates the work to walk the internals of the running container to generate a summary */
|
|
52
60
|
submitSummary(options: ISubmitSummaryOptions): Promise<SubmitSummaryResult>;
|
|
@@ -57,6 +65,7 @@ export interface ISummarizerInternalsProvider {
|
|
|
57
65
|
|
|
58
66
|
/**
|
|
59
67
|
* @deprecated Options that control the behavior of a running summarizer.
|
|
68
|
+
* @public
|
|
60
69
|
* */
|
|
61
70
|
export interface ISummarizerOptions {
|
|
62
71
|
/**
|
|
@@ -68,11 +77,17 @@ export interface ISummarizerOptions {
|
|
|
68
77
|
disableHeuristics: boolean;
|
|
69
78
|
}
|
|
70
79
|
|
|
80
|
+
/**
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
71
83
|
export interface ISummarizingWarning extends ContainerWarning {
|
|
72
84
|
readonly errorType: "summarizingError";
|
|
73
85
|
readonly logged: boolean;
|
|
74
86
|
}
|
|
75
87
|
|
|
88
|
+
/**
|
|
89
|
+
* @public
|
|
90
|
+
*/
|
|
76
91
|
export interface IConnectableRuntime {
|
|
77
92
|
readonly disposed: boolean;
|
|
78
93
|
readonly connected: boolean;
|
|
@@ -80,6 +95,9 @@ export interface IConnectableRuntime {
|
|
|
80
95
|
once(event: "connected" | "disconnected" | "dispose", listener: () => void): this;
|
|
81
96
|
}
|
|
82
97
|
|
|
98
|
+
/**
|
|
99
|
+
* @public
|
|
100
|
+
*/
|
|
83
101
|
export interface ISummarizerRuntime extends IConnectableRuntime {
|
|
84
102
|
readonly logger: ITelemetryLoggerExt;
|
|
85
103
|
/** clientId of parent (non-summarizing) container that owns summarizer container */
|
|
@@ -97,19 +115,25 @@ export interface ISummarizerRuntime extends IConnectableRuntime {
|
|
|
97
115
|
): this;
|
|
98
116
|
}
|
|
99
117
|
|
|
100
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* Options affecting summarize behavior.
|
|
120
|
+
* @public
|
|
121
|
+
*/
|
|
101
122
|
export interface ISummarizeOptions {
|
|
102
123
|
/** True to generate the full tree with no handle reuse optimizations; defaults to false */
|
|
103
124
|
readonly fullTree?: boolean;
|
|
104
125
|
/**
|
|
105
126
|
* True to ask the server what the latest summary is first; defaults to false
|
|
106
127
|
*
|
|
107
|
-
* @deprecated
|
|
128
|
+
* @deprecated Summarize will not refresh latest snapshot state anymore. Instead it updates the cache and closes.
|
|
108
129
|
* It's expected a new summarizer client will be created, likely by the same parent.
|
|
109
130
|
*/
|
|
110
131
|
readonly refreshLatestAck?: boolean;
|
|
111
132
|
}
|
|
112
133
|
|
|
134
|
+
/**
|
|
135
|
+
* @public
|
|
136
|
+
*/
|
|
113
137
|
export interface ISubmitSummaryOptions extends ISummarizeOptions {
|
|
114
138
|
/** Logger to use for correlated summary events */
|
|
115
139
|
readonly summaryLogger: ITelemetryLoggerExt;
|
|
@@ -119,12 +143,18 @@ export interface ISubmitSummaryOptions extends ISummarizeOptions {
|
|
|
119
143
|
readonly finalAttempt?: boolean;
|
|
120
144
|
}
|
|
121
145
|
|
|
146
|
+
/**
|
|
147
|
+
* @public
|
|
148
|
+
*/
|
|
122
149
|
export interface IOnDemandSummarizeOptions extends ISummarizeOptions {
|
|
123
150
|
/** Reason for generating summary. */
|
|
124
151
|
readonly reason: string;
|
|
125
152
|
}
|
|
126
153
|
|
|
127
|
-
/**
|
|
154
|
+
/**
|
|
155
|
+
* Options to use when enqueueing a summarize attempt.
|
|
156
|
+
* @public
|
|
157
|
+
*/
|
|
128
158
|
export interface IEnqueueSummarizeOptions extends IOnDemandSummarizeOptions {
|
|
129
159
|
/** If specified, The summarize attempt will not occur until after this sequence number. */
|
|
130
160
|
readonly afterSequenceNumber?: number;
|
|
@@ -141,6 +171,7 @@ export interface IEnqueueSummarizeOptions extends IOnDemandSummarizeOptions {
|
|
|
141
171
|
/**
|
|
142
172
|
* In addition to the normal summary tree + stats, this contains additional stats
|
|
143
173
|
* only relevant at the root of the tree.
|
|
174
|
+
* @public
|
|
144
175
|
*/
|
|
145
176
|
export interface IGeneratedSummaryStats extends ISummaryStats {
|
|
146
177
|
/** The total number of data stores in the container. */
|
|
@@ -157,7 +188,10 @@ export interface IGeneratedSummaryStats extends ISummaryStats {
|
|
|
157
188
|
readonly summaryNumber: number;
|
|
158
189
|
}
|
|
159
190
|
|
|
160
|
-
/**
|
|
191
|
+
/**
|
|
192
|
+
* Base results for all submitSummary attempts.
|
|
193
|
+
* @public
|
|
194
|
+
*/
|
|
161
195
|
export interface IBaseSummarizeResult {
|
|
162
196
|
readonly stage: "base";
|
|
163
197
|
/** Error object related to failed summarize attempt. */
|
|
@@ -167,7 +201,10 @@ export interface IBaseSummarizeResult {
|
|
|
167
201
|
readonly minimumSequenceNumber: number;
|
|
168
202
|
}
|
|
169
203
|
|
|
170
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Results of submitSummary after generating the summary tree.
|
|
206
|
+
* @public
|
|
207
|
+
*/
|
|
171
208
|
export interface IGenerateSummaryTreeResult extends Omit<IBaseSummarizeResult, "stage"> {
|
|
172
209
|
readonly stage: "generate";
|
|
173
210
|
/** Generated summary tree. */
|
|
@@ -180,7 +217,10 @@ export interface IGenerateSummaryTreeResult extends Omit<IBaseSummarizeResult, "
|
|
|
180
217
|
readonly forcedFullTree: boolean;
|
|
181
218
|
}
|
|
182
219
|
|
|
183
|
-
/**
|
|
220
|
+
/**
|
|
221
|
+
* Results of submitSummary after uploading the tree to storage.
|
|
222
|
+
* @public
|
|
223
|
+
*/
|
|
184
224
|
export interface IUploadSummaryResult extends Omit<IGenerateSummaryTreeResult, "stage"> {
|
|
185
225
|
readonly stage: "upload";
|
|
186
226
|
/** The handle returned by storage pointing to the uploaded summary tree. */
|
|
@@ -189,7 +229,10 @@ export interface IUploadSummaryResult extends Omit<IGenerateSummaryTreeResult, "
|
|
|
189
229
|
readonly uploadDuration: number;
|
|
190
230
|
}
|
|
191
231
|
|
|
192
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* Results of submitSummary after submitting the summarize op.
|
|
234
|
+
* @public
|
|
235
|
+
*/
|
|
193
236
|
export interface ISubmitSummaryOpResult extends Omit<IUploadSummaryResult, "stage" | "error"> {
|
|
194
237
|
readonly stage: "submit";
|
|
195
238
|
/** The client sequence number of the summarize op submitted for the summary. */
|
|
@@ -213,6 +256,7 @@ export interface ISubmitSummaryOpResult extends Omit<IUploadSummaryResult, "stag
|
|
|
213
256
|
* 3. "upload" - the summary was uploaded to storage, and the result contains the server-provided handle
|
|
214
257
|
*
|
|
215
258
|
* 4. "submit" - the summarize op was submitted, and the result contains the op client sequence number.
|
|
259
|
+
* @public
|
|
216
260
|
*/
|
|
217
261
|
export type SubmitSummaryResult =
|
|
218
262
|
| IBaseSummarizeResult
|
|
@@ -220,34 +264,55 @@ export type SubmitSummaryResult =
|
|
|
220
264
|
| IUploadSummaryResult
|
|
221
265
|
| ISubmitSummaryOpResult;
|
|
222
266
|
|
|
223
|
-
/**
|
|
267
|
+
/**
|
|
268
|
+
* The stages of Summarize, used to describe how far progress succeeded in case of a failure at a later stage.
|
|
269
|
+
* @public
|
|
270
|
+
*/
|
|
224
271
|
export type SummaryStage = SubmitSummaryResult["stage"] | "unknown";
|
|
225
272
|
|
|
226
|
-
/**
|
|
273
|
+
/**
|
|
274
|
+
* Type for summarization failures that are retriable.
|
|
275
|
+
* @public
|
|
276
|
+
*/
|
|
227
277
|
export interface IRetriableFailureResult {
|
|
228
278
|
readonly retryAfterSeconds?: number;
|
|
229
279
|
}
|
|
230
280
|
|
|
231
|
-
/**
|
|
281
|
+
/**
|
|
282
|
+
* The data in summarizer result when submit summary stage fails.
|
|
283
|
+
* @public
|
|
284
|
+
*/
|
|
232
285
|
export interface SubmitSummaryFailureData extends IRetriableFailureResult {
|
|
233
286
|
stage: SummaryStage;
|
|
234
287
|
}
|
|
235
288
|
|
|
289
|
+
/**
|
|
290
|
+
* @public
|
|
291
|
+
*/
|
|
236
292
|
export interface IBroadcastSummaryResult {
|
|
237
293
|
readonly summarizeOp: ISummaryOpMessage;
|
|
238
294
|
readonly broadcastDuration: number;
|
|
239
295
|
}
|
|
240
296
|
|
|
297
|
+
/**
|
|
298
|
+
* @public
|
|
299
|
+
*/
|
|
241
300
|
export interface IAckSummaryResult {
|
|
242
301
|
readonly summaryAckOp: ISummaryAckMessage;
|
|
243
302
|
readonly ackNackDuration: number;
|
|
244
303
|
}
|
|
245
304
|
|
|
305
|
+
/**
|
|
306
|
+
* @public
|
|
307
|
+
*/
|
|
246
308
|
export interface INackSummaryResult extends IRetriableFailureResult {
|
|
247
309
|
readonly summaryNackOp: ISummaryNackMessage;
|
|
248
310
|
readonly ackNackDuration: number;
|
|
249
311
|
}
|
|
250
312
|
|
|
313
|
+
/**
|
|
314
|
+
* @public
|
|
315
|
+
*/
|
|
251
316
|
export type SummarizeResultPart<TSuccess, TFailure = undefined> =
|
|
252
317
|
| {
|
|
253
318
|
success: true;
|
|
@@ -260,6 +325,9 @@ export type SummarizeResultPart<TSuccess, TFailure = undefined> =
|
|
|
260
325
|
error: any;
|
|
261
326
|
};
|
|
262
327
|
|
|
328
|
+
/**
|
|
329
|
+
* @public
|
|
330
|
+
*/
|
|
263
331
|
export interface ISummarizeResults {
|
|
264
332
|
/** Resolves when we generate, upload, and submit the summary. */
|
|
265
333
|
readonly summarySubmitted: Promise<
|
|
@@ -273,6 +341,9 @@ export interface ISummarizeResults {
|
|
|
273
341
|
>;
|
|
274
342
|
}
|
|
275
343
|
|
|
344
|
+
/**
|
|
345
|
+
* @public
|
|
346
|
+
*/
|
|
276
347
|
export type EnqueueSummarizeResult =
|
|
277
348
|
| (ISummarizeResults & {
|
|
278
349
|
/**
|
|
@@ -300,6 +371,9 @@ export type EnqueueSummarizeResult =
|
|
|
300
371
|
readonly overridden?: undefined;
|
|
301
372
|
};
|
|
302
373
|
|
|
374
|
+
/**
|
|
375
|
+
* @public
|
|
376
|
+
*/
|
|
303
377
|
export type SummarizerStopReason =
|
|
304
378
|
/** Summarizer client failed to summarize in all 3 consecutive attempts. */
|
|
305
379
|
| "failToSummarize"
|
|
@@ -326,16 +400,26 @@ export type SummarizerStopReason =
|
|
|
326
400
|
*/
|
|
327
401
|
| "latestSummaryStateStale";
|
|
328
402
|
|
|
403
|
+
/**
|
|
404
|
+
* @public
|
|
405
|
+
*/
|
|
329
406
|
export interface ISummarizeEventProps {
|
|
330
407
|
result: "success" | "failure" | "canceled";
|
|
331
408
|
currentAttempt: number;
|
|
332
409
|
maxAttempts: number;
|
|
333
410
|
error?: any;
|
|
334
411
|
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* @public
|
|
415
|
+
*/
|
|
335
416
|
export interface ISummarizerEvents extends IEvent {
|
|
336
417
|
(event: "summarize", listener: (props: ISummarizeEventProps) => void);
|
|
337
418
|
}
|
|
338
419
|
|
|
420
|
+
/**
|
|
421
|
+
* @public
|
|
422
|
+
*/
|
|
339
423
|
export interface ISummarizer extends IEventProvider<ISummarizerEvents> {
|
|
340
424
|
/**
|
|
341
425
|
* Allows {@link ISummarizer} to be used with our {@link @fluidframework/core-interfaces#FluidObject} pattern.
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Interface for summary op messages with typed contents.
|
|
22
|
+
* @public
|
|
22
23
|
*/
|
|
23
24
|
export interface ISummaryOpMessage extends ISequencedDocumentMessage {
|
|
24
25
|
type: MessageType.Summarize;
|
|
@@ -27,6 +28,7 @@ export interface ISummaryOpMessage extends ISequencedDocumentMessage {
|
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Interface for summary ack messages with typed contents.
|
|
31
|
+
* @public
|
|
30
32
|
*/
|
|
31
33
|
export interface ISummaryAckMessage extends ISequencedDocumentMessage {
|
|
32
34
|
type: MessageType.SummaryAck;
|
|
@@ -35,6 +37,7 @@ export interface ISummaryAckMessage extends ISequencedDocumentMessage {
|
|
|
35
37
|
|
|
36
38
|
/**
|
|
37
39
|
* Interface for summary nack messages with typed contents.
|
|
40
|
+
* @public
|
|
38
41
|
*/
|
|
39
42
|
export interface ISummaryNackMessage extends ISequencedDocumentMessage {
|
|
40
43
|
type: MessageType.SummaryNack;
|
|
@@ -44,6 +47,7 @@ export interface ISummaryNackMessage extends ISequencedDocumentMessage {
|
|
|
44
47
|
/**
|
|
45
48
|
* A single summary which can be tracked as it goes through its life cycle.
|
|
46
49
|
* The life cycle is: Local to Broadcast to Acked/Nacked.
|
|
50
|
+
* @public
|
|
47
51
|
*/
|
|
48
52
|
export interface ISummary {
|
|
49
53
|
readonly clientId: string;
|
|
@@ -54,6 +58,7 @@ export interface ISummary {
|
|
|
54
58
|
|
|
55
59
|
/**
|
|
56
60
|
* A single summary which has already been acked by the server.
|
|
61
|
+
* @public
|
|
57
62
|
*/
|
|
58
63
|
export interface IAckedSummary {
|
|
59
64
|
readonly summaryOp: ISummaryOpMessage;
|
|
@@ -140,6 +145,7 @@ class Summary implements ISummary {
|
|
|
140
145
|
|
|
141
146
|
/**
|
|
142
147
|
* Watches summaries created by a specific client.
|
|
148
|
+
* @public
|
|
143
149
|
*/
|
|
144
150
|
export interface IClientSummaryWatcher extends IDisposable {
|
|
145
151
|
watchSummary(clientSequenceNumber: number): ISummary;
|
|
@@ -207,13 +213,23 @@ class ClientSummaryWatcher implements IClientSummaryWatcher {
|
|
|
207
213
|
this._disposed = true;
|
|
208
214
|
}
|
|
209
215
|
}
|
|
210
|
-
|
|
216
|
+
/**
|
|
217
|
+
* @public
|
|
218
|
+
*/
|
|
211
219
|
export type OpActionEventName =
|
|
212
220
|
| MessageType.Summarize
|
|
213
221
|
| MessageType.SummaryAck
|
|
214
222
|
| MessageType.SummaryNack
|
|
215
223
|
| "default";
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @public
|
|
227
|
+
*/
|
|
216
228
|
export type OpActionEventListener = (op: ISequencedDocumentMessage) => void;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @public
|
|
232
|
+
*/
|
|
217
233
|
export interface ISummaryCollectionOpEvents extends IEvent {
|
|
218
234
|
(event: OpActionEventName, listener: OpActionEventListener);
|
|
219
235
|
}
|
|
@@ -222,6 +238,7 @@ export interface ISummaryCollectionOpEvents extends IEvent {
|
|
|
222
238
|
* Data structure that looks at the op stream to track summaries as they
|
|
223
239
|
* are broadcast, acked and nacked.
|
|
224
240
|
* It provides functionality for watching specific summaries.
|
|
241
|
+
* @public
|
|
225
242
|
*/
|
|
226
243
|
export class SummaryCollection extends TypedEventEmitter<ISummaryCollectionOpEvents> {
|
|
227
244
|
// key: clientId
|
|
@@ -405,6 +422,7 @@ export class SummaryCollection extends TypedEventEmitter<ISummaryCollectionOpEve
|
|
|
405
422
|
private handleSummaryAck(op: ISummaryAckMessage) {
|
|
406
423
|
const seq = op.contents.summaryProposal.summarySequenceNumber;
|
|
407
424
|
const summary = this.pendingSummaries.get(seq);
|
|
425
|
+
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- optional chain is not logically equivalent
|
|
408
426
|
if (!summary || summary.summaryOp === undefined) {
|
|
409
427
|
// Summary ack without an op should be rare. We could fetch the
|
|
410
428
|
// reference sequence number from the snapshot, but instead we
|