@fluidframework/container-runtime 2.0.0-internal.3.0.0 → 2.0.0-internal.3.1.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/.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 +10 -0
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +140 -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 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +66 -15
- 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 +34 -14
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +188 -93
- package/dist/garbageCollection.js.map +1 -1
- package/dist/garbageCollectionConstants.d.ts +3 -0
- package/dist/garbageCollectionConstants.d.ts.map +1 -1
- package/dist/garbageCollectionConstants.js +6 -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.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +5 -2
- 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 +19 -17
- 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 +22 -0
- 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 +34 -15
- 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 +10 -0
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +146 -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 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +68 -17
- 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 +34 -14
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +190 -95
- package/lib/garbageCollection.js.map +1 -1
- package/lib/garbageCollectionConstants.d.ts +3 -0
- package/lib/garbageCollectionConstants.d.ts.map +1 -1
- package/lib/garbageCollectionConstants.js +5 -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.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +5 -2
- 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 +19 -17
- 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 +22 -0
- 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 +34 -15
- 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 -149
- 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 -2940
- package/src/dataStore.ts +172 -159
- package/src/dataStoreContext.ts +1098 -996
- 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 +1883 -1692
- package/src/garbageCollectionConstants.ts +6 -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 -81
- package/src/opLifecycle/opSplitter.ts +214 -188
- package/src/opLifecycle/outbox.ts +204 -194
- 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 +170 -126
- package/src/summaryGenerator.ts +465 -406
- 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
package/src/summaryCollection.ts
CHANGED
|
@@ -7,36 +7,36 @@ import { IDisposable, IEvent, ITelemetryLogger } from "@fluidframework/common-de
|
|
|
7
7
|
import { Deferred, assert, TypedEventEmitter } from "@fluidframework/common-utils";
|
|
8
8
|
import { IDeltaManager } from "@fluidframework/container-definitions";
|
|
9
9
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
IDocumentMessage,
|
|
11
|
+
ISequencedDocumentMessage,
|
|
12
|
+
ISummaryAck,
|
|
13
|
+
ISummaryContent,
|
|
14
|
+
ISummaryNack,
|
|
15
|
+
MessageType,
|
|
16
16
|
} from "@fluidframework/protocol-definitions";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Interface for summary op messages with typed contents.
|
|
20
20
|
*/
|
|
21
21
|
export interface ISummaryOpMessage extends ISequencedDocumentMessage {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
type: MessageType.Summarize;
|
|
23
|
+
contents: ISummaryContent;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* Interface for summary ack messages with typed contents.
|
|
28
28
|
*/
|
|
29
29
|
export interface ISummaryAckMessage extends ISequencedDocumentMessage {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
type: MessageType.SummaryAck;
|
|
31
|
+
contents: ISummaryAck;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Interface for summary nack messages with typed contents.
|
|
36
36
|
*/
|
|
37
37
|
export interface ISummaryNackMessage extends ISequencedDocumentMessage {
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
type: MessageType.SummaryNack;
|
|
39
|
+
contents: ISummaryNack;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -44,92 +44,102 @@ export interface ISummaryNackMessage extends ISequencedDocumentMessage {
|
|
|
44
44
|
* The life cycle is: Local to Broadcast to Acked/Nacked.
|
|
45
45
|
*/
|
|
46
46
|
export interface ISummary {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
readonly clientId: string;
|
|
48
|
+
readonly clientSequenceNumber: number;
|
|
49
|
+
waitBroadcast(): Promise<ISummaryOpMessage>;
|
|
50
|
+
waitAckNack(): Promise<ISummaryAckMessage | ISummaryNackMessage>;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* A single summary which has already been acked by the server.
|
|
55
55
|
*/
|
|
56
56
|
export interface IAckedSummary {
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
readonly summaryOp: ISummaryOpMessage;
|
|
58
|
+
readonly summaryAck: ISummaryAckMessage;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
enum SummaryState {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
Local = 0,
|
|
63
|
+
Broadcast = 1,
|
|
64
|
+
Acked = 2,
|
|
65
|
+
Nacked = -1,
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
class Summary implements ISummary {
|
|
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
|
-
|
|
69
|
+
public static createLocal(clientId: string, clientSequenceNumber: number) {
|
|
70
|
+
return new Summary(clientId, clientSequenceNumber);
|
|
71
|
+
}
|
|
72
|
+
public static createFromOp(op: ISummaryOpMessage) {
|
|
73
|
+
const summary = new Summary(op.clientId, op.clientSequenceNumber);
|
|
74
|
+
summary.broadcast(op);
|
|
75
|
+
return summary;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private state = SummaryState.Local;
|
|
79
|
+
|
|
80
|
+
private _summaryOp?: ISummaryOpMessage;
|
|
81
|
+
private _summaryAckNack?: ISummaryAckMessage | ISummaryNackMessage;
|
|
82
|
+
|
|
83
|
+
private readonly defSummaryOp = new Deferred<void>();
|
|
84
|
+
private readonly defSummaryAck = new Deferred<void>();
|
|
85
|
+
|
|
86
|
+
public get summaryOp() {
|
|
87
|
+
return this._summaryOp;
|
|
88
|
+
}
|
|
89
|
+
public get summaryAckNack() {
|
|
90
|
+
return this._summaryAckNack;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private constructor(
|
|
94
|
+
public readonly clientId: string,
|
|
95
|
+
public readonly clientSequenceNumber: number,
|
|
96
|
+
) {}
|
|
97
|
+
|
|
98
|
+
public hasBeenAcked(): this is IAckedSummary {
|
|
99
|
+
return this.state === SummaryState.Acked;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public broadcast(op: ISummaryOpMessage) {
|
|
103
|
+
assert(
|
|
104
|
+
this.state === SummaryState.Local,
|
|
105
|
+
0x175 /* "Can only broadcast if summarizer starts in local state" */,
|
|
106
|
+
);
|
|
107
|
+
this._summaryOp = op;
|
|
108
|
+
this.defSummaryOp.resolve();
|
|
109
|
+
this.state = SummaryState.Broadcast;
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public ackNack(op: ISummaryAckMessage | ISummaryNackMessage) {
|
|
114
|
+
assert(
|
|
115
|
+
this.state === SummaryState.Broadcast,
|
|
116
|
+
0x176 /* "Can only ack/nack if summarizer is in broadcasting state" */,
|
|
117
|
+
);
|
|
118
|
+
this._summaryAckNack = op;
|
|
119
|
+
this.defSummaryAck.resolve();
|
|
120
|
+
this.state = op.type === MessageType.SummaryAck ? SummaryState.Acked : SummaryState.Nacked;
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
public async waitBroadcast(): Promise<ISummaryOpMessage> {
|
|
125
|
+
await this.defSummaryOp.promise;
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
127
|
+
return this._summaryOp!;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public async waitAckNack(): Promise<ISummaryAckMessage | ISummaryNackMessage> {
|
|
131
|
+
await this.defSummaryAck.promise;
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
133
|
+
return this._summaryAckNack!;
|
|
134
|
+
}
|
|
125
135
|
}
|
|
126
136
|
|
|
127
137
|
/**
|
|
128
138
|
* Watches summaries created by a specific client.
|
|
129
139
|
*/
|
|
130
140
|
export interface IClientSummaryWatcher extends IDisposable {
|
|
131
|
-
|
|
132
|
-
|
|
141
|
+
watchSummary(clientSequenceNumber: number): ISummary;
|
|
142
|
+
waitFlushed(): Promise<IAckedSummary | undefined>;
|
|
133
143
|
}
|
|
134
144
|
|
|
135
145
|
/**
|
|
@@ -137,65 +147,71 @@ export interface IClientSummaryWatcher extends IDisposable {
|
|
|
137
147
|
* It should be created and managed from a SummaryCollection.
|
|
138
148
|
*/
|
|
139
149
|
class ClientSummaryWatcher implements IClientSummaryWatcher {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
150
|
+
// key: clientSeqNum
|
|
151
|
+
private readonly localSummaries = new Map<number, Summary>();
|
|
152
|
+
private _disposed = false;
|
|
153
|
+
|
|
154
|
+
public get disposed() {
|
|
155
|
+
return this._disposed;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public constructor(
|
|
159
|
+
public readonly clientId: string,
|
|
160
|
+
private readonly summaryCollection: SummaryCollection,
|
|
161
|
+
) {}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Watches for a specific sent summary op.
|
|
165
|
+
* @param clientSequenceNumber - client sequence number of sent summary op
|
|
166
|
+
*/
|
|
167
|
+
public watchSummary(clientSequenceNumber: number): ISummary {
|
|
168
|
+
let summary = this.localSummaries.get(clientSequenceNumber);
|
|
169
|
+
if (!summary) {
|
|
170
|
+
summary = Summary.createLocal(this.clientId, clientSequenceNumber);
|
|
171
|
+
this.localSummaries.set(summary.clientSequenceNumber, summary);
|
|
172
|
+
}
|
|
173
|
+
return summary;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Waits until all of the pending summaries in the underlying SummaryCollection
|
|
178
|
+
* are acked/nacked.
|
|
179
|
+
*/
|
|
180
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
181
|
+
public waitFlushed() {
|
|
182
|
+
return this.summaryCollection.waitFlushed();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Gets a watched summary or returns undefined if not watched.
|
|
187
|
+
* @param clientSequenceNumber - client sequence number of sent summary op
|
|
188
|
+
*/
|
|
189
|
+
public tryGetSummary(clientSequenceNumber: number) {
|
|
190
|
+
return this.localSummaries.get(clientSequenceNumber);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Starts watching a summary made by this client.
|
|
195
|
+
* @param summary - summary to start watching
|
|
196
|
+
*/
|
|
197
|
+
public setSummary(summary: Summary) {
|
|
198
|
+
this.localSummaries.set(summary.clientSequenceNumber, summary);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public dispose() {
|
|
202
|
+
this.summaryCollection.removeWatcher(this.clientId);
|
|
203
|
+
this._disposed = true;
|
|
204
|
+
}
|
|
193
205
|
}
|
|
194
206
|
|
|
195
|
-
export type OpActionEventName =
|
|
207
|
+
export type OpActionEventName =
|
|
208
|
+
| MessageType.Summarize
|
|
209
|
+
| MessageType.SummaryAck
|
|
210
|
+
| MessageType.SummaryNack
|
|
211
|
+
| "default";
|
|
196
212
|
export type OpActionEventListener = (op: ISequencedDocumentMessage) => void;
|
|
197
213
|
export interface ISummaryCollectionOpEvents extends IEvent {
|
|
198
|
-
|
|
214
|
+
(event: OpActionEventName, listener: OpActionEventListener);
|
|
199
215
|
}
|
|
200
216
|
|
|
201
217
|
/**
|
|
@@ -204,218 +220,231 @@ export interface ISummaryCollectionOpEvents extends IEvent {
|
|
|
204
220
|
* It provides functionality for watching specific summaries.
|
|
205
221
|
*/
|
|
206
222
|
export class SummaryCollection extends TypedEventEmitter<ISummaryCollectionOpEvents> {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
223
|
+
// key: clientId
|
|
224
|
+
private readonly summaryWatchers = new Map<string, ClientSummaryWatcher>();
|
|
225
|
+
// key: summarySeqNum
|
|
226
|
+
private readonly pendingSummaries = new Map<number, Summary>();
|
|
227
|
+
private refreshWaitNextAck = new Deferred<void>();
|
|
228
|
+
|
|
229
|
+
private lastSummaryTimestamp: number | undefined;
|
|
230
|
+
private maxAckWaitTime: number | undefined;
|
|
231
|
+
private pendingAckTimerTimeoutCallback: (() => void) | undefined;
|
|
232
|
+
private lastAck: IAckedSummary | undefined;
|
|
233
|
+
|
|
234
|
+
public get latestAck(): IAckedSummary | undefined {
|
|
235
|
+
return this.lastAck;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
public emit(event: OpActionEventName, ...args: Parameters<OpActionEventListener>): boolean {
|
|
239
|
+
return super.emit(event, ...args);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public get opsSinceLastAck() {
|
|
243
|
+
return (
|
|
244
|
+
this.deltaManager.lastSequenceNumber -
|
|
245
|
+
(this.lastAck?.summaryAck.sequenceNumber ?? this.deltaManager.initialSequenceNumber)
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
public addOpListener(listener: () => void) {
|
|
250
|
+
this.deltaManager.on("op", listener);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
public removeOpListener(listener: () => void) {
|
|
254
|
+
this.deltaManager.off("op", listener);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
public constructor(
|
|
258
|
+
private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
|
|
259
|
+
private readonly logger: ITelemetryLogger,
|
|
260
|
+
) {
|
|
261
|
+
super();
|
|
262
|
+
this.deltaManager.on("op", (op) => this.handleOp(op));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Creates and returns a summary watcher for a specific client.
|
|
267
|
+
* This will allow for local sent summaries to be better tracked.
|
|
268
|
+
* @param clientId - client id for watcher
|
|
269
|
+
*/
|
|
270
|
+
public createWatcher(clientId: string): IClientSummaryWatcher {
|
|
271
|
+
const watcher = new ClientSummaryWatcher(clientId, this);
|
|
272
|
+
this.summaryWatchers.set(clientId, watcher);
|
|
273
|
+
return watcher;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
public removeWatcher(clientId: string) {
|
|
277
|
+
this.summaryWatchers.delete(clientId);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
public setPendingAckTimerTimeoutCallback(maxAckWaitTime: number, timeoutCallback: () => void) {
|
|
281
|
+
this.maxAckWaitTime = maxAckWaitTime;
|
|
282
|
+
this.pendingAckTimerTimeoutCallback = timeoutCallback;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
public unsetPendingAckTimerTimeoutCallback() {
|
|
286
|
+
this.maxAckWaitTime = undefined;
|
|
287
|
+
this.pendingAckTimerTimeoutCallback = undefined;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Returns a promise that resolves once all pending summary ops
|
|
292
|
+
* have been acked or nacked.
|
|
293
|
+
*/
|
|
294
|
+
public async waitFlushed(): Promise<IAckedSummary | undefined> {
|
|
295
|
+
while (this.pendingSummaries.size > 0) {
|
|
296
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
297
|
+
const promises = Array.from(this.pendingSummaries, ([, summary]) =>
|
|
298
|
+
summary.waitAckNack(),
|
|
299
|
+
);
|
|
300
|
+
await Promise.all(promises);
|
|
301
|
+
}
|
|
302
|
+
return this.lastAck;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Returns a promise that resolves once a summary is acked that has a reference
|
|
307
|
+
* sequence number greater than or equal to the passed in sequence number.
|
|
308
|
+
* @param referenceSequenceNumber - reference sequence number to wait for
|
|
309
|
+
* @returns The latest acked summary
|
|
310
|
+
*/
|
|
311
|
+
public async waitSummaryAck(referenceSequenceNumber: number): Promise<IAckedSummary> {
|
|
312
|
+
while (
|
|
313
|
+
!this.lastAck ||
|
|
314
|
+
this.lastAck.summaryOp.referenceSequenceNumber < referenceSequenceNumber
|
|
315
|
+
) {
|
|
316
|
+
await this.refreshWaitNextAck.promise;
|
|
317
|
+
}
|
|
318
|
+
return this.lastAck;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
private parseContent(op: ISequencedDocumentMessage) {
|
|
322
|
+
// back-compat: ADO #1385: Make this unconditional in the future,
|
|
323
|
+
// when Container.processRemoteMessage stops parsing contents. That said, we should move to
|
|
324
|
+
// listen for "op" events from ContainerRuntime, and parsing may not be required at all if
|
|
325
|
+
// ContainerRuntime.process() would parse it for all types of ops.
|
|
326
|
+
// Can make either of those changes only when LTS moves to a version that has no content
|
|
327
|
+
// parsing in loader layer!
|
|
328
|
+
if (typeof op.contents === "string") {
|
|
329
|
+
op.contents = JSON.parse(op.contents);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Handler for ops; only handles ops relating to summaries.
|
|
335
|
+
* @param op - op message to handle
|
|
336
|
+
*/
|
|
337
|
+
private handleOp(opArg: ISequencedDocumentMessage) {
|
|
338
|
+
const op = { ...opArg };
|
|
339
|
+
|
|
340
|
+
switch (op.type) {
|
|
341
|
+
case MessageType.Summarize:
|
|
342
|
+
this.parseContent(op);
|
|
343
|
+
return this.handleSummaryOp(op as ISummaryOpMessage);
|
|
344
|
+
case MessageType.SummaryAck:
|
|
345
|
+
case MessageType.SummaryNack:
|
|
346
|
+
// Old files (prior to PR #10077) may not contain this info
|
|
347
|
+
// back-compat: ADO #1385: remove cast when ISequencedDocumentMessage changes are propagated
|
|
348
|
+
if ((op as any).data !== undefined) {
|
|
349
|
+
op.contents = JSON.parse((op as any).data);
|
|
350
|
+
} else {
|
|
351
|
+
this.parseContent(op);
|
|
352
|
+
}
|
|
353
|
+
return op.type === MessageType.SummaryAck
|
|
354
|
+
? this.handleSummaryAck(op as ISummaryAckMessage)
|
|
355
|
+
: this.handleSummaryNack(op as ISummaryNackMessage);
|
|
356
|
+
default: {
|
|
357
|
+
// If the difference between timestamp of current op and last summary op is greater than
|
|
358
|
+
// the maxAckWaitTime, then we need to inform summarizer to not wait and summarize
|
|
359
|
+
// immediately as we have already waited for maxAckWaitTime.
|
|
360
|
+
const lastOpTimestamp = op.timestamp;
|
|
361
|
+
if (
|
|
362
|
+
this.lastSummaryTimestamp !== undefined &&
|
|
363
|
+
this.maxAckWaitTime !== undefined &&
|
|
364
|
+
lastOpTimestamp - this.lastSummaryTimestamp >= this.maxAckWaitTime
|
|
365
|
+
) {
|
|
366
|
+
this.pendingAckTimerTimeoutCallback?.();
|
|
367
|
+
}
|
|
368
|
+
this.emit("default", op);
|
|
369
|
+
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
private handleSummaryOp(op: ISummaryOpMessage) {
|
|
376
|
+
let summary: Summary | undefined;
|
|
377
|
+
|
|
378
|
+
// Check if summary already being watched, broadcast if so
|
|
379
|
+
const watcher = this.summaryWatchers.get(op.clientId);
|
|
380
|
+
if (watcher) {
|
|
381
|
+
summary = watcher.tryGetSummary(op.clientSequenceNumber);
|
|
382
|
+
if (summary) {
|
|
383
|
+
summary.broadcast(op);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// If not watched, create from op
|
|
388
|
+
if (!summary) {
|
|
389
|
+
summary = Summary.createFromOp(op);
|
|
390
|
+
if (watcher) {
|
|
391
|
+
watcher.setSummary(summary);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
this.pendingSummaries.set(op.sequenceNumber, summary);
|
|
395
|
+
this.lastSummaryTimestamp = op.timestamp;
|
|
396
|
+
this.emit(MessageType.Summarize, op);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
private handleSummaryAck(op: ISummaryAckMessage) {
|
|
400
|
+
const seq = op.contents.summaryProposal.summarySequenceNumber;
|
|
401
|
+
const summary = this.pendingSummaries.get(seq);
|
|
402
|
+
if (!summary || summary.summaryOp === undefined) {
|
|
403
|
+
// Summary ack without an op should be rare. We could fetch the
|
|
404
|
+
// reference sequence number from the snapshot, but instead we
|
|
405
|
+
// will not emit this ack. It should be the case that the summary
|
|
406
|
+
// op that this ack is for is earlier than this file was loaded
|
|
407
|
+
// from. i.e. initialSequenceNumber > summarySequenceNumber.
|
|
408
|
+
// We really don't care about it for now, since it is older than
|
|
409
|
+
// the one we loaded from.
|
|
410
|
+
if (seq > this.deltaManager.initialSequenceNumber) {
|
|
411
|
+
// Potential causes for it to be later than our initialSequenceNumber
|
|
412
|
+
// are that the summaryOp was nacked then acked, double-acked, or
|
|
413
|
+
// the summarySequenceNumber is incorrect.
|
|
414
|
+
this.logger.sendTelemetryEvent({
|
|
415
|
+
eventName: "SummaryAckWithoutOp",
|
|
416
|
+
sequenceNumber: op.sequenceNumber, // summary ack seq #
|
|
417
|
+
summarySequenceNumber: seq, // missing summary seq #
|
|
418
|
+
initialSequenceNumber: this.deltaManager.initialSequenceNumber,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
summary.ackNack(op);
|
|
424
|
+
this.pendingSummaries.delete(seq);
|
|
425
|
+
|
|
426
|
+
// Track latest ack
|
|
427
|
+
if (
|
|
428
|
+
!this.lastAck ||
|
|
429
|
+
seq > this.lastAck.summaryAck.contents.summaryProposal.summarySequenceNumber
|
|
430
|
+
) {
|
|
431
|
+
this.lastAck = {
|
|
432
|
+
summaryOp: summary.summaryOp,
|
|
433
|
+
summaryAck: op,
|
|
434
|
+
};
|
|
435
|
+
this.refreshWaitNextAck.resolve();
|
|
436
|
+
this.refreshWaitNextAck = new Deferred<void>();
|
|
437
|
+
this.emit(MessageType.SummaryAck, op);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
private handleSummaryNack(op: ISummaryNackMessage) {
|
|
442
|
+
const seq = op.contents.summaryProposal.summarySequenceNumber;
|
|
443
|
+
const summary = this.pendingSummaries.get(seq);
|
|
444
|
+
if (summary) {
|
|
445
|
+
summary.ackNack(op);
|
|
446
|
+
this.pendingSummaries.delete(seq);
|
|
447
|
+
this.emit(MessageType.SummaryNack, op);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
421
450
|
}
|