@fluidframework/container-runtime 2.0.0-internal.6.3.3 → 2.0.0-internal.6.4.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 +8 -0
- package/dist/blobManager.d.ts +3 -2
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +29 -25
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +14 -69
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +155 -184
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +3 -1
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +1 -1
- package/dist/dataStores.js +3 -3
- package/dist/dataStores.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +6 -3
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +6 -3
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +13 -2
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +14 -15
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +0 -9
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +1 -13
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +1 -4
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/index.d.ts +2 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +3 -4
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/messageTypes.d.ts +134 -0
- package/dist/messageTypes.d.ts.map +1 -0
- package/dist/messageTypes.js +29 -0
- package/dist/messageTypes.js.map +1 -0
- package/dist/opLifecycle/definitions.d.ts +2 -1
- package/dist/opLifecycle/definitions.d.ts.map +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +0 -4
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js +4 -2
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/opSplitter.js +3 -3
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +17 -3
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +38 -25
- 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 +2 -2
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +13 -6
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +1 -1
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +4 -2
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +2 -2
- package/dist/summary/summarizer.js +2 -2
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.d.ts +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +2 -1
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +3 -0
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js +3 -0
- package/dist/summary/summaryFormat.js.map +1 -1
- package/lib/blobManager.d.ts +3 -2
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +30 -26
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +14 -69
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +121 -150
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +3 -1
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +1 -1
- package/lib/dataStores.js +4 -4
- package/lib/dataStores.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +6 -3
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +6 -3
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +13 -2
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +13 -14
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +0 -9
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +0 -11
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +1 -4
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/index.d.ts +2 -2
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +2 -2
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/messageTypes.d.ts +134 -0
- package/lib/messageTypes.d.ts.map +1 -0
- package/lib/messageTypes.js +26 -0
- package/lib/messageTypes.js.map +1 -0
- package/lib/opLifecycle/definitions.d.ts +2 -1
- package/lib/opLifecycle/definitions.d.ts.map +1 -1
- package/lib/opLifecycle/definitions.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +0 -4
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js +4 -2
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/opSplitter.js +1 -1
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +17 -3
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +37 -24
- 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 +2 -2
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +12 -5
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +1 -1
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +4 -2
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -2
- package/lib/summary/summarizer.js +2 -2
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.ts +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +2 -1
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +3 -0
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js +3 -0
- package/lib/summary/summaryFormat.js.map +1 -1
- package/package.json +16 -16
- package/src/blobManager.ts +38 -28
- package/src/containerRuntime.ts +181 -245
- package/src/dataStoreContext.ts +3 -1
- package/src/dataStores.ts +4 -4
- package/src/gc/garbageCollection.md +53 -5
- package/src/gc/garbageCollection.ts +6 -3
- package/src/gc/gcDefinitions.ts +13 -14
- package/src/gc/gcEarlyAdoption.md +145 -0
- package/src/gc/gcHelpers.ts +0 -12
- package/src/gc/gcTelemetry.ts +1 -4
- package/src/gc/index.ts +2 -3
- package/src/index.ts +7 -4
- package/src/messageTypes.ts +225 -0
- package/src/opLifecycle/README.md +40 -40
- package/src/opLifecycle/definitions.ts +2 -1
- package/src/opLifecycle/opDecompressor.ts +0 -8
- package/src/opLifecycle/opGroupingManager.ts +7 -6
- package/src/opLifecycle/opSplitter.ts +2 -2
- package/src/opLifecycle/remoteMessageProcessor.ts +54 -33
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +23 -6
- package/src/summary/runningSummarizer.ts +4 -2
- package/src/summary/summarizer.ts +2 -2
- package/src/summary/summarizerNode/summarizerNode.ts +1 -1
- package/src/summary/summarizerTypes.ts +2 -1
- package/src/summary/summaryFormat.ts +3 -0
package/src/dataStoreContext.ts
CHANGED
|
@@ -314,7 +314,9 @@ export abstract class FluidDataStoreContext
|
|
|
314
314
|
properties: {
|
|
315
315
|
all: tagCodeArtifacts({
|
|
316
316
|
fluidDataStoreId: this.id,
|
|
317
|
-
|
|
317
|
+
// The package name is a getter because `this.pkg` may not be initialized during construction.
|
|
318
|
+
// For data stores loaded from summary, it is initialized during data store realization.
|
|
319
|
+
fullPackageName: () => this.pkg?.join("/"),
|
|
318
320
|
}),
|
|
319
321
|
},
|
|
320
322
|
});
|
package/src/dataStores.ts
CHANGED
|
@@ -67,7 +67,7 @@ import { StorageServiceWithAttachBlobs } from "./storageServiceWithAttachBlobs";
|
|
|
67
67
|
import { IDataStoreAliasMessage, isDataStoreAliasMessage } from "./dataStore";
|
|
68
68
|
import {
|
|
69
69
|
GCNodeType,
|
|
70
|
-
|
|
70
|
+
disableDatastoreSweepKey,
|
|
71
71
|
throwOnTombstoneLoadKey,
|
|
72
72
|
sendGCUnexpectedUsageEvent,
|
|
73
73
|
} from "./gc";
|
|
@@ -212,7 +212,7 @@ export class DataStores implements IDisposable {
|
|
|
212
212
|
|
|
213
213
|
public async waitIfPendingAlias(maybeAlias: string): Promise<AliasResult> {
|
|
214
214
|
const pendingAliasPromise = this.pendingAliases.get(maybeAlias);
|
|
215
|
-
return pendingAliasPromise
|
|
215
|
+
return pendingAliasPromise ?? "Success";
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
public processAttachMessage(message: ISequencedDocumentMessage, local: boolean) {
|
|
@@ -820,11 +820,11 @@ export class DataStores implements IDisposable {
|
|
|
820
820
|
* Delete data stores and its objects that are sweep ready.
|
|
821
821
|
* @param sweepReadyDataStoreRoutes - The routes of data stores and its objects that are sweep ready and should
|
|
822
822
|
* be deleted.
|
|
823
|
-
* @returns
|
|
823
|
+
* @returns The routes of data stores and its objects that were deleted.
|
|
824
824
|
*/
|
|
825
825
|
public deleteSweepReadyNodes(sweepReadyDataStoreRoutes: string[]): string[] {
|
|
826
826
|
// If sweep for data stores is not enabled, return empty list indicating nothing is deleted.
|
|
827
|
-
if (this.mc.config.getBoolean(
|
|
827
|
+
if (this.mc.config.getBoolean(disableDatastoreSweepKey) === true) {
|
|
828
828
|
return [];
|
|
829
829
|
}
|
|
830
830
|
for (const route of sweepReadyDataStoreRoutes) {
|
|
@@ -48,12 +48,60 @@ In this phase, the GC algorithm identifies all Fluid objects that are unreferenc
|
|
|
48
48
|
|
|
49
49
|
Mark phase is enabled by default for a container. It is enabled during creation of the container runtime and remains enabled throughout its lifetime. Basically, this setting is persisted in the summary and cannot be changed.
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
### Sweep phase
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
In this phase, the GC algorithm identifies all Fluid objects that have been unreferenced for a specific amount of time (typically 30-40 days) and deletes them.
|
|
54
|
+
Objects are only swept once the GC system is sure that they could never be referenced again by any active clients, i.e., clients that have the object in memory and could reference it.
|
|
55
|
+
The Fluid Runtime enforces a maximum session length (configurable) in order to guarantee an object is safe to delete after sufficient time has elapsed.
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
GC sweep phase has not been enabled by default yet. A "soft" version of Sweep called "Tombstone Mode" is enabled by default
|
|
58
|
+
as part of the Mark Phase when Sweep is disabled. In this mode, any object that GC determines is ready to be deleted is
|
|
59
|
+
marked as a "Tombstone", which triggers certain logging events and/or behavior changes if/when that Tombstoned object is
|
|
60
|
+
accessed by the application.
|
|
61
|
+
|
|
62
|
+
Tombstone is intended for use by early adopters of GC and is documented in more detail [here](./gcEarlyAdoption.md).
|
|
63
|
+
|
|
64
|
+
## GC Configuration
|
|
65
|
+
|
|
66
|
+
The default configuration for GC today is:
|
|
67
|
+
|
|
68
|
+
- GC Mark Phase is **enabled**, including Tombstone Mode
|
|
69
|
+
- Session Expiry is **enabled**
|
|
70
|
+
- GC Sweep Phase is **disabled**
|
|
71
|
+
- Note: Once enabled, Sweep will only run for documents created from that point forward
|
|
72
|
+
|
|
73
|
+
### Techniques used for configuration
|
|
74
|
+
|
|
75
|
+
There are two ways to configure the Fluid Framework's GC behavior, referred to by name throughout these documents:
|
|
76
|
+
|
|
77
|
+
1. **"GC Options"**: `ContainerRuntime.loadRuntime` takes an options value of type `IContainerRuntimeOptions`.
|
|
78
|
+
This type includes a sub-object `gcOptions`, for GC-specific options.
|
|
79
|
+
2. **"Config Settings"**: The `Loader`'s constructor takes in `ILoaderProps`, which includes `configProvider?: IConfigProviderBase`
|
|
80
|
+
This configProvider can be used to inject config settings.
|
|
81
|
+
|
|
82
|
+
Typically GC Options are used for more "official" and stable configuration, whereas Config Settings provide a mechanism
|
|
83
|
+
for apps to override settings easily, e.g. by backing their `IConfigProviderBase` with a configuration/flighting service.
|
|
84
|
+
In cases where a behavior is controlled by both a Config Setting and GC Option, you may experiment at first using Config Settings
|
|
85
|
+
and then later update the passed-in GC Options to finalize the configuration in your code.
|
|
86
|
+
|
|
87
|
+
### Disabling Mark Phase
|
|
88
|
+
|
|
89
|
+
If you wish to disable Mark Phase for newly-created documents, set the `gcAllowed` GC Option to `false`.
|
|
90
|
+
Note that this will disable GC permanently (including the sweep phase) for the container during its lifetime.
|
|
91
|
+
|
|
92
|
+
Mark Phase can also be disabled just for the session, among other behaviors,
|
|
93
|
+
covered in the [Advanced Configuration](./gcEarlyAdoption.md#more-advanced-configurations) docs.
|
|
94
|
+
|
|
95
|
+
### Enabling Sweep Phase
|
|
96
|
+
|
|
97
|
+
To enable Sweep Phase for new documents, you must set the `gcSweepGeneration` GC Option to a number, e.g. 0 to start.
|
|
98
|
+
The full semantics of this GC Option are discussed [here](./gcEarlyAdoption.md#more-about-gcsweepgeneration-and-gctombstonegeneration).
|
|
99
|
+
Note that this will disabled Tombstone Mode.
|
|
100
|
+
|
|
101
|
+
A full treatment of Tombstone and Sweep configuration can be found in
|
|
102
|
+
[this companion document geared towards early adopters of GC](./gcEarlyAdoption.md).
|
|
56
103
|
|
|
57
|
-
|
|
104
|
+
### More Advanced Configuration
|
|
58
105
|
|
|
59
|
-
|
|
106
|
+
For additional behaviors that can be configured (e.g. for testing), please see these
|
|
107
|
+
[Advanced Configuration](./gcEarlyAdoption.md#more-advanced-configurations) docs.
|
|
@@ -577,14 +577,17 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
577
577
|
|
|
578
578
|
/**
|
|
579
579
|
* Runs the GC Mark phase. It does the following:
|
|
580
|
+
*
|
|
580
581
|
* 1. Marks all referenced nodes in this run by clearing tracking for them.
|
|
582
|
+
*
|
|
581
583
|
* 2. Marks unreferenced nodes in this run by starting tracking for them.
|
|
584
|
+
*
|
|
582
585
|
* 3. Calls the runtime to update nodes that were marked referenced.
|
|
583
586
|
*
|
|
584
587
|
* @param gcResult - The result of the GC run on the gcData.
|
|
585
588
|
* @param allReferencedNodeIds - Nodes referenced in this GC run + referenced between previous and current GC run.
|
|
586
589
|
* @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
|
|
587
|
-
* @returns
|
|
590
|
+
* @returns A list of sweep ready nodes, i.e., nodes that ready to be deleted.
|
|
588
591
|
*/
|
|
589
592
|
private runMarkPhase(
|
|
590
593
|
gcResult: IGCResult,
|
|
@@ -643,7 +646,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
643
646
|
* @param sweepReadyNodes - List of nodes that are sweep ready.
|
|
644
647
|
* @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
|
|
645
648
|
* @param logger - The logger to be used to log any telemetry.
|
|
646
|
-
* @returns
|
|
649
|
+
* @returns A list of nodes that have been deleted.
|
|
647
650
|
*/
|
|
648
651
|
private runSweepPhase(
|
|
649
652
|
gcResult: IGCResult,
|
|
@@ -722,7 +725,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
722
725
|
* This function identifies nodes that were referenced since the last run.
|
|
723
726
|
* If these nodes are currently unreferenced, they will be assigned new unreferenced state by the current run.
|
|
724
727
|
*
|
|
725
|
-
* @returns
|
|
728
|
+
* @returns A list of all nodes referenced from the last local summary until now.
|
|
726
729
|
*/
|
|
727
730
|
private findAllNodesReferencedBetweenGCs(
|
|
728
731
|
currentGCData: IGarbageCollectionData,
|
package/src/gc/gcDefinitions.ts
CHANGED
|
@@ -43,29 +43,28 @@ export const gcTombstoneGenerationOptionName = "gcTombstoneGeneration";
|
|
|
43
43
|
*/
|
|
44
44
|
export const gcSweepGenerationOptionName = "gcSweepGeneration";
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
/** Config key to turn GC on / off. */
|
|
47
47
|
export const runGCKey = "Fluid.GarbageCollection.RunGC";
|
|
48
|
-
|
|
48
|
+
/** Config key to turn GC sweep on / off. */
|
|
49
49
|
export const runSweepKey = "Fluid.GarbageCollection.RunSweep";
|
|
50
|
-
|
|
50
|
+
/** Config key to turn GC test mode on / off. */
|
|
51
51
|
export const gcTestModeKey = "Fluid.GarbageCollection.GCTestMode";
|
|
52
|
-
|
|
52
|
+
/** Config key to expire a session after a set period of time. Defaults to true. */
|
|
53
53
|
export const runSessionExpiryKey = "Fluid.GarbageCollection.RunSessionExpiry";
|
|
54
|
-
|
|
54
|
+
/** Config key to turn GC sweep log off. */
|
|
55
55
|
export const disableSweepLogKey = "Fluid.GarbageCollection.DisableSweepLog";
|
|
56
|
-
|
|
56
|
+
/** Config key to disable the tombstone feature, i.e., tombstone information is not read / written into summary. */
|
|
57
57
|
export const disableTombstoneKey = "Fluid.GarbageCollection.DisableTombstone";
|
|
58
|
-
|
|
58
|
+
/** Config key to enable throwing an error when tombstone object is loaded (requested). */
|
|
59
59
|
export const throwOnTombstoneLoadKey = "Fluid.GarbageCollection.ThrowOnTombstoneLoad";
|
|
60
|
-
|
|
60
|
+
/** Config key to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops). */
|
|
61
61
|
export const throwOnTombstoneUsageKey = "Fluid.GarbageCollection.ThrowOnTombstoneUsage";
|
|
62
|
-
|
|
62
|
+
/** Config key to enable GC version upgrade. */
|
|
63
63
|
export const gcVersionUpgradeToV4Key = "Fluid.GarbageCollection.GCVersionUpgradeToV4";
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
export const sweepAttachmentBlobsKey = "Fluid.GarbageCollection.Test.SweepAttachmentBlobs";
|
|
64
|
+
/** Config key to disable GC sweep for datastores. */
|
|
65
|
+
export const disableDatastoreSweepKey = "Fluid.GarbageCollection.DisableDataStoreSweep";
|
|
66
|
+
/** Config key to disable GC sweep for attachment blobs. */
|
|
67
|
+
export const disableAttachmentBlobSweepKey = "Fluid.GarbageCollection.DisableAttachmentBlobSweep";
|
|
69
68
|
|
|
70
69
|
// One day in milliseconds.
|
|
71
70
|
export const oneDayMs = 1 * 24 * 60 * 60 * 1000;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Garbage Collection: Advanced configuration for early adopters
|
|
2
|
+
|
|
3
|
+
_For a technical overview of Garbage Collection, start with [GarbageCollection.md](./garbageCollection.md)_
|
|
4
|
+
|
|
5
|
+
GC Sweep is not yet enabled by default, and until that time early adopters have several configuration options available
|
|
6
|
+
for how to enable GC and monitor for any GC-impacting bugs that would need to be mitigated.
|
|
7
|
+
|
|
8
|
+
Please refer to the section [Techniques Used for Configuration](./garbageCollection.md#techniques-used-for-configuration)
|
|
9
|
+
before continuing, to ensure you're familiar with using "GC Options" and "Config Settings" for configuring GC.
|
|
10
|
+
|
|
11
|
+
## What's on by default
|
|
12
|
+
|
|
13
|
+
GC Mark Phase is enabled by default, which includes marking objects that are ready to be deleted as Tombstones.
|
|
14
|
+
FF will log an informational event if/when a Tombstoned object is loaded - a scenario that would represent data loss if Sweep were enabled.
|
|
15
|
+
The eventName for the Tombstone log ends with `GC_Tombstone_DataStore_Requested`.
|
|
16
|
+
|
|
17
|
+
There's a similar event logged long before an object is Tombstoned. Ater only 7 days (configurable), an unreferenced object is considered
|
|
18
|
+
"Inactive", and FF will log if an Inactive object is loaded as well.
|
|
19
|
+
The eventName for the Inactive log ends with `InactiveObject_Loaded`.
|
|
20
|
+
|
|
21
|
+
## Getting earlier signals: Shortening the InactiveObject timeout
|
|
22
|
+
|
|
23
|
+
The default timeout for an unreferenced object to become "Inactive" is 7 days. This is intended to be long enough such that
|
|
24
|
+
it's very unlikely to hit a legitimate case where an object is revived within the same session it was deleted (e.g. delete then undo).
|
|
25
|
+
Based on your application's user experience, you may choose to shorten this timeout to get an earlier signal (but beware of false positives).
|
|
26
|
+
|
|
27
|
+
To override the default InactiveObject timeout, use the `inactiveTimeoutMs` GC Option.
|
|
28
|
+
There's also a Config Setting which can be used for testing (if the Config Provider allows overriding via localStorage/sessionStorage):
|
|
29
|
+
`Fluid.GarbageCollection.TestOverride.InactiveTimeoutMs`
|
|
30
|
+
|
|
31
|
+
## Enabling Tombstone Enforcement
|
|
32
|
+
|
|
33
|
+
By default, GC is marking objects as Tombstoned, but merely logging if they're used after that point.
|
|
34
|
+
You can enable enforcement of Tombstone objects to simulate real Sweep while having the peace of mind
|
|
35
|
+
that the data is not yet deleted from the user's file, and can be recovered.
|
|
36
|
+
|
|
37
|
+
The first step is to prevent the Fluid Framework from loading a Tombstoned object (via `handle.get()` as described previously),
|
|
38
|
+
by using this Config Setting:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
"Fluid.GarbageCollection.ThrowOnTombstoneLoad": true
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Now, even with `Fluid.GarbageCollection.ThrowOnTombstoneLoad` set to true, changes to a Tombstoned object will be allowed.
|
|
45
|
+
This is required for the advanced recovery options to work, explained [below](#advanced-back-door-recovering-and-reviving-tombstoned-objects).
|
|
46
|
+
|
|
47
|
+
To instruct FF to treat Tombstoned objects as if they are truly not present in the document, use this Config Setting:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
"Fluid.GarbageCollection.ThrowOnTombstoneUsage": true
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### In case of emergency: Bumping the gcTombstoneGeneration
|
|
54
|
+
|
|
55
|
+
GC includes a mechanism for Tombstone by which all new documents may be stamped with a "Generation" number,
|
|
56
|
+
and if set then Tombstone is only enforceable for documents of the latest Generation. This number is specified
|
|
57
|
+
via the `gcTombstoneGeneration` GC Option, and will not change over the lifetime of a given document.
|
|
58
|
+
|
|
59
|
+
In case a bug is released that is found to cause GC errors, a bump to the gcTombstoneGeneration can be incuded
|
|
60
|
+
with the fix, which will prevent any user pain for those potentially affected documents that were exposed to the bug.
|
|
61
|
+
|
|
62
|
+
If gcTombstoneGeneration is unset, Tombstone enforcement will be enabled/disabled as otherwise configured.
|
|
63
|
+
In other words, until you start using this, Tombstone enforcement will apply to all documents.
|
|
64
|
+
|
|
65
|
+
### Advanced "Back door": Recovering and reviving Tombstoned objects
|
|
66
|
+
|
|
67
|
+
If your application has Tombstone enabled and your users are encountering Tombstones - even at the point where
|
|
68
|
+
Tombstone enforcement is enabled - there is a way to still access these objects to recover them and property
|
|
69
|
+
reference them ("revival"). However, please understand that this is an advanced and unsupported path that may
|
|
70
|
+
be immediately deprecated at any time.
|
|
71
|
+
|
|
72
|
+
As mentioned above, bumping the gcTombstoneGeneration will free up impacted documents, but that's a permanent
|
|
73
|
+
mitigation - those documents will never be exposed to GC Tombstone or Sweep.
|
|
74
|
+
|
|
75
|
+
If there's a particular codepath in your application where objects being loaded may be Tombstoned,
|
|
76
|
+
you may use this advanced "back door" to recover them and then properly reference them, thus restoring the document.
|
|
77
|
+
For this to work, you must disable the `Fluid.GarbageCollection.ThrowOnTombstoneUsage` Config Setting.
|
|
78
|
+
|
|
79
|
+
When a Tombstoned object (via `handle.get()`) fails to load, the 404 response error object has an `underlyingResponseHeaders` with the
|
|
80
|
+
`isTombstoned` flag set to true: i.e. `error.underlyingResponseHeaders?.isTombstoned === true`. In this case,
|
|
81
|
+
you may turn around and use `IContainerRuntime.resolveHandle` with `allowTombstone: true` in `IRequest.headers` to request
|
|
82
|
+
the object again - this time it will succeed.
|
|
83
|
+
|
|
84
|
+
To be very clear once again - This path uses deprecated APIs (`resolveHandle`) and comes with no guarantees of support.
|
|
85
|
+
|
|
86
|
+
### Tombstones and the Summarizer Client
|
|
87
|
+
|
|
88
|
+
Note: The Summarizer client will _never_ throw on usage or load of a Tombstoned object.
|
|
89
|
+
|
|
90
|
+
## Enabling Sweep
|
|
91
|
+
|
|
92
|
+
To enable Sweep for the first time, set this GC Option:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
gcSweepGeneration: 0;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
This will enable sweep for all documents moving forward _as well as_ any documents created with `gcTombstoneGeneration: 0`
|
|
99
|
+
(this is a special case in the code).
|
|
100
|
+
|
|
101
|
+
### A caveat...
|
|
102
|
+
|
|
103
|
+
If you used `gcTombstoneGeneration` **and ever bumped it**, you should skip 0 here to avoid enabling Sweep for old / at-risk documents:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
gcSweepGeneration: 1;
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Remember, you can always bump `gcSweepGeneration` to disable Sweep for all existing documents and start fresh,
|
|
110
|
+
in case a major bug is discovered and fixed.
|
|
111
|
+
|
|
112
|
+
### More about gcSweepGeneration and gcTombstoneGeneration
|
|
113
|
+
|
|
114
|
+
`gcSweepGeneration` is persisted and immutable in the document, just like `gcTombstoneGeneration`.
|
|
115
|
+
However, behavior differs in a few important ways.
|
|
116
|
+
|
|
117
|
+
For Tombstone, if `gcTombstoneGeneration` is not set, Tombstone enforcement will be **enabled**.
|
|
118
|
+
For Sweep however, if `gcSweepGeneration` is not set, Sweep enforcement will be **disabled**.
|
|
119
|
+
|
|
120
|
+
This means that until the `gcSweepGeneration` GC Option is set, _no existing document will be eligible for Sweep, ever_.
|
|
121
|
+
So all documents created since the most recent bump to the gcSweepGeneration will have Sweep enabled.
|
|
122
|
+
Note that if `gcSweepGeneration` is set and matches, Tombstone Mode is off for the session and `gcTombstoneGeneration` is ignored.
|
|
123
|
+
|
|
124
|
+
And as mentioned above, there is a special case when `gcSweepGeneration === 0`: Any document with `gcTombstoneGeneration: 0` will
|
|
125
|
+
be eligible for Sweep as well. This was done for historical reasons due to circumstances during GC's development.
|
|
126
|
+
|
|
127
|
+
## More Advanced Configurations
|
|
128
|
+
|
|
129
|
+
There are a handful of other configuration options/settings that can be used to tweak GC's behavior,
|
|
130
|
+
mostly for testing. Please refer to the function [`generateGCConfigs` in gcConfigs.ts](./gcConfigs.ts) and the
|
|
131
|
+
[setting/option names listed in gcDefinitions.ts](./gcDefinitions.ts) for the full story.
|
|
132
|
+
|
|
133
|
+
Examples of available advanced configuration include:
|
|
134
|
+
|
|
135
|
+
- Disabling GC permanently for new files
|
|
136
|
+
- Overriding GC Mark/Sweep enablement for this session:
|
|
137
|
+
- Disabling running GC Mark and/or Sweep phases for this session
|
|
138
|
+
- Forcing GC Mark and/or Sweep to run for this session even if otherwise it would be disabled
|
|
139
|
+
- Disabling Tombstone Mode (don't even mark objects as Tombstones)
|
|
140
|
+
- Disabling the deletion of either DataStores or AttachmentBlobs independent of one another (when Sweep is enabled)
|
|
141
|
+
- Overriding the default Session Expiry for new files (or disabling it altogether, which will also disable Tombstone/Sweep)
|
|
142
|
+
- Overriding the Sweep Timeout, _independent of Session Expiry_, so use with care (for testing purposes only - data loss could occur)
|
|
143
|
+
- Running in "Test Mode", where objects are deleted as soon as they're unreferenced
|
|
144
|
+
- Force "Full GC" to run, which ignores incremental optimizations based on previously computed GC Data
|
|
145
|
+
- Treat InactiveObjects like Tombstones: throw an error on load (with the same back door to follow-up with a successful request)
|
package/src/gc/gcHelpers.ts
CHANGED
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
IGarbageCollectionData,
|
|
13
13
|
IGarbageCollectionDetailsBase,
|
|
14
14
|
} from "@fluidframework/runtime-definitions";
|
|
15
|
-
import { TelemetryDataTag } from "@fluidframework/telemetry-utils";
|
|
16
15
|
import { GCFeatureMatrix, GCVersion, IGCMetadata } from "./gcDefinitions";
|
|
17
16
|
import {
|
|
18
17
|
IGarbageCollectionNodeData,
|
|
@@ -304,14 +303,3 @@ export function unpackChildNodesGCDetails(gcDetails: IGarbageCollectionDetailsBa
|
|
|
304
303
|
export function trimLeadingAndTrailingSlashes(str: string) {
|
|
305
304
|
return str.replace(/^\/+|\/+$/g, "");
|
|
306
305
|
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Tags the passed value as a CodeArtifact and returns the tagged value.
|
|
310
|
-
* @deprecated - Use telemetry-utils tagCodeArtifacts instead
|
|
311
|
-
*/
|
|
312
|
-
export function tagAsCodeArtifact(value: string) {
|
|
313
|
-
return {
|
|
314
|
-
value,
|
|
315
|
-
tag: TelemetryDataTag.CodeArtifact,
|
|
316
|
-
};
|
|
317
|
-
}
|
package/src/gc/gcTelemetry.ts
CHANGED
|
@@ -23,8 +23,6 @@ import {
|
|
|
23
23
|
runSweepKey,
|
|
24
24
|
} from "./gcDefinitions";
|
|
25
25
|
import { UnreferencedStateTracker } from "./gcUnreferencedStateTracker";
|
|
26
|
-
// eslint-disable-next-line import/no-deprecated
|
|
27
|
-
import { tagAsCodeArtifact } from "./gcHelpers";
|
|
28
26
|
|
|
29
27
|
type NodeUsageType = "Changed" | "Loaded" | "Revived";
|
|
30
28
|
|
|
@@ -184,8 +182,7 @@ export class GCTelemetryTracker {
|
|
|
184
182
|
{
|
|
185
183
|
eventName: `GC_Tombstone_${nodeType}_Revived`,
|
|
186
184
|
category: "generic",
|
|
187
|
-
|
|
188
|
-
url: tagAsCodeArtifact(id),
|
|
185
|
+
...tagCodeArtifacts({ url: id }),
|
|
189
186
|
gcTombstoneEnforcementAllowed: this.gcTombstoneEnforcementAllowed,
|
|
190
187
|
},
|
|
191
188
|
undefined /* packagePath */,
|
package/src/gc/index.ts
CHANGED
|
@@ -29,8 +29,8 @@ export {
|
|
|
29
29
|
runSessionExpiryKey,
|
|
30
30
|
runSweepKey,
|
|
31
31
|
stableGCVersion,
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
disableAttachmentBlobSweepKey,
|
|
33
|
+
disableDatastoreSweepKey,
|
|
34
34
|
throwOnTombstoneLoadKey,
|
|
35
35
|
throwOnTombstoneUsageKey,
|
|
36
36
|
UnreferencedState,
|
|
@@ -42,7 +42,6 @@ export {
|
|
|
42
42
|
shouldAllowGcSweep,
|
|
43
43
|
trimLeadingAndTrailingSlashes,
|
|
44
44
|
unpackChildNodesGCDetails,
|
|
45
|
-
tagAsCodeArtifact,
|
|
46
45
|
} from "./gcHelpers";
|
|
47
46
|
export { runGarbageCollection } from "./gcReferenceGraphAlgorithm";
|
|
48
47
|
export {
|
package/src/index.ts
CHANGED
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
export {
|
|
7
|
-
ContainerMessageType,
|
|
8
|
-
ContainerRuntimeMessage,
|
|
9
|
-
IContainerRuntimeMessageCompatDetails,
|
|
10
|
-
CompatModeBehavior,
|
|
11
7
|
ISummaryRuntimeOptions,
|
|
12
8
|
ISummaryBaseConfiguration,
|
|
13
9
|
ISummaryConfigurationHeuristics,
|
|
@@ -28,6 +24,13 @@ export {
|
|
|
28
24
|
ICompressionRuntimeOptions,
|
|
29
25
|
CompressionAlgorithms,
|
|
30
26
|
} from "./containerRuntime";
|
|
27
|
+
export {
|
|
28
|
+
ContainerMessageType,
|
|
29
|
+
ContainerRuntimeMessage,
|
|
30
|
+
IContainerRuntimeMessageCompatDetails,
|
|
31
|
+
CompatModeBehavior,
|
|
32
|
+
RecentlyAddedContainerRuntimeMessageDetails,
|
|
33
|
+
} from "./messageTypes";
|
|
31
34
|
export { FluidDataStoreRegistry } from "./dataStoreRegistry";
|
|
32
35
|
export { IGCRuntimeOptions, IGCStats } from "./gc";
|
|
33
36
|
export {
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
7
|
+
import {
|
|
8
|
+
IEnvelope,
|
|
9
|
+
InboundAttachMessage,
|
|
10
|
+
IAttachMessage,
|
|
11
|
+
IdCreationRangeWithStashedState,
|
|
12
|
+
IdCreationRange,
|
|
13
|
+
} from "@fluidframework/runtime-definitions";
|
|
14
|
+
import { IDataStoreAliasMessage } from "./dataStore";
|
|
15
|
+
import { IChunkedOp } from "./opLifecycle";
|
|
16
|
+
|
|
17
|
+
export enum ContainerMessageType {
|
|
18
|
+
// An op to be delivered to store
|
|
19
|
+
FluidDataStoreOp = "component",
|
|
20
|
+
|
|
21
|
+
// Creates a new store
|
|
22
|
+
Attach = "attach",
|
|
23
|
+
|
|
24
|
+
// Chunked operation.
|
|
25
|
+
ChunkedOp = "chunkedOp",
|
|
26
|
+
|
|
27
|
+
// Signifies that a blob has been attached and should not be garbage collected by storage
|
|
28
|
+
BlobAttach = "blobAttach",
|
|
29
|
+
|
|
30
|
+
// Ties our new clientId to our old one on reconnect
|
|
31
|
+
Rejoin = "rejoin",
|
|
32
|
+
|
|
33
|
+
// Sets the alias of a root data store
|
|
34
|
+
Alias = "alias",
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* An op containing an IdRange of Ids allocated using the runtime's IdCompressor since
|
|
38
|
+
* the last allocation op was sent.
|
|
39
|
+
* See the [IdCompressor README](./id-compressor/README.md) for more details.
|
|
40
|
+
*/
|
|
41
|
+
IdAllocation = "idAllocation",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* How should an older client handle an unrecognized remote op type?
|
|
46
|
+
*
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
export type CompatModeBehavior =
|
|
50
|
+
/** Ignore the op. It won't be persisted if this client summarizes */
|
|
51
|
+
| "Ignore"
|
|
52
|
+
/** Fail processing immediately. (The container will close) */
|
|
53
|
+
| "FailToProcess";
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* All the info an older client would need to know how to handle an unrecognized remote op type
|
|
57
|
+
*
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
60
|
+
export interface IContainerRuntimeMessageCompatDetails {
|
|
61
|
+
/** How should an older client handle an unrecognized remote op type? */
|
|
62
|
+
behavior: CompatModeBehavior;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime.
|
|
67
|
+
* Message type are differentiated via a `type` string and contain different contents depending on their type.
|
|
68
|
+
*
|
|
69
|
+
* IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
|
|
70
|
+
* This way stringified values can be compared.
|
|
71
|
+
*/
|
|
72
|
+
interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> {
|
|
73
|
+
/** Type of the op, within the ContainerRuntime's domain */
|
|
74
|
+
type: TType;
|
|
75
|
+
/** Domain-specific contents, interpreted according to the type */
|
|
76
|
+
contents: TContents;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Additional details expected for any recently added message.
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
export interface RecentlyAddedContainerRuntimeMessageDetails {
|
|
84
|
+
/** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */
|
|
85
|
+
compatDetails: IContainerRuntimeMessageCompatDetails;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export type ContainerRuntimeDataStoreOpMessage = TypedContainerRuntimeMessage<
|
|
89
|
+
ContainerMessageType.FluidDataStoreOp,
|
|
90
|
+
IEnvelope
|
|
91
|
+
>;
|
|
92
|
+
export type InboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<
|
|
93
|
+
ContainerMessageType.Attach,
|
|
94
|
+
InboundAttachMessage
|
|
95
|
+
>;
|
|
96
|
+
export type OutboundContainerRuntimeAttachMessage = TypedContainerRuntimeMessage<
|
|
97
|
+
ContainerMessageType.Attach,
|
|
98
|
+
IAttachMessage
|
|
99
|
+
>;
|
|
100
|
+
export type ContainerRuntimeChunkedOpMessage = TypedContainerRuntimeMessage<
|
|
101
|
+
ContainerMessageType.ChunkedOp,
|
|
102
|
+
IChunkedOp
|
|
103
|
+
>;
|
|
104
|
+
export type ContainerRuntimeBlobAttachMessage = TypedContainerRuntimeMessage<
|
|
105
|
+
ContainerMessageType.BlobAttach,
|
|
106
|
+
undefined
|
|
107
|
+
>;
|
|
108
|
+
export type ContainerRuntimeRejoinMessage = TypedContainerRuntimeMessage<
|
|
109
|
+
ContainerMessageType.Rejoin,
|
|
110
|
+
undefined
|
|
111
|
+
>;
|
|
112
|
+
export type ContainerRuntimeAliasMessage = TypedContainerRuntimeMessage<
|
|
113
|
+
ContainerMessageType.Alias,
|
|
114
|
+
IDataStoreAliasMessage
|
|
115
|
+
>;
|
|
116
|
+
export type LocalContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
|
|
117
|
+
ContainerMessageType.IdAllocation,
|
|
118
|
+
IdCreationRangeWithStashedState
|
|
119
|
+
>;
|
|
120
|
+
export type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
|
|
121
|
+
ContainerMessageType.IdAllocation,
|
|
122
|
+
IdCreationRange & { stashedState?: never }
|
|
123
|
+
>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Represents an unrecognized {@link TypedContainerRuntimeMessage}, e.g. a message from a future version of the container runtime.
|
|
127
|
+
* @internal
|
|
128
|
+
*/
|
|
129
|
+
export interface UnknownContainerRuntimeMessage
|
|
130
|
+
extends Partial<RecentlyAddedContainerRuntimeMessageDetails> {
|
|
131
|
+
/** Invalid type of the op, within the ContainerRuntime's domain. This value should never exist at runtime.
|
|
132
|
+
* This is useful for type narrowing but should never be used as an actual message type at runtime.
|
|
133
|
+
* Actual value will not be "__unknown...", but the type `Exclude<string, ContainerMessageType>` is not supported.
|
|
134
|
+
*/
|
|
135
|
+
type: "__unknown_container_message_type__never_use_as_value__";
|
|
136
|
+
|
|
137
|
+
/** Domain-specific contents, but not decipherable by an unknown op. */
|
|
138
|
+
contents: unknown;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A {@link TypedContainerRuntimeMessage} that is received from the server and will be processed by the container runtime.
|
|
143
|
+
*/
|
|
144
|
+
export type InboundContainerRuntimeMessage =
|
|
145
|
+
| ContainerRuntimeDataStoreOpMessage
|
|
146
|
+
| InboundContainerRuntimeAttachMessage
|
|
147
|
+
| ContainerRuntimeChunkedOpMessage
|
|
148
|
+
| ContainerRuntimeBlobAttachMessage
|
|
149
|
+
| ContainerRuntimeRejoinMessage
|
|
150
|
+
| ContainerRuntimeAliasMessage
|
|
151
|
+
| ContainerRuntimeIdAllocationMessage
|
|
152
|
+
// Inbound messages may include unknown types from other clients, so we include that as a special case here
|
|
153
|
+
| UnknownContainerRuntimeMessage;
|
|
154
|
+
|
|
155
|
+
/** A {@link TypedContainerRuntimeMessage} that has been generated by the container runtime but is not yet being sent to the server. */
|
|
156
|
+
export type LocalContainerRuntimeMessage =
|
|
157
|
+
| ContainerRuntimeDataStoreOpMessage
|
|
158
|
+
| OutboundContainerRuntimeAttachMessage
|
|
159
|
+
| ContainerRuntimeChunkedOpMessage
|
|
160
|
+
| ContainerRuntimeBlobAttachMessage
|
|
161
|
+
| ContainerRuntimeRejoinMessage
|
|
162
|
+
| ContainerRuntimeAliasMessage
|
|
163
|
+
| LocalContainerRuntimeIdAllocationMessage
|
|
164
|
+
// In rare cases (e.g. related to stashed ops) we could have a local message of an unknown type
|
|
165
|
+
| UnknownContainerRuntimeMessage;
|
|
166
|
+
|
|
167
|
+
/** A {@link TypedContainerRuntimeMessage} that is being sent to the server from the container runtime. */
|
|
168
|
+
export type OutboundContainerRuntimeMessage =
|
|
169
|
+
| ContainerRuntimeDataStoreOpMessage
|
|
170
|
+
| OutboundContainerRuntimeAttachMessage
|
|
171
|
+
| ContainerRuntimeChunkedOpMessage
|
|
172
|
+
| ContainerRuntimeBlobAttachMessage
|
|
173
|
+
| ContainerRuntimeRejoinMessage
|
|
174
|
+
| ContainerRuntimeAliasMessage
|
|
175
|
+
| ContainerRuntimeIdAllocationMessage;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* An unpacked ISequencedDocumentMessage with the inner TypedContainerRuntimeMessage type/contents/etc
|
|
179
|
+
* promoted up to the outer object
|
|
180
|
+
*/
|
|
181
|
+
export type InboundSequencedContainerRuntimeMessage = Omit<
|
|
182
|
+
ISequencedDocumentMessage,
|
|
183
|
+
"type" | "contents"
|
|
184
|
+
> &
|
|
185
|
+
InboundContainerRuntimeMessage;
|
|
186
|
+
|
|
187
|
+
/** Essentially ISequencedDocumentMessage except that `type` is not `string` to enable narrowing
|
|
188
|
+
* as `Exclude<string, InboundContainerRuntimeMessage['type']>` is not supported.
|
|
189
|
+
* There should never be a runtime value of "__not_a_...".
|
|
190
|
+
* Currently additionally replaces `contents` type until protocol-definitions update is taken with `unknown` instead of `any`.
|
|
191
|
+
*/
|
|
192
|
+
type InboundSequencedNonContainerRuntimeMessage = Omit<
|
|
193
|
+
ISequencedDocumentMessage,
|
|
194
|
+
"type" | "contents"
|
|
195
|
+
> & { type: "__not_a_container_runtime_message_type__"; contents: unknown };
|
|
196
|
+
|
|
197
|
+
export type InboundSequencedContainerRuntimeMessageOrSystemMessage =
|
|
198
|
+
| InboundSequencedContainerRuntimeMessage
|
|
199
|
+
| InboundSequencedNonContainerRuntimeMessage;
|
|
200
|
+
|
|
201
|
+
/** A [loose] InboundSequencedContainerRuntimeMessage that is recent and may contain compat details.
|
|
202
|
+
* It exists solely to to provide access to those details.
|
|
203
|
+
*/
|
|
204
|
+
export type InboundSequencedRecentlyAddedContainerRuntimeMessage = ISequencedDocumentMessage &
|
|
205
|
+
Partial<RecentlyAddedContainerRuntimeMessageDetails>;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime
|
|
209
|
+
*
|
|
210
|
+
* IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
|
|
211
|
+
* This way stringified values can be compared.
|
|
212
|
+
*
|
|
213
|
+
* @deprecated - this is an internal type which should not be used outside of the package.
|
|
214
|
+
* Internally, it is superseded by `TypedContainerRuntimeMessage`.
|
|
215
|
+
*
|
|
216
|
+
* @internal
|
|
217
|
+
*/
|
|
218
|
+
export interface ContainerRuntimeMessage {
|
|
219
|
+
/** Type of the op, within the ContainerRuntime's domain */
|
|
220
|
+
type: ContainerMessageType;
|
|
221
|
+
/** Domain-specific contents, interpreted according to the type */
|
|
222
|
+
contents: any;
|
|
223
|
+
/** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */
|
|
224
|
+
compatDetails?: IContainerRuntimeMessageCompatDetails;
|
|
225
|
+
}
|