@fluidframework/container-runtime 2.0.0-internal.6.1.0 → 2.0.0-internal.6.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 +35 -0
- package/README.md +4 -3
- package/dist/batchTracker.d.ts +1 -1
- package/dist/batchTracker.js +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +4 -20
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +47 -125
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +82 -14
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +236 -138
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +1 -2
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +4 -5
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +1 -2
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/dataStoreRegistry.js +2 -2
- package/dist/dataStoreRegistry.js.map +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +4 -5
- package/dist/dataStores.js.map +1 -1
- package/dist/error.d.ts +14 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +21 -0
- package/dist/error.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +23 -5
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +5 -3
- package/dist/gc/gcConfigs.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/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +2 -0
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.d.ts +8 -30
- package/dist/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
- package/dist/id-compressor/appendOnlySortedMap.js +25 -67
- package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
- package/dist/id-compressor/finalSpace.d.ts +29 -0
- package/dist/id-compressor/finalSpace.d.ts.map +1 -0
- package/dist/id-compressor/finalSpace.js +62 -0
- package/dist/id-compressor/finalSpace.js.map +1 -0
- package/dist/id-compressor/idCompressor.d.ts +25 -250
- package/dist/id-compressor/idCompressor.d.ts.map +1 -1
- package/dist/id-compressor/idCompressor.js +385 -1149
- package/dist/id-compressor/idCompressor.js.map +1 -1
- package/dist/id-compressor/identifiers.d.ts +32 -0
- package/dist/id-compressor/identifiers.d.ts.map +1 -0
- package/dist/id-compressor/identifiers.js +15 -0
- package/dist/id-compressor/identifiers.js.map +1 -0
- package/dist/id-compressor/index.d.ts +5 -6
- package/dist/id-compressor/index.d.ts.map +1 -1
- package/dist/id-compressor/index.js +20 -26
- package/dist/id-compressor/index.js.map +1 -1
- package/dist/id-compressor/persistanceUtilities.d.ts +22 -0
- package/dist/id-compressor/persistanceUtilities.d.ts.map +1 -0
- package/dist/id-compressor/persistanceUtilities.js +43 -0
- package/dist/id-compressor/persistanceUtilities.js.map +1 -0
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
- package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
- package/dist/id-compressor/sessionSpaceNormalizer.js +80 -0
- package/dist/id-compressor/sessionSpaceNormalizer.js.map +1 -0
- package/dist/id-compressor/sessions.d.ts +115 -0
- package/dist/id-compressor/sessions.d.ts.map +1 -0
- package/dist/id-compressor/sessions.js +305 -0
- package/dist/id-compressor/sessions.js.map +1 -0
- package/dist/id-compressor/utilities.d.ts +49 -0
- package/dist/id-compressor/utilities.d.ts.map +1 -0
- package/dist/id-compressor/utilities.js +166 -0
- package/dist/id-compressor/utilities.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opCompressor.js +1 -2
- package/dist/opLifecycle/opCompressor.js.map +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +2 -3
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +1 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +10 -11
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +11 -5
- package/dist/opLifecycle/remoteMessageProcessor.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 +12 -5
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +24 -10
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.d.ts.map +1 -1
- package/dist/scheduleManager.js +4 -5
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summary/index.d.ts +2 -2
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +2 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -2
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js +2 -3
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +27 -4
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +237 -66
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +6 -5
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +70 -67
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +38 -25
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryCollection.d.ts +1 -2
- package/dist/summary/summaryCollection.d.ts.map +1 -1
- package/dist/summary/summaryCollection.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +9 -3
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +42 -38
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryManager.d.ts +7 -6
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +22 -15
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/batchTracker.d.ts +1 -1
- package/lib/batchTracker.js +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +4 -20
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +46 -124
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +82 -14
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +223 -123
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +1 -2
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +1 -2
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +1 -2
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/dataStoreRegistry.js +1 -1
- package/lib/dataStoreRegistry.js.map +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +1 -2
- package/lib/dataStores.js.map +1 -1
- package/lib/error.d.ts +14 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +17 -0
- package/lib/error.js.map +1 -0
- package/lib/gc/garbageCollection.d.ts +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +22 -4
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +3 -1
- package/lib/gc/gcConfigs.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/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +2 -0
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.d.ts +8 -30
- package/lib/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
- package/lib/id-compressor/appendOnlySortedMap.js +24 -65
- package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
- package/lib/id-compressor/finalSpace.d.ts +29 -0
- package/lib/id-compressor/finalSpace.d.ts.map +1 -0
- package/lib/id-compressor/finalSpace.js +58 -0
- package/lib/id-compressor/finalSpace.js.map +1 -0
- package/lib/id-compressor/idCompressor.d.ts +25 -250
- package/lib/id-compressor/idCompressor.d.ts.map +1 -1
- package/lib/id-compressor/idCompressor.js +381 -1139
- package/lib/id-compressor/idCompressor.js.map +1 -1
- package/lib/id-compressor/identifiers.d.ts +32 -0
- package/lib/id-compressor/identifiers.d.ts.map +1 -0
- package/lib/id-compressor/identifiers.js +11 -0
- package/lib/id-compressor/identifiers.js.map +1 -0
- package/lib/id-compressor/index.d.ts +5 -6
- package/lib/id-compressor/index.d.ts.map +1 -1
- package/lib/id-compressor/index.js +5 -6
- package/lib/id-compressor/index.js.map +1 -1
- package/lib/id-compressor/persistanceUtilities.d.ts +22 -0
- package/lib/id-compressor/persistanceUtilities.d.ts.map +1 -0
- package/lib/id-compressor/persistanceUtilities.js +34 -0
- package/lib/id-compressor/persistanceUtilities.js.map +1 -0
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
- package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
- package/lib/id-compressor/sessionSpaceNormalizer.js +76 -0
- package/lib/id-compressor/sessionSpaceNormalizer.js.map +1 -0
- package/lib/id-compressor/sessions.d.ts +115 -0
- package/lib/id-compressor/sessions.d.ts.map +1 -0
- package/lib/id-compressor/sessions.js +290 -0
- package/lib/id-compressor/sessions.js.map +1 -0
- package/lib/id-compressor/utilities.d.ts +49 -0
- package/lib/id-compressor/utilities.d.ts.map +1 -0
- package/lib/id-compressor/utilities.js +148 -0
- package/lib/id-compressor/utilities.js.map +1 -0
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opCompressor.js +1 -2
- package/lib/opLifecycle/opCompressor.js.map +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +1 -2
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +1 -0
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +6 -7
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +12 -6
- package/lib/opLifecycle/remoteMessageProcessor.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 +12 -5
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +21 -7
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.d.ts.map +1 -1
- package/lib/scheduleManager.js +1 -2
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summary/index.d.ts +2 -2
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -1
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -2
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js +1 -2
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +27 -4
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +237 -66
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +6 -5
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +68 -65
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +38 -25
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryCollection.d.ts +1 -2
- package/lib/summary/summaryCollection.d.ts.map +1 -1
- package/lib/summary/summaryCollection.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +9 -3
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +43 -39
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryManager.d.ts +7 -6
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +23 -16
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +27 -24
- package/src/batchTracker.ts +1 -1
- package/src/blobManager.ts +57 -146
- package/src/containerRuntime.ts +331 -158
- package/src/dataStore.ts +1 -2
- package/src/dataStoreContext.ts +3 -6
- package/src/dataStoreContexts.ts +1 -2
- package/src/dataStoreRegistry.ts +1 -1
- package/src/dataStores.ts +3 -5
- package/src/error.ts +18 -0
- package/src/gc/garbageCollection.ts +38 -5
- package/src/gc/gcConfigs.ts +4 -2
- package/src/gc/gcDefinitions.ts +2 -0
- package/src/gc/gcTelemetry.ts +2 -0
- package/src/id-compressor/appendOnlySortedMap.ts +25 -86
- package/src/id-compressor/finalSpace.ts +67 -0
- package/src/id-compressor/idCompressor.ts +455 -1681
- package/src/id-compressor/identifiers.ts +42 -0
- package/src/id-compressor/index.ts +11 -20
- package/src/id-compressor/persistanceUtilities.ts +58 -0
- package/src/id-compressor/sessionSpaceNormalizer.ts +83 -0
- package/src/id-compressor/sessions.ts +405 -0
- package/src/id-compressor/utilities.ts +187 -0
- package/src/index.ts +7 -1
- package/src/opLifecycle/opCompressor.ts +1 -2
- package/src/opLifecycle/opSplitter.ts +4 -4
- package/src/opLifecycle/outbox.ts +13 -10
- package/src/opLifecycle/remoteMessageProcessor.ts +19 -6
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +49 -27
- package/src/scheduleManager.ts +5 -4
- package/src/summary/index.ts +3 -1
- package/src/summary/orderedClientElection.ts +6 -4
- package/src/summary/runningSummarizer.ts +276 -95
- package/src/summary/summarizer.ts +22 -12
- package/src/summary/summarizerClientElection.ts +1 -1
- package/src/summary/summarizerTypes.ts +40 -25
- package/src/summary/summaryCollection.ts +1 -2
- package/src/summary/summaryGenerator.ts +49 -52
- package/src/summary/summaryManager.ts +33 -11
- package/dist/id-compressor/idRange.d.ts +0 -11
- package/dist/id-compressor/idRange.d.ts.map +0 -1
- package/dist/id-compressor/idRange.js +0 -29
- package/dist/id-compressor/idRange.js.map +0 -1
- package/dist/id-compressor/numericUuid.d.ts +0 -59
- package/dist/id-compressor/numericUuid.d.ts.map +0 -1
- package/dist/id-compressor/numericUuid.js +0 -325
- package/dist/id-compressor/numericUuid.js.map +0 -1
- package/dist/id-compressor/sessionIdNormalizer.d.ts +0 -138
- package/dist/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
- package/dist/id-compressor/sessionIdNormalizer.js +0 -483
- package/dist/id-compressor/sessionIdNormalizer.js.map +0 -1
- package/dist/id-compressor/utils.d.ts +0 -57
- package/dist/id-compressor/utils.d.ts.map +0 -1
- package/dist/id-compressor/utils.js +0 -90
- package/dist/id-compressor/utils.js.map +0 -1
- package/dist/id-compressor/uuidUtilities.d.ts +0 -28
- package/dist/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/dist/id-compressor/uuidUtilities.js +0 -104
- package/dist/id-compressor/uuidUtilities.js.map +0 -1
- package/lib/id-compressor/idRange.d.ts +0 -11
- package/lib/id-compressor/idRange.d.ts.map +0 -1
- package/lib/id-compressor/idRange.js +0 -25
- package/lib/id-compressor/idRange.js.map +0 -1
- package/lib/id-compressor/numericUuid.d.ts +0 -59
- package/lib/id-compressor/numericUuid.d.ts.map +0 -1
- package/lib/id-compressor/numericUuid.js +0 -315
- package/lib/id-compressor/numericUuid.js.map +0 -1
- package/lib/id-compressor/sessionIdNormalizer.d.ts +0 -138
- package/lib/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
- package/lib/id-compressor/sessionIdNormalizer.js +0 -479
- package/lib/id-compressor/sessionIdNormalizer.js.map +0 -1
- package/lib/id-compressor/utils.d.ts +0 -57
- package/lib/id-compressor/utils.d.ts.map +0 -1
- package/lib/id-compressor/utils.js +0 -79
- package/lib/id-compressor/utils.js.map +0 -1
- package/lib/id-compressor/uuidUtilities.d.ts +0 -28
- package/lib/id-compressor/uuidUtilities.d.ts.map +0 -1
- package/lib/id-compressor/uuidUtilities.js +0 -96
- package/lib/id-compressor/uuidUtilities.js.map +0 -1
- package/src/id-compressor/idRange.ts +0 -35
- package/src/id-compressor/numericUuid.ts +0 -383
- package/src/id-compressor/sessionIdNormalizer.ts +0 -609
- package/src/id-compressor/utils.ts +0 -114
- package/src/id-compressor/uuidUtilities.ts +0 -120
package/src/containerRuntime.ts
CHANGED
|
@@ -27,23 +27,22 @@ import {
|
|
|
27
27
|
IContainerRuntime,
|
|
28
28
|
IContainerRuntimeEvents,
|
|
29
29
|
} from "@fluidframework/container-runtime-definitions";
|
|
30
|
-
import {
|
|
31
|
-
assert,
|
|
32
|
-
delay,
|
|
33
|
-
Trace,
|
|
34
|
-
TypedEventEmitter,
|
|
35
|
-
unreachableCase,
|
|
36
|
-
} from "@fluidframework/common-utils";
|
|
30
|
+
import { assert, delay, Trace, TypedEventEmitter } from "@fluidframework/common-utils";
|
|
37
31
|
import { LazyPromise } from "@fluidframework/core-utils";
|
|
38
32
|
import {
|
|
39
33
|
createChildLogger,
|
|
34
|
+
createChildMonitoringContext,
|
|
35
|
+
DataCorruptionError,
|
|
36
|
+
DataProcessingError,
|
|
37
|
+
GenericError,
|
|
40
38
|
raiseConnectedEvent,
|
|
41
39
|
PerformanceEvent,
|
|
40
|
+
// eslint-disable-next-line import/no-deprecated
|
|
42
41
|
TaggedLoggerAdapter,
|
|
43
42
|
MonitoringContext,
|
|
44
43
|
wrapError,
|
|
45
44
|
ITelemetryLoggerExt,
|
|
46
|
-
|
|
45
|
+
UsageError,
|
|
47
46
|
} from "@fluidframework/telemetry-utils";
|
|
48
47
|
import {
|
|
49
48
|
DriverHeader,
|
|
@@ -52,12 +51,6 @@ import {
|
|
|
52
51
|
ISummaryContext,
|
|
53
52
|
} from "@fluidframework/driver-definitions";
|
|
54
53
|
import { readAndParse } from "@fluidframework/driver-utils";
|
|
55
|
-
import {
|
|
56
|
-
DataCorruptionError,
|
|
57
|
-
DataProcessingError,
|
|
58
|
-
GenericError,
|
|
59
|
-
UsageError,
|
|
60
|
-
} from "@fluidframework/container-utils";
|
|
61
54
|
import {
|
|
62
55
|
IClientDetails,
|
|
63
56
|
IDocumentMessage,
|
|
@@ -157,6 +150,11 @@ import {
|
|
|
157
150
|
RunWhileConnectedCoordinator,
|
|
158
151
|
IGenerateSummaryTreeResult,
|
|
159
152
|
RetriableSummaryError,
|
|
153
|
+
IOnDemandSummarizeOptions,
|
|
154
|
+
ISummarizeResults,
|
|
155
|
+
IEnqueueSummarizeOptions,
|
|
156
|
+
EnqueueSummarizeResult,
|
|
157
|
+
ISummarizerEvents,
|
|
160
158
|
} from "./summary";
|
|
161
159
|
import { formExponentialFn, Throttler } from "./throttler";
|
|
162
160
|
import {
|
|
@@ -214,11 +212,64 @@ export enum ContainerMessageType {
|
|
|
214
212
|
IdAllocation = "idAllocation",
|
|
215
213
|
}
|
|
216
214
|
|
|
215
|
+
/**
|
|
216
|
+
* How should an older client handle an unrecognized remote op type?
|
|
217
|
+
*
|
|
218
|
+
* @internal
|
|
219
|
+
*/
|
|
220
|
+
export type CompatModeBehavior =
|
|
221
|
+
/** Ignore the op. It won't be persisted if this client summarizes */
|
|
222
|
+
| "Ignore"
|
|
223
|
+
/** Fail processing immediately. (The container will close) */
|
|
224
|
+
| "FailToProcess";
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* All the info an older client would need to know how to handle an unrecognized remote op type
|
|
228
|
+
*
|
|
229
|
+
* @internal
|
|
230
|
+
*/
|
|
231
|
+
export interface IContainerRuntimeMessageCompatDetails {
|
|
232
|
+
/** How should an older client handle an unrecognized remote op type? */
|
|
233
|
+
behavior: CompatModeBehavior;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Utility to implement compat behaviors given an unknown message type
|
|
238
|
+
* The parameters are typed to support compile-time enforcement of handling all known types/behaviors
|
|
239
|
+
*
|
|
240
|
+
* @param _unknownContainerRuntimeMessageType - Typed as never, to ensure all known types have been
|
|
241
|
+
* handled before calling this function (e.g. in a switch statement).
|
|
242
|
+
* @param compatBehavior - Typed redundantly with CompatModeBehavior to ensure handling is added when updating that type
|
|
243
|
+
*/
|
|
244
|
+
function compatBehaviorAllowsMessageType(
|
|
245
|
+
_unknownContainerRuntimeMessageType: never,
|
|
246
|
+
compatBehavior: "Ignore" | "FailToProcess" | undefined,
|
|
247
|
+
): boolean {
|
|
248
|
+
// undefined defaults to same behavior as "FailToProcess"
|
|
249
|
+
return compatBehavior === "Ignore";
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime
|
|
254
|
+
*
|
|
255
|
+
* IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
|
|
256
|
+
* This way stringified values can be compared.
|
|
257
|
+
*/
|
|
217
258
|
export interface ContainerRuntimeMessage {
|
|
218
|
-
|
|
259
|
+
/** Type of the op, within the ContainerRuntime's domain */
|
|
219
260
|
type: ContainerMessageType;
|
|
261
|
+
/** Domain-specific contents, interpreted according to the type */
|
|
262
|
+
contents: any;
|
|
263
|
+
/** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */
|
|
264
|
+
compatDetails?: IContainerRuntimeMessageCompatDetails;
|
|
220
265
|
}
|
|
221
266
|
|
|
267
|
+
/**
|
|
268
|
+
* An unpacked ISequencedDocumentMessage with the inner ContainerRuntimeMessage type/contents/etc
|
|
269
|
+
* promoted up to the outer object
|
|
270
|
+
*/
|
|
271
|
+
export type SequencedContainerRuntimeMessage = ISequencedDocumentMessage & ContainerRuntimeMessage;
|
|
272
|
+
|
|
222
273
|
export interface ISummaryBaseConfiguration {
|
|
223
274
|
/**
|
|
224
275
|
* Delay before first attempt to spawn summarizing container.
|
|
@@ -457,9 +508,13 @@ export enum RuntimeHeaders {
|
|
|
457
508
|
|
|
458
509
|
/** True if a tombstoned object should be returned without erroring */
|
|
459
510
|
export const AllowTombstoneRequestHeaderKey = "allowTombstone"; // Belongs in the enum above, but avoiding the breaking change
|
|
511
|
+
/** [IRRELEVANT IF throwOnInactiveLoad OPTION NOT SET] True if an inactive object should be returned without erroring */
|
|
512
|
+
export const AllowInactiveRequestHeaderKey = "allowInactive"; // Belongs in the enum above, but avoiding the breaking change
|
|
460
513
|
|
|
461
514
|
/** Tombstone error responses will have this header set to true */
|
|
462
515
|
export const TombstoneResponseHeaderKey = "isTombstoned";
|
|
516
|
+
/** Inactive error responses will have this header set to true */
|
|
517
|
+
export const InactiveResponseHeaderKey = "isInactive";
|
|
463
518
|
|
|
464
519
|
/**
|
|
465
520
|
* The full set of parsed header data that may be found on Runtime requests
|
|
@@ -500,7 +555,7 @@ interface OldContainerContextWithLogger extends Omit<IContainerContext, "taggedL
|
|
|
500
555
|
* instantiated runtime in a new instance of the container, so it can load to the
|
|
501
556
|
* same state
|
|
502
557
|
*/
|
|
503
|
-
interface IPendingRuntimeState {
|
|
558
|
+
export interface IPendingRuntimeState {
|
|
504
559
|
/**
|
|
505
560
|
* Pending ops from PendingStateManager
|
|
506
561
|
*/
|
|
@@ -605,7 +660,7 @@ export const makeLegacySendBatchFn =
|
|
|
605
660
|
* It will define the store level mappings.
|
|
606
661
|
*/
|
|
607
662
|
export class ContainerRuntime
|
|
608
|
-
extends TypedEventEmitter<IContainerRuntimeEvents>
|
|
663
|
+
extends TypedEventEmitter<IContainerRuntimeEvents & ISummarizerEvents>
|
|
609
664
|
implements IContainerRuntime, IRuntime, ISummarizerRuntime, ISummarizerInternalsProvider
|
|
610
665
|
{
|
|
611
666
|
/**
|
|
@@ -665,16 +720,30 @@ export class ContainerRuntime
|
|
|
665
720
|
* - initializeEntryPoint - Promise that resolves to an object which will act as entryPoint for the Container.
|
|
666
721
|
* This object should provide all the functionality that the Container is expected to provide to the loader layer.
|
|
667
722
|
*/
|
|
668
|
-
public static async loadRuntime(
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
723
|
+
public static async loadRuntime(
|
|
724
|
+
params: {
|
|
725
|
+
context: IContainerContext;
|
|
726
|
+
registryEntries: NamedFluidDataStoreRegistryEntries;
|
|
727
|
+
existing: boolean;
|
|
728
|
+
runtimeOptions?: IContainerRuntimeOptions;
|
|
729
|
+
containerScope?: FluidObject;
|
|
730
|
+
containerRuntimeCtor?: typeof ContainerRuntime;
|
|
731
|
+
} & (
|
|
732
|
+
| {
|
|
733
|
+
requestHandler?: (
|
|
734
|
+
request: IRequest,
|
|
735
|
+
runtime: IContainerRuntime,
|
|
736
|
+
) => Promise<IResponse>;
|
|
737
|
+
initializeEntryPoint?: undefined;
|
|
738
|
+
}
|
|
739
|
+
| {
|
|
740
|
+
requestHandler?: undefined;
|
|
741
|
+
initializeEntryPoint: (
|
|
742
|
+
containerRuntime: IContainerRuntime,
|
|
743
|
+
) => Promise<FluidObject>;
|
|
744
|
+
}
|
|
745
|
+
),
|
|
746
|
+
): Promise<ContainerRuntime> {
|
|
678
747
|
const {
|
|
679
748
|
context,
|
|
680
749
|
registryEntries,
|
|
@@ -683,14 +752,25 @@ export class ContainerRuntime
|
|
|
683
752
|
runtimeOptions = {},
|
|
684
753
|
containerScope = {},
|
|
685
754
|
containerRuntimeCtor = ContainerRuntime,
|
|
686
|
-
initializeEntryPoint,
|
|
687
755
|
} = params;
|
|
688
756
|
|
|
757
|
+
const initializeEntryPoint =
|
|
758
|
+
params.initializeEntryPoint ??
|
|
759
|
+
(async (containerRuntime: IContainerRuntime) => ({
|
|
760
|
+
get IFluidRouter() {
|
|
761
|
+
return this;
|
|
762
|
+
},
|
|
763
|
+
async request(req) {
|
|
764
|
+
return containerRuntime.request(req);
|
|
765
|
+
},
|
|
766
|
+
}));
|
|
767
|
+
|
|
689
768
|
// If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
|
|
690
769
|
// back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
|
|
691
770
|
const backCompatContext: IContainerContext | OldContainerContextWithLogger = context;
|
|
692
771
|
const passLogger =
|
|
693
772
|
backCompatContext.taggedLogger ??
|
|
773
|
+
// eslint-disable-next-line import/no-deprecated
|
|
694
774
|
new TaggedLoggerAdapter((backCompatContext as OldContainerContextWithLogger).logger);
|
|
695
775
|
const logger = createChildLogger({
|
|
696
776
|
logger: passLogger,
|
|
@@ -785,7 +865,7 @@ export class ContainerRuntime
|
|
|
785
865
|
idCompressor =
|
|
786
866
|
serializedIdCompressor !== undefined
|
|
787
867
|
? IdCompressor.deserialize(serializedIdCompressor, createSessionId())
|
|
788
|
-
:
|
|
868
|
+
: IdCompressor.create(logger);
|
|
789
869
|
}
|
|
790
870
|
|
|
791
871
|
const runtime = new containerRuntimeCtor(
|
|
@@ -818,6 +898,7 @@ export class ContainerRuntime
|
|
|
818
898
|
initializeEntryPoint,
|
|
819
899
|
);
|
|
820
900
|
|
|
901
|
+
await runtime.blobManager.processStashedChanges();
|
|
821
902
|
// It's possible to have ops with a reference sequence number of 0. Op sequence numbers start
|
|
822
903
|
// at 1, so we won't see a replayed saved op with a sequence number of 0.
|
|
823
904
|
await runtime.pendingStateManager.applyStashedOpsAt(0);
|
|
@@ -849,6 +930,7 @@ export class ContainerRuntime
|
|
|
849
930
|
localOpMetadata: unknown,
|
|
850
931
|
opMetadata: Record<string, unknown> | undefined,
|
|
851
932
|
) => this.reSubmitCore({ type, contents }, localOpMetadata, opMetadata);
|
|
933
|
+
// Note: compatDetails is not included in this deprecated API
|
|
852
934
|
}
|
|
853
935
|
|
|
854
936
|
private readonly submitFn: (
|
|
@@ -994,7 +1076,7 @@ export class ContainerRuntime
|
|
|
994
1076
|
private readonly validateSummaryBeforeUpload: boolean;
|
|
995
1077
|
|
|
996
1078
|
private readonly defaultTelemetrySignalSampleCount = 100;
|
|
997
|
-
private _perfSignalData: IPerfSignalReport = {
|
|
1079
|
+
private readonly _perfSignalData: IPerfSignalReport = {
|
|
998
1080
|
signalsLost: 0,
|
|
999
1081
|
signalSequenceNumber: 0,
|
|
1000
1082
|
signalTimestamp: 0,
|
|
@@ -1478,8 +1560,7 @@ export class ContainerRuntime
|
|
|
1478
1560
|
this.summaryCollection = new SummaryCollection(this.deltaManager, this.logger);
|
|
1479
1561
|
|
|
1480
1562
|
this.dirtyContainer =
|
|
1481
|
-
this.attachState !== AttachState.Attached ||
|
|
1482
|
-
this.pendingStateManager.hasPendingMessages();
|
|
1563
|
+
this.attachState !== AttachState.Attached || this.hasPendingMessages();
|
|
1483
1564
|
context.updateDirtyContainerState(this.dirtyContainer);
|
|
1484
1565
|
|
|
1485
1566
|
if (this.summariesDisabled) {
|
|
@@ -1564,6 +1645,9 @@ export class ContainerRuntime
|
|
|
1564
1645
|
},
|
|
1565
1646
|
this.heuristicsDisabled,
|
|
1566
1647
|
);
|
|
1648
|
+
this.summaryManager.on("summarize", (eventProps) => {
|
|
1649
|
+
this.emit("summarize", eventProps);
|
|
1650
|
+
});
|
|
1567
1651
|
this.summaryManager.start();
|
|
1568
1652
|
}
|
|
1569
1653
|
}
|
|
@@ -1736,7 +1820,7 @@ export class ContainerRuntime
|
|
|
1736
1820
|
subRequest.url.startsWith("/"),
|
|
1737
1821
|
0x126 /* "Expected createSubRequest url to include a leading slash" */,
|
|
1738
1822
|
);
|
|
1739
|
-
return dataStore.
|
|
1823
|
+
return dataStore.request(subRequest);
|
|
1740
1824
|
}
|
|
1741
1825
|
|
|
1742
1826
|
return create404Response(request);
|
|
@@ -1784,6 +1868,7 @@ export class ContainerRuntime
|
|
|
1784
1868
|
dataStoreContext.packagePath,
|
|
1785
1869
|
request?.headers,
|
|
1786
1870
|
);
|
|
1871
|
+
|
|
1787
1872
|
return dataStoreChannel;
|
|
1788
1873
|
}
|
|
1789
1874
|
|
|
@@ -1878,7 +1963,7 @@ export class ContainerRuntime
|
|
|
1878
1963
|
this.mc.logger.sendTelemetryEvent({
|
|
1879
1964
|
eventName: "ReconnectsWithNoProgress",
|
|
1880
1965
|
attempts: this.consecutiveReconnects,
|
|
1881
|
-
pendingMessages: this.
|
|
1966
|
+
pendingMessages: this.pendingMessagesCount,
|
|
1882
1967
|
});
|
|
1883
1968
|
}
|
|
1884
1969
|
|
|
@@ -1947,14 +2032,15 @@ export class ContainerRuntime
|
|
|
1947
2032
|
*/
|
|
1948
2033
|
private parseOpContent(serializedContent?: string): ContainerRuntimeMessage {
|
|
1949
2034
|
assert(serializedContent !== undefined, 0x6d5 /* content must be defined */);
|
|
1950
|
-
const { type, contents } =
|
|
2035
|
+
const { type, contents, compatDetails }: ContainerRuntimeMessage =
|
|
2036
|
+
JSON.parse(serializedContent);
|
|
1951
2037
|
assert(type !== undefined, 0x6d6 /* incorrect op content format */);
|
|
1952
|
-
return { type, contents };
|
|
2038
|
+
return { type, contents, compatDetails };
|
|
1953
2039
|
}
|
|
1954
2040
|
|
|
1955
2041
|
private async applyStashedOp(op: string): Promise<unknown> {
|
|
1956
2042
|
// Need to parse from string for back-compat
|
|
1957
|
-
const { type, contents } = this.parseOpContent(op);
|
|
2043
|
+
const { type, contents, compatDetails } = this.parseOpContent(op);
|
|
1958
2044
|
switch (type) {
|
|
1959
2045
|
case ContainerMessageType.FluidDataStoreOp:
|
|
1960
2046
|
return this.dataStores.applyStashedOp(contents as IEnvelope);
|
|
@@ -1973,8 +2059,27 @@ export class ContainerRuntime
|
|
|
1973
2059
|
throw new Error("chunkedOp not expected here");
|
|
1974
2060
|
case ContainerMessageType.Rejoin:
|
|
1975
2061
|
throw new Error("rejoin not expected here");
|
|
1976
|
-
default:
|
|
1977
|
-
|
|
2062
|
+
default: {
|
|
2063
|
+
// This should be extremely rare for stashed ops.
|
|
2064
|
+
// It would require a newer runtime stashing ops and then an older one applying them,
|
|
2065
|
+
// e.g. if an app rolled back its container version
|
|
2066
|
+
const compatBehavior = compatDetails?.behavior;
|
|
2067
|
+
if (!compatBehaviorAllowsMessageType(type, compatBehavior)) {
|
|
2068
|
+
const error = DataProcessingError.create(
|
|
2069
|
+
"Stashed runtime message of unknown type",
|
|
2070
|
+
"applyStashedOp",
|
|
2071
|
+
undefined /* sequencedMessage */,
|
|
2072
|
+
{
|
|
2073
|
+
messageDetails: JSON.stringify({
|
|
2074
|
+
type,
|
|
2075
|
+
compatBehavior,
|
|
2076
|
+
}),
|
|
2077
|
+
},
|
|
2078
|
+
);
|
|
2079
|
+
this.closeFn(error);
|
|
2080
|
+
throw error;
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
1978
2083
|
}
|
|
1979
2084
|
}
|
|
1980
2085
|
|
|
@@ -1988,32 +2093,6 @@ export class ContainerRuntime
|
|
|
1988
2093
|
return;
|
|
1989
2094
|
}
|
|
1990
2095
|
|
|
1991
|
-
// If attachment blobs were added while disconnected, we need to delay
|
|
1992
|
-
// propagation of the "connected" event until we have uploaded them to
|
|
1993
|
-
// ensure we don't submit ops referencing a blob that has not been uploaded
|
|
1994
|
-
// Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
|
|
1995
|
-
const connecting =
|
|
1996
|
-
connected && !this._connected && !this.innerDeltaManager.readOnlyInfo.readonly;
|
|
1997
|
-
if (connecting && this.blobManager.hasPendingOfflineUploads) {
|
|
1998
|
-
assert(
|
|
1999
|
-
!this.delayConnectClientId,
|
|
2000
|
-
0x392 /* Connect event delay must be canceled before subsequent connect event */,
|
|
2001
|
-
);
|
|
2002
|
-
assert(!!clientId, 0x393 /* Must have clientId when connecting */);
|
|
2003
|
-
this.delayConnectClientId = clientId;
|
|
2004
|
-
this.blobManager.onConnected().then(
|
|
2005
|
-
() => {
|
|
2006
|
-
// make sure we didn't reconnect before the promise resolved
|
|
2007
|
-
if (this.delayConnectClientId === clientId && !this.disposed) {
|
|
2008
|
-
this.delayConnectClientId = undefined;
|
|
2009
|
-
this.setConnectionStateCore(connected, clientId);
|
|
2010
|
-
}
|
|
2011
|
-
},
|
|
2012
|
-
(error) => this.closeFn(error),
|
|
2013
|
-
);
|
|
2014
|
-
return;
|
|
2015
|
-
}
|
|
2016
|
-
|
|
2017
2096
|
this.setConnectionStateCore(connected, clientId);
|
|
2018
2097
|
}
|
|
2019
2098
|
|
|
@@ -2061,7 +2140,7 @@ export class ContainerRuntime
|
|
|
2061
2140
|
{
|
|
2062
2141
|
dataLoss: 1,
|
|
2063
2142
|
attempts: this.consecutiveReconnects,
|
|
2064
|
-
pendingMessages: this.
|
|
2143
|
+
pendingMessages: this.pendingMessagesCount,
|
|
2065
2144
|
},
|
|
2066
2145
|
),
|
|
2067
2146
|
);
|
|
@@ -2086,15 +2165,15 @@ export class ContainerRuntime
|
|
|
2086
2165
|
public process(messageArg: ISequencedDocumentMessage, local: boolean) {
|
|
2087
2166
|
this.verifyNotClosed();
|
|
2088
2167
|
|
|
2089
|
-
// Whether or not the message
|
|
2168
|
+
// Whether or not the message appears to be a runtime message from an up-to-date client.
|
|
2090
2169
|
// It may be a legacy runtime message (ie already unpacked and ContainerMessageType)
|
|
2091
2170
|
// or something different, like a system message.
|
|
2092
|
-
const
|
|
2171
|
+
const modernRuntimeMessage = messageArg.type === MessageType.Operation;
|
|
2093
2172
|
|
|
2094
2173
|
// Do shallow copy of message, as the processing flow will modify it.
|
|
2095
2174
|
const messageCopy = { ...messageArg };
|
|
2096
2175
|
for (const message of this.remoteMessageProcessor.process(messageCopy)) {
|
|
2097
|
-
this.processCore(message, local,
|
|
2176
|
+
this.processCore(message, local, modernRuntimeMessage);
|
|
2098
2177
|
}
|
|
2099
2178
|
}
|
|
2100
2179
|
|
|
@@ -2104,12 +2183,12 @@ export class ContainerRuntime
|
|
|
2104
2183
|
* Direct the message to the correct subsystem for processing, and implement other side effects
|
|
2105
2184
|
* @param message - The unpacked message. Likely a ContainerRuntimeMessage, but could also be a system op
|
|
2106
2185
|
* @param local - Did this client send the op?
|
|
2107
|
-
* @param
|
|
2186
|
+
* @param modernRuntimeMessage - Does this appear like a current ContainerRuntimeMessage?
|
|
2108
2187
|
*/
|
|
2109
2188
|
private processCore(
|
|
2110
|
-
message: ISequencedDocumentMessage,
|
|
2189
|
+
message: ISequencedDocumentMessage | SequencedContainerRuntimeMessage,
|
|
2111
2190
|
local: boolean,
|
|
2112
|
-
|
|
2191
|
+
modernRuntimeMessage: boolean,
|
|
2113
2192
|
) {
|
|
2114
2193
|
// Surround the actual processing of the operation with messages to the schedule manager indicating
|
|
2115
2194
|
// the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
|
|
@@ -2120,8 +2199,10 @@ export class ContainerRuntime
|
|
|
2120
2199
|
|
|
2121
2200
|
try {
|
|
2122
2201
|
let localOpMetadata: unknown;
|
|
2123
|
-
if (local &&
|
|
2124
|
-
localOpMetadata = this.pendingStateManager.processPendingLocalMessage(
|
|
2202
|
+
if (local && modernRuntimeMessage && message.type !== ContainerMessageType.ChunkedOp) {
|
|
2203
|
+
localOpMetadata = this.pendingStateManager.processPendingLocalMessage(
|
|
2204
|
+
message as SequencedContainerRuntimeMessage,
|
|
2205
|
+
);
|
|
2125
2206
|
}
|
|
2126
2207
|
|
|
2127
2208
|
// If there are no more pending messages after processing a local message,
|
|
@@ -2130,51 +2211,14 @@ export class ContainerRuntime
|
|
|
2130
2211
|
this.updateDocumentDirtyState(false);
|
|
2131
2212
|
}
|
|
2132
2213
|
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
this.processAliasMessage(message, localOpMetadata, local);
|
|
2140
|
-
break;
|
|
2141
|
-
case ContainerMessageType.FluidDataStoreOp:
|
|
2142
|
-
this.dataStores.processFluidDataStoreOp(message, local, localOpMetadata);
|
|
2143
|
-
break;
|
|
2144
|
-
case ContainerMessageType.BlobAttach:
|
|
2145
|
-
this.blobManager.processBlobAttachOp(message, local);
|
|
2146
|
-
break;
|
|
2147
|
-
case ContainerMessageType.IdAllocation:
|
|
2148
|
-
assert(
|
|
2149
|
-
this.idCompressor !== undefined,
|
|
2150
|
-
0x67c /* IdCompressor should be defined if enabled */,
|
|
2151
|
-
);
|
|
2152
|
-
this.idCompressor.finalizeCreationRange(message.contents as IdCreationRange);
|
|
2153
|
-
break;
|
|
2154
|
-
case ContainerMessageType.ChunkedOp:
|
|
2155
|
-
case ContainerMessageType.Rejoin:
|
|
2156
|
-
break;
|
|
2157
|
-
default:
|
|
2158
|
-
if (runtimeMessage) {
|
|
2159
|
-
const error = DataProcessingError.create(
|
|
2160
|
-
// Former assert 0x3ce
|
|
2161
|
-
"Runtime message of unknown type",
|
|
2162
|
-
"OpProcessing",
|
|
2163
|
-
message,
|
|
2164
|
-
{
|
|
2165
|
-
local,
|
|
2166
|
-
type: message.type,
|
|
2167
|
-
contentType: typeof message.contents,
|
|
2168
|
-
batch: (message.metadata as IBatchMetadata | undefined)?.batch,
|
|
2169
|
-
compression: message.compression,
|
|
2170
|
-
},
|
|
2171
|
-
);
|
|
2172
|
-
this.closeFn(error);
|
|
2173
|
-
throw error;
|
|
2174
|
-
}
|
|
2175
|
-
}
|
|
2214
|
+
this.validateAndProcessRuntimeMessage(
|
|
2215
|
+
message,
|
|
2216
|
+
localOpMetadata,
|
|
2217
|
+
local,
|
|
2218
|
+
modernRuntimeMessage,
|
|
2219
|
+
);
|
|
2176
2220
|
|
|
2177
|
-
this.emit("op", message,
|
|
2221
|
+
this.emit("op", message, modernRuntimeMessage);
|
|
2178
2222
|
|
|
2179
2223
|
this.scheduleManager.afterOpProcessing(undefined, message);
|
|
2180
2224
|
|
|
@@ -2189,13 +2233,74 @@ export class ContainerRuntime
|
|
|
2189
2233
|
throw e;
|
|
2190
2234
|
}
|
|
2191
2235
|
}
|
|
2192
|
-
|
|
2193
|
-
|
|
2236
|
+
/**
|
|
2237
|
+
* Assuming the given message is also a ContainerRuntimeMessage,
|
|
2238
|
+
* checks its type and dispatches the message to the appropriate handler in the runtime.
|
|
2239
|
+
* Throws a DataProcessingError if the message doesn't conform to the ContainerRuntimeMessage type.
|
|
2240
|
+
*/
|
|
2241
|
+
private validateAndProcessRuntimeMessage(
|
|
2194
2242
|
message: ISequencedDocumentMessage,
|
|
2195
2243
|
localOpMetadata: unknown,
|
|
2196
2244
|
local: boolean,
|
|
2197
|
-
|
|
2198
|
-
|
|
2245
|
+
expectRuntimeMessageType: boolean,
|
|
2246
|
+
): asserts message is SequencedContainerRuntimeMessage {
|
|
2247
|
+
// Optimistically extract ContainerRuntimeMessage-specific props from the message
|
|
2248
|
+
const { type: maybeContainerMessageType, compatDetails } =
|
|
2249
|
+
message as ContainerRuntimeMessage;
|
|
2250
|
+
|
|
2251
|
+
switch (maybeContainerMessageType) {
|
|
2252
|
+
case ContainerMessageType.Attach:
|
|
2253
|
+
this.dataStores.processAttachMessage(message, local);
|
|
2254
|
+
break;
|
|
2255
|
+
case ContainerMessageType.Alias:
|
|
2256
|
+
this.dataStores.processAliasMessage(message, localOpMetadata, local);
|
|
2257
|
+
break;
|
|
2258
|
+
case ContainerMessageType.FluidDataStoreOp:
|
|
2259
|
+
this.dataStores.processFluidDataStoreOp(message, local, localOpMetadata);
|
|
2260
|
+
break;
|
|
2261
|
+
case ContainerMessageType.BlobAttach:
|
|
2262
|
+
this.blobManager.processBlobAttachOp(message, local);
|
|
2263
|
+
break;
|
|
2264
|
+
case ContainerMessageType.IdAllocation:
|
|
2265
|
+
assert(
|
|
2266
|
+
this.idCompressor !== undefined,
|
|
2267
|
+
0x67c /* IdCompressor should be defined if enabled */,
|
|
2268
|
+
);
|
|
2269
|
+
this.idCompressor.finalizeCreationRange(message.contents as IdCreationRange);
|
|
2270
|
+
break;
|
|
2271
|
+
case ContainerMessageType.ChunkedOp:
|
|
2272
|
+
case ContainerMessageType.Rejoin:
|
|
2273
|
+
break;
|
|
2274
|
+
default: {
|
|
2275
|
+
// If we didn't necessarily expect a runtime message type, then no worries - just return
|
|
2276
|
+
// e.g. this case applies to system ops, or legacy ops that would have fallen into the above cases anyway.
|
|
2277
|
+
if (!expectRuntimeMessageType) {
|
|
2278
|
+
return;
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
const compatBehavior = compatDetails?.behavior;
|
|
2282
|
+
if (!compatBehaviorAllowsMessageType(maybeContainerMessageType, compatBehavior)) {
|
|
2283
|
+
const error = DataProcessingError.create(
|
|
2284
|
+
// Former assert 0x3ce
|
|
2285
|
+
"Runtime message of unknown type",
|
|
2286
|
+
"OpProcessing",
|
|
2287
|
+
message,
|
|
2288
|
+
{
|
|
2289
|
+
local,
|
|
2290
|
+
messageDetails: JSON.stringify({
|
|
2291
|
+
type: message.type,
|
|
2292
|
+
contentType: typeof message.contents,
|
|
2293
|
+
compatBehavior,
|
|
2294
|
+
batch: (message.metadata as IBatchMetadata | undefined)?.batch,
|
|
2295
|
+
compression: message.compression,
|
|
2296
|
+
}),
|
|
2297
|
+
},
|
|
2298
|
+
);
|
|
2299
|
+
this.closeFn(error);
|
|
2300
|
+
throw error;
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2199
2304
|
}
|
|
2200
2305
|
|
|
2201
2306
|
/**
|
|
@@ -2834,7 +2939,7 @@ export class ContainerRuntime
|
|
|
2834
2939
|
* @param options - options controlling how the summary is generated or submitted
|
|
2835
2940
|
*/
|
|
2836
2941
|
public async submitSummary(options: ISubmitSummaryOptions): Promise<SubmitSummaryResult> {
|
|
2837
|
-
const { fullTree = false, refreshLatestAck, summaryLogger } = options;
|
|
2942
|
+
const { fullTree = false, finalAttempt = false, refreshLatestAck, summaryLogger } = options;
|
|
2838
2943
|
// The summary number for this summary. This will be updated during the summary process, so get it now and
|
|
2839
2944
|
// use it for all events logged during this summary.
|
|
2840
2945
|
const summaryNumber = this.nextSummaryNumber;
|
|
@@ -2952,9 +3057,9 @@ export class ContainerRuntime
|
|
|
2952
3057
|
};
|
|
2953
3058
|
}
|
|
2954
3059
|
|
|
2955
|
-
// If validateSummaryBeforeUpload is true, validate that the summary generated
|
|
2956
|
-
// correct before this summary is uploaded.
|
|
3060
|
+
// If validateSummaryBeforeUpload is true, validate that the summary generated is correct before uploading.
|
|
2957
3061
|
if (this.validateSummaryBeforeUpload) {
|
|
3062
|
+
// Validate that the summaries generated by summarize nodes is correct.
|
|
2958
3063
|
const validateResult = this.summarizerNode.validateSummary();
|
|
2959
3064
|
if (!validateResult.success) {
|
|
2960
3065
|
const { success, ...loggingProps } = validateResult;
|
|
@@ -2970,6 +3075,49 @@ export class ContainerRuntime
|
|
|
2970
3075
|
error,
|
|
2971
3076
|
};
|
|
2972
3077
|
}
|
|
3078
|
+
|
|
3079
|
+
// If there are pending messages, the summary has more data than at the summaryRefSeqNum.
|
|
3080
|
+
if (this.hasPendingMessages()) {
|
|
3081
|
+
// If "SkipFailingIncorrectSummary" option is true, don't fail the summary in the last attempt.
|
|
3082
|
+
// This is a fallback to make progress in documents where there are consistently pending ops in
|
|
3083
|
+
// the summarizer.
|
|
3084
|
+
if (
|
|
3085
|
+
finalAttempt &&
|
|
3086
|
+
this.mc.config.getBoolean("Fluid.Summarizer.SkipFailingIncorrectSummary")
|
|
3087
|
+
) {
|
|
3088
|
+
const error = DataProcessingError.create(
|
|
3089
|
+
"Pending ops during summarization",
|
|
3090
|
+
"submitSummary",
|
|
3091
|
+
undefined,
|
|
3092
|
+
{ pendingMessages: this.pendingMessagesCount },
|
|
3093
|
+
);
|
|
3094
|
+
summaryNumberLogger.sendErrorEvent(
|
|
3095
|
+
{
|
|
3096
|
+
eventName: "SkipFailingIncorrectSummary",
|
|
3097
|
+
referenceSequenceNumber: summaryRefSeqNum,
|
|
3098
|
+
minimumSequenceNumber,
|
|
3099
|
+
},
|
|
3100
|
+
error,
|
|
3101
|
+
);
|
|
3102
|
+
} else {
|
|
3103
|
+
// Default retry delay is 1 second. This can be overridden via config so that we can adjust it
|
|
3104
|
+
// based on telemetry while we decide on a stable number.
|
|
3105
|
+
const retryDelayMs =
|
|
3106
|
+
this.mc.config.getNumber("Fluid.Summarizer.PendingOpsRetryDelayMs") ??
|
|
3107
|
+
1000;
|
|
3108
|
+
const error = new RetriableSummaryError(
|
|
3109
|
+
"PendingMessagesInSummary",
|
|
3110
|
+
retryDelayMs / 1000,
|
|
3111
|
+
{ count: this.pendingMessagesCount },
|
|
3112
|
+
);
|
|
3113
|
+
return {
|
|
3114
|
+
stage: "base",
|
|
3115
|
+
referenceSequenceNumber: summaryRefSeqNum,
|
|
3116
|
+
minimumSequenceNumber,
|
|
3117
|
+
error,
|
|
3118
|
+
};
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
2973
3121
|
}
|
|
2974
3122
|
|
|
2975
3123
|
const { summary: summaryTree, stats: partialStats } = summarizeResult;
|
|
@@ -3110,8 +3258,12 @@ export class ContainerRuntime
|
|
|
3110
3258
|
}
|
|
3111
3259
|
}
|
|
3112
3260
|
|
|
3261
|
+
private get pendingMessagesCount(): number {
|
|
3262
|
+
return this.pendingStateManager.pendingMessagesCount + this.outbox.messageCount;
|
|
3263
|
+
}
|
|
3264
|
+
|
|
3113
3265
|
private hasPendingMessages() {
|
|
3114
|
-
return this.
|
|
3266
|
+
return this.pendingMessagesCount !== 0;
|
|
3115
3267
|
}
|
|
3116
3268
|
|
|
3117
3269
|
private updateDocumentDirtyState(dirty: boolean) {
|
|
@@ -3178,7 +3330,7 @@ export class ContainerRuntime
|
|
|
3178
3330
|
);
|
|
3179
3331
|
idRange = this.idCompressor.takeNextCreationRange();
|
|
3180
3332
|
// Don't include the idRange if there weren't any Ids allocated
|
|
3181
|
-
idRange = idRange?.ids
|
|
3333
|
+
idRange = idRange?.ids !== undefined ? idRange : undefined;
|
|
3182
3334
|
}
|
|
3183
3335
|
|
|
3184
3336
|
if (idRange !== undefined) {
|
|
@@ -3439,11 +3591,31 @@ export class ContainerRuntime
|
|
|
3439
3591
|
case ContainerMessageType.Rejoin:
|
|
3440
3592
|
this.submit(message);
|
|
3441
3593
|
break;
|
|
3442
|
-
default:
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
)
|
|
3594
|
+
default: {
|
|
3595
|
+
// This case should be very rare - it would imply an op was stashed from a
|
|
3596
|
+
// future version of runtime code and now is being applied on an older version
|
|
3597
|
+
const compatBehavior = message.compatDetails?.behavior;
|
|
3598
|
+
if (compatBehaviorAllowsMessageType(message.type, compatBehavior)) {
|
|
3599
|
+
this.logger.sendTelemetryEvent({
|
|
3600
|
+
eventName: "resubmitUnrecognizedMessageTypeAllowed",
|
|
3601
|
+
messageDetails: { type: message.type, compatBehavior },
|
|
3602
|
+
});
|
|
3603
|
+
} else {
|
|
3604
|
+
const error = DataProcessingError.create(
|
|
3605
|
+
"Resubmitting runtime message of unknown type",
|
|
3606
|
+
"reSubmitCore",
|
|
3607
|
+
undefined /* sequencedMessage */,
|
|
3608
|
+
{
|
|
3609
|
+
messageDetails: JSON.stringify({
|
|
3610
|
+
type: message.type,
|
|
3611
|
+
compatBehavior,
|
|
3612
|
+
}),
|
|
3613
|
+
},
|
|
3614
|
+
);
|
|
3615
|
+
this.closeFn(error);
|
|
3616
|
+
throw error;
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3447
3619
|
}
|
|
3448
3620
|
}
|
|
3449
3621
|
|
|
@@ -3457,6 +3629,7 @@ export class ContainerRuntime
|
|
|
3457
3629
|
this.dataStores.rollbackDataStoreOp(contents as IEnvelope, localOpMetadata);
|
|
3458
3630
|
break;
|
|
3459
3631
|
default:
|
|
3632
|
+
// Don't check message.compatDetails because this is for rolling back a local op so the type will be known
|
|
3460
3633
|
throw new Error(`Can't rollback ${type}`);
|
|
3461
3634
|
}
|
|
3462
3635
|
}
|
|
@@ -3489,7 +3662,7 @@ export class ContainerRuntime
|
|
|
3489
3662
|
// It should only be done by the summarizerNode, if required.
|
|
3490
3663
|
// When fetching from storage we will always get the latest version and do not use the ackHandle.
|
|
3491
3664
|
const fetchLatestSnapshot: () => Promise<IFetchSnapshotResult> = async () => {
|
|
3492
|
-
let fetchResult = await this.
|
|
3665
|
+
let fetchResult = await this.fetchSnapshotFromStorageAndMaybeClose(
|
|
3493
3666
|
summaryLogger,
|
|
3494
3667
|
{
|
|
3495
3668
|
eventName: "RefreshLatestSummaryAckFetch",
|
|
@@ -3497,6 +3670,7 @@ export class ContainerRuntime
|
|
|
3497
3670
|
targetSequenceNumber: summaryRefSeq,
|
|
3498
3671
|
},
|
|
3499
3672
|
readAndParseBlob,
|
|
3673
|
+
null,
|
|
3500
3674
|
);
|
|
3501
3675
|
|
|
3502
3676
|
/**
|
|
@@ -3506,7 +3680,7 @@ export class ContainerRuntime
|
|
|
3506
3680
|
* change that started fetching latest snapshot always.
|
|
3507
3681
|
*/
|
|
3508
3682
|
if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
|
|
3509
|
-
fetchResult = await this.
|
|
3683
|
+
fetchResult = await this.fetchSnapshotFromStorageAndMaybeClose(
|
|
3510
3684
|
summaryLogger,
|
|
3511
3685
|
{
|
|
3512
3686
|
eventName: "RefreshLatestSummaryAckFetchBackCompat",
|
|
@@ -3579,12 +3753,13 @@ export class ContainerRuntime
|
|
|
3579
3753
|
): Promise<{ latestSnapshotRefSeq: number; latestSnapshotVersionId: string | undefined }> {
|
|
3580
3754
|
const readAndParseBlob = async <T>(id: string) => readAndParse<T>(this.storage, id);
|
|
3581
3755
|
const { snapshotTree, versionId, latestSnapshotRefSeq } =
|
|
3582
|
-
await this.
|
|
3756
|
+
await this.fetchSnapshotFromStorageAndMaybeClose(
|
|
3583
3757
|
summaryLogger,
|
|
3584
3758
|
{
|
|
3585
3759
|
eventName: "RefreshLatestSummaryFromServerFetch",
|
|
3586
3760
|
},
|
|
3587
3761
|
readAndParseBlob,
|
|
3762
|
+
null,
|
|
3588
3763
|
);
|
|
3589
3764
|
const fetchLatestSnapshot: IFetchSnapshotResult = {
|
|
3590
3765
|
snapshotTree,
|
|
@@ -3608,20 +3783,12 @@ export class ContainerRuntime
|
|
|
3608
3783
|
return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
|
|
3609
3784
|
}
|
|
3610
3785
|
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
logger,
|
|
3618
|
-
event,
|
|
3619
|
-
readAndParseBlob,
|
|
3620
|
-
null /* latest */,
|
|
3621
|
-
);
|
|
3622
|
-
}
|
|
3623
|
-
|
|
3624
|
-
private async fetchSnapshotFromStorageAndClose(
|
|
3786
|
+
/**
|
|
3787
|
+
* Downloads snapshot from storage with the given versionId or latest if versionId is null.
|
|
3788
|
+
* By default, it also closes the container after downloading the snapshot. However, this may be
|
|
3789
|
+
* overridden via options.
|
|
3790
|
+
*/
|
|
3791
|
+
private async fetchSnapshotFromStorageAndMaybeClose(
|
|
3625
3792
|
logger: ITelemetryLoggerExt,
|
|
3626
3793
|
event: ITelemetryGenericEvent,
|
|
3627
3794
|
readAndParseBlob: ReadAndParseBlob,
|
|
@@ -3710,42 +3877,48 @@ export class ContainerRuntime
|
|
|
3710
3877
|
throw new UsageError("can't get state during orderSequentially");
|
|
3711
3878
|
}
|
|
3712
3879
|
const pendingAttachmentBlobs = await this.blobManager.getPendingBlobs(waitBlobsToAttach);
|
|
3880
|
+
|
|
3881
|
+
if (!pendingAttachmentBlobs && !this.hasPendingMessages()) {
|
|
3882
|
+
return; // no pending state to save
|
|
3883
|
+
}
|
|
3884
|
+
|
|
3713
3885
|
// Flush pending batch.
|
|
3714
3886
|
// getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
|
|
3715
3887
|
// to close current batch.
|
|
3716
3888
|
this.flush();
|
|
3717
3889
|
|
|
3718
|
-
|
|
3890
|
+
const pendingState: IPendingRuntimeState = {
|
|
3719
3891
|
pending: this.pendingStateManager.getLocalState(),
|
|
3720
3892
|
pendingAttachmentBlobs,
|
|
3721
3893
|
};
|
|
3894
|
+
return pendingState;
|
|
3722
3895
|
}
|
|
3723
3896
|
|
|
3724
|
-
public
|
|
3897
|
+
public summarizeOnDemand(options: IOnDemandSummarizeOptions): ISummarizeResults {
|
|
3725
3898
|
if (this.isSummarizerClient) {
|
|
3726
|
-
return this.summarizer.summarizeOnDemand(
|
|
3899
|
+
return this.summarizer.summarizeOnDemand(options);
|
|
3727
3900
|
} else if (this.summaryManager !== undefined) {
|
|
3728
|
-
return this.summaryManager.summarizeOnDemand(
|
|
3901
|
+
return this.summaryManager.summarizeOnDemand(options);
|
|
3729
3902
|
} else {
|
|
3730
3903
|
// If we're not the summarizer, and we don't have a summaryManager, we expect that
|
|
3731
3904
|
// disableSummaries is turned on. We are throwing instead of returning a failure here,
|
|
3732
3905
|
// because it is a misuse of the API rather than an expected failure.
|
|
3733
3906
|
throw new UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
3734
3907
|
}
|
|
3735
|
-
}
|
|
3908
|
+
}
|
|
3736
3909
|
|
|
3737
|
-
public
|
|
3910
|
+
public enqueueSummarize(options: IEnqueueSummarizeOptions): EnqueueSummarizeResult {
|
|
3738
3911
|
if (this.isSummarizerClient) {
|
|
3739
|
-
return this.summarizer.enqueueSummarize(
|
|
3912
|
+
return this.summarizer.enqueueSummarize(options);
|
|
3740
3913
|
} else if (this.summaryManager !== undefined) {
|
|
3741
|
-
return this.summaryManager.enqueueSummarize(
|
|
3914
|
+
return this.summaryManager.enqueueSummarize(options);
|
|
3742
3915
|
} else {
|
|
3743
3916
|
// If we're not the summarizer, and we don't have a summaryManager, we expect that
|
|
3744
3917
|
// generateSummaries is turned off. We are throwing instead of returning a failure here,
|
|
3745
3918
|
// because it is a misuse of the API rather than an expected failure.
|
|
3746
3919
|
throw new UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
|
|
3747
3920
|
}
|
|
3748
|
-
}
|
|
3921
|
+
}
|
|
3749
3922
|
|
|
3750
3923
|
/**
|
|
3751
3924
|
* * Forms a function that will request a Summarizer.
|