@fluidframework/container-runtime 2.0.0-dev-rc.1.0.0.225277 → 2.0.0-dev-rc.1.0.0.232845
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 +34 -0
- package/README.md +0 -6
- package/api-report/container-runtime.api.md +14 -3
- package/dist/{batchTracker.cjs → batchTracker.js} +1 -1
- package/dist/batchTracker.js.map +1 -0
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/{blobManager.cjs → blobManager.js} +9 -3
- package/dist/blobManager.js.map +1 -0
- package/dist/{connectionTelemetry.cjs → connectionTelemetry.js} +1 -1
- package/dist/connectionTelemetry.js.map +1 -0
- package/dist/container-runtime-alpha.d.ts +13 -3
- package/dist/container-runtime-beta.d.ts +7 -0
- package/dist/container-runtime-public.d.ts +7 -0
- package/dist/container-runtime-untrimmed.d.ts +30 -3
- package/dist/{containerHandleContext.cjs → containerHandleContext.js} +1 -1
- package/dist/containerHandleContext.js.map +1 -0
- package/dist/containerRuntime.d.ts +5 -2
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/{containerRuntime.cjs → containerRuntime.js} +78 -85
- package/dist/containerRuntime.js.map +1 -0
- package/dist/{dataStore.cjs → dataStore.js} +1 -1
- package/dist/dataStore.js.map +1 -0
- package/dist/dataStoreContext.d.ts +7 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/{dataStoreContext.cjs → dataStoreContext.js} +13 -7
- package/dist/dataStoreContext.js.map +1 -0
- package/dist/{dataStoreContexts.cjs → dataStoreContexts.js} +1 -1
- package/dist/dataStoreContexts.js.map +1 -0
- package/dist/{dataStoreRegistry.cjs → dataStoreRegistry.js} +1 -1
- package/dist/dataStoreRegistry.js.map +1 -0
- package/dist/dataStores.d.ts +9 -3
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/{dataStores.cjs → dataStores.js} +62 -16
- package/dist/dataStores.js.map +1 -0
- package/dist/{deltaManagerProxyBase.cjs → deltaManagerProxyBase.js} +1 -1
- package/dist/deltaManagerProxyBase.js.map +1 -0
- package/dist/{deltaManagerSummarizerProxy.cjs → deltaManagerSummarizerProxy.js} +3 -3
- package/dist/deltaManagerSummarizerProxy.js.map +1 -0
- package/dist/{deltaScheduler.cjs → deltaScheduler.js} +1 -1
- package/dist/deltaScheduler.js.map +1 -0
- package/dist/{error.cjs → error.js} +1 -1
- package/dist/error.js.map +1 -0
- package/dist/gc/garbageCollection.d.ts +17 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/{garbageCollection.cjs → garbageCollection.js} +111 -42
- package/dist/gc/garbageCollection.js.map +1 -0
- package/dist/gc/{gcConfigs.cjs → gcConfigs.js} +3 -3
- package/dist/gc/gcConfigs.js.map +1 -0
- package/dist/gc/gcDefinitions.d.ts +20 -2
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/{gcDefinitions.cjs → gcDefinitions.js} +8 -2
- package/dist/gc/gcDefinitions.js.map +1 -0
- package/dist/gc/{gcHelpers.cjs → gcHelpers.js} +1 -1
- package/dist/gc/gcHelpers.js.map +1 -0
- package/dist/gc/{gcReferenceGraphAlgorithm.cjs → gcReferenceGraphAlgorithm.js} +1 -1
- package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -0
- package/dist/gc/{gcSummaryDefinitions.cjs → gcSummaryDefinitions.js} +1 -1
- package/dist/gc/gcSummaryDefinitions.js.map +1 -0
- package/dist/gc/{gcSummaryStateTracker.cjs → gcSummaryStateTracker.js} +2 -2
- package/dist/gc/gcSummaryStateTracker.js.map +1 -0
- package/dist/gc/gcTelemetry.d.ts +1 -0
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/{gcTelemetry.cjs → gcTelemetry.js} +2 -4
- package/dist/gc/gcTelemetry.js.map +1 -0
- package/dist/gc/gcUnreferencedStateTracker.d.ts +5 -0
- package/dist/gc/gcUnreferencedStateTracker.d.ts.map +1 -1
- package/dist/gc/{gcUnreferencedStateTracker.cjs → gcUnreferencedStateTracker.js} +14 -3
- package/dist/gc/{gcUnreferencedStateTracker.cjs.map → gcUnreferencedStateTracker.js.map} +1 -1
- package/dist/gc/index.d.ts +1 -1
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/{index.cjs → index.js} +11 -9
- package/dist/gc/index.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/{index.cjs → index.js} +10 -8
- package/dist/index.js.map +1 -0
- package/dist/messageTypes.d.ts +1 -1
- package/dist/{messageTypes.cjs → messageTypes.js} +1 -1
- package/dist/messageTypes.js.map +1 -0
- package/dist/{metadata.cjs → metadata.js} +1 -1
- package/dist/metadata.js.map +1 -0
- package/dist/opLifecycle/{batchManager.cjs → batchManager.js} +1 -1
- package/dist/opLifecycle/batchManager.js.map +1 -0
- package/dist/opLifecycle/{definitions.cjs → definitions.js} +1 -1
- package/dist/opLifecycle/definitions.js.map +1 -0
- package/dist/opLifecycle/{index.cjs → index.js} +8 -8
- package/dist/opLifecycle/index.js.map +1 -0
- package/dist/opLifecycle/{opCompressor.cjs → opCompressor.js} +3 -3
- package/dist/opLifecycle/opCompressor.js.map +1 -0
- package/dist/opLifecycle/{opDecompressor.cjs → opDecompressor.js} +2 -2
- package/dist/opLifecycle/opDecompressor.js.map +1 -0
- package/dist/opLifecycle/{opGroupingManager.cjs → opGroupingManager.js} +1 -1
- package/dist/opLifecycle/opGroupingManager.js.map +1 -0
- package/dist/opLifecycle/{opSplitter.cjs → opSplitter.js} +3 -3
- package/dist/opLifecycle/opSplitter.js.map +1 -0
- package/dist/opLifecycle/{outbox.cjs → outbox.js} +2 -2
- package/dist/opLifecycle/outbox.js.map +1 -0
- package/dist/opLifecycle/{remoteMessageProcessor.cjs → remoteMessageProcessor.js} +2 -2
- package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -0
- package/dist/{opProperties.cjs → opProperties.js} +1 -1
- package/dist/opProperties.js.map +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/{packageVersion.cjs → packageVersion.js} +2 -2
- package/dist/packageVersion.js.map +1 -0
- package/dist/{pendingStateManager.cjs → pendingStateManager.js} +2 -2
- package/dist/pendingStateManager.js.map +1 -0
- package/dist/{scheduleManager.cjs → scheduleManager.js} +3 -3
- package/dist/scheduleManager.js.map +1 -0
- package/dist/{storageServiceWithAttachBlobs.cjs → storageServiceWithAttachBlobs.js} +1 -1
- package/dist/storageServiceWithAttachBlobs.js.map +1 -0
- package/dist/summary/{index.cjs → index.js} +12 -12
- package/dist/summary/index.js.map +1 -0
- package/dist/summary/{orderedClientElection.cjs → orderedClientElection.js} +2 -2
- package/dist/summary/orderedClientElection.js.map +1 -0
- package/dist/summary/{runWhileConnectedCoordinator.cjs → runWhileConnectedCoordinator.js} +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -0
- package/dist/summary/runningSummarizer.d.ts +11 -6
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/{runningSummarizer.cjs → runningSummarizer.js} +140 -93
- package/dist/summary/runningSummarizer.js.map +1 -0
- package/dist/summary/{summarizer.cjs → summarizer.js} +4 -4
- package/dist/summary/summarizer.js.map +1 -0
- package/dist/summary/{summarizerClientElection.cjs → summarizerClientElection.js} +1 -1
- package/dist/summary/summarizerClientElection.js.map +1 -0
- package/dist/summary/{summarizerHeuristics.cjs → summarizerHeuristics.js} +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -0
- package/dist/summary/summarizerNode/{index.cjs → index.js} +3 -3
- package/dist/summary/summarizerNode/index.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNode.d.ts +2 -3
- package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
- package/dist/summary/summarizerNode/{summarizerNode.cjs → summarizerNode.js} +8 -50
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -18
- package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
- package/dist/summary/summarizerNode/{summarizerNodeUtils.cjs → summarizerNodeUtils.js} +2 -22
- package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -0
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +3 -3
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/{summarizerNodeWithGc.cjs → summarizerNodeWithGc.js} +9 -9
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -0
- package/dist/summary/summarizerTypes.d.ts +3 -1
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/{summarizerTypes.cjs → summarizerTypes.js} +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -0
- package/dist/summary/{summaryCollection.cjs → summaryCollection.js} +1 -1
- package/dist/summary/summaryCollection.js.map +1 -0
- package/dist/summary/{summaryFormat.cjs → summaryFormat.js} +1 -1
- package/dist/summary/summaryFormat.js.map +1 -0
- package/dist/summary/{summaryGenerator.cjs → summaryGenerator.js} +1 -1
- package/dist/summary/summaryGenerator.js.map +1 -0
- package/dist/summary/{summaryManager.cjs → summaryManager.js} +2 -2
- package/dist/summary/summaryManager.js.map +1 -0
- package/dist/{throttler.cjs → throttler.js} +1 -1
- package/dist/throttler.js.map +1 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/blobManager.d.mts.map +1 -1
- package/lib/blobManager.mjs +7 -1
- package/lib/blobManager.mjs.map +1 -1
- package/lib/container-runtime-alpha.d.mts +13 -3
- package/lib/container-runtime-beta.d.mts +7 -0
- package/lib/container-runtime-public.d.mts +7 -0
- package/lib/container-runtime-untrimmed.d.mts +30 -3
- package/lib/containerRuntime.d.mts +5 -2
- package/lib/containerRuntime.d.mts.map +1 -1
- package/lib/containerRuntime.mjs +62 -69
- package/lib/containerRuntime.mjs.map +1 -1
- package/lib/dataStoreContext.d.mts +7 -1
- package/lib/dataStoreContext.d.mts.map +1 -1
- package/lib/dataStoreContext.mjs +11 -5
- package/lib/dataStoreContext.mjs.map +1 -1
- package/lib/dataStores.d.mts +9 -3
- package/lib/dataStores.d.mts.map +1 -1
- package/lib/dataStores.mjs +54 -9
- package/lib/dataStores.mjs.map +1 -1
- package/lib/gc/garbageCollection.d.mts +17 -1
- package/lib/gc/garbageCollection.d.mts.map +1 -1
- package/lib/gc/garbageCollection.mjs +103 -34
- package/lib/gc/garbageCollection.mjs.map +1 -1
- package/lib/gc/gcDefinitions.d.mts +20 -2
- package/lib/gc/gcDefinitions.d.mts.map +1 -1
- package/lib/gc/gcDefinitions.mjs +6 -0
- package/lib/gc/gcDefinitions.mjs.map +1 -1
- package/lib/gc/gcTelemetry.d.mts +1 -0
- package/lib/gc/gcTelemetry.d.mts.map +1 -1
- package/lib/gc/gcTelemetry.mjs +0 -2
- package/lib/gc/gcTelemetry.mjs.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.d.mts +5 -0
- package/lib/gc/gcUnreferencedStateTracker.d.mts.map +1 -1
- package/lib/gc/gcUnreferencedStateTracker.mjs +10 -0
- package/lib/gc/gcUnreferencedStateTracker.mjs.map +1 -1
- package/lib/gc/index.d.mts +1 -1
- package/lib/gc/index.d.mts.map +1 -1
- package/lib/gc/index.mjs +1 -1
- package/lib/gc/index.mjs.map +1 -1
- package/lib/index.d.mts +2 -1
- package/lib/index.d.mts.map +1 -1
- package/lib/index.mjs +1 -0
- package/lib/index.mjs.map +1 -1
- package/lib/messageTypes.d.mts +1 -1
- package/lib/messageTypes.mjs.map +1 -1
- package/lib/packageVersion.d.mts +1 -1
- package/lib/packageVersion.mjs +1 -1
- package/lib/packageVersion.mjs.map +1 -1
- package/lib/summary/runningSummarizer.d.mts +11 -6
- package/lib/summary/runningSummarizer.d.mts.map +1 -1
- package/lib/summary/runningSummarizer.mjs +136 -89
- package/lib/summary/runningSummarizer.mjs.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.d.mts +2 -3
- package/lib/summary/summarizerNode/summarizerNode.d.mts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.mjs +8 -50
- package/lib/summary/summarizerNode/summarizerNode.mjs.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts +1 -18
- package/lib/summary/summarizerNode/summarizerNodeUtils.d.mts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeUtils.mjs +0 -19
- package/lib/summary/summarizerNode/summarizerNodeUtils.mjs.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts +3 -3
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.mts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs +5 -5
- package/lib/summary/summarizerNode/summarizerNodeWithGc.mjs.map +1 -1
- package/lib/summary/summarizerTypes.d.mts +3 -1
- package/lib/summary/summarizerTypes.d.mts.map +1 -1
- package/lib/summary/summarizerTypes.mjs.map +1 -1
- package/package.json +48 -38
- package/src/blobManager.ts +7 -1
- package/src/containerRuntime.ts +103 -85
- package/src/dataStoreContext.ts +15 -6
- package/src/dataStores.ts +64 -6
- package/src/gc/garbageCollection.ts +118 -32
- package/src/gc/gcDefinitions.ts +21 -3
- package/src/gc/gcTelemetry.ts +1 -2
- package/src/gc/gcUnreferencedStateTracker.ts +11 -0
- package/src/gc/index.ts +3 -0
- package/src/index.ts +2 -0
- package/src/messageTypes.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/summary/runningSummarizer.ts +174 -113
- package/src/summary/summarizerNode/summarizerNode.ts +4 -64
- package/src/summary/summarizerNode/summarizerNodeUtils.ts +2 -33
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +0 -6
- package/src/summary/summarizerTypes.ts +3 -1
- package/dist/batchTracker.cjs.map +0 -1
- package/dist/blobManager.cjs.map +0 -1
- package/dist/connectionTelemetry.cjs.map +0 -1
- package/dist/containerHandleContext.cjs.map +0 -1
- package/dist/containerRuntime.cjs.map +0 -1
- package/dist/dataStore.cjs.map +0 -1
- package/dist/dataStoreContext.cjs.map +0 -1
- package/dist/dataStoreContexts.cjs.map +0 -1
- package/dist/dataStoreRegistry.cjs.map +0 -1
- package/dist/dataStores.cjs.map +0 -1
- package/dist/deltaManagerProxyBase.cjs.map +0 -1
- package/dist/deltaManagerSummarizerProxy.cjs.map +0 -1
- package/dist/deltaScheduler.cjs.map +0 -1
- package/dist/error.cjs.map +0 -1
- package/dist/gc/garbageCollection.cjs.map +0 -1
- package/dist/gc/gcConfigs.cjs.map +0 -1
- package/dist/gc/gcDefinitions.cjs.map +0 -1
- package/dist/gc/gcHelpers.cjs.map +0 -1
- package/dist/gc/gcReferenceGraphAlgorithm.cjs.map +0 -1
- package/dist/gc/gcSummaryDefinitions.cjs.map +0 -1
- package/dist/gc/gcSummaryStateTracker.cjs.map +0 -1
- package/dist/gc/gcTelemetry.cjs.map +0 -1
- package/dist/gc/index.cjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/messageTypes.cjs.map +0 -1
- package/dist/metadata.cjs.map +0 -1
- package/dist/opLifecycle/batchManager.cjs.map +0 -1
- package/dist/opLifecycle/definitions.cjs.map +0 -1
- package/dist/opLifecycle/index.cjs.map +0 -1
- package/dist/opLifecycle/opCompressor.cjs.map +0 -1
- package/dist/opLifecycle/opDecompressor.cjs.map +0 -1
- package/dist/opLifecycle/opGroupingManager.cjs.map +0 -1
- package/dist/opLifecycle/opSplitter.cjs.map +0 -1
- package/dist/opLifecycle/outbox.cjs.map +0 -1
- package/dist/opLifecycle/remoteMessageProcessor.cjs.map +0 -1
- package/dist/opProperties.cjs.map +0 -1
- package/dist/packageVersion.cjs.map +0 -1
- package/dist/pendingStateManager.cjs.map +0 -1
- package/dist/scheduleManager.cjs.map +0 -1
- package/dist/storageServiceWithAttachBlobs.cjs.map +0 -1
- package/dist/summary/index.cjs.map +0 -1
- package/dist/summary/orderedClientElection.cjs.map +0 -1
- package/dist/summary/runWhileConnectedCoordinator.cjs.map +0 -1
- package/dist/summary/runningSummarizer.cjs.map +0 -1
- package/dist/summary/summarizer.cjs.map +0 -1
- package/dist/summary/summarizerClientElection.cjs.map +0 -1
- package/dist/summary/summarizerHeuristics.cjs.map +0 -1
- package/dist/summary/summarizerNode/index.cjs.map +0 -1
- package/dist/summary/summarizerNode/summarizerNode.cjs.map +0 -1
- package/dist/summary/summarizerNode/summarizerNodeUtils.cjs.map +0 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.cjs.map +0 -1
- package/dist/summary/summarizerTypes.cjs.map +0 -1
- package/dist/summary/summaryCollection.cjs.map +0 -1
- package/dist/summary/summaryFormat.cjs.map +0 -1
- package/dist/summary/summaryGenerator.cjs.map +0 -1
- package/dist/summary/summaryManager.cjs.map +0 -1
- package/dist/throttler.cjs.map +0 -1
- package/tsc-multi.test.json +0 -4
- /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
|
@@ -20,7 +20,9 @@ import {
|
|
|
20
20
|
ITelemetryLoggerExt,
|
|
21
21
|
MonitoringContext,
|
|
22
22
|
PerformanceEvent,
|
|
23
|
+
tagCodeArtifacts,
|
|
23
24
|
} from "@fluidframework/telemetry-utils";
|
|
25
|
+
import { BlobManager } from "../blobManager";
|
|
24
26
|
import {
|
|
25
27
|
InactiveResponseHeaderKey,
|
|
26
28
|
RuntimeHeaderData,
|
|
@@ -44,6 +46,7 @@ import {
|
|
|
44
46
|
ISweepPhaseStats,
|
|
45
47
|
GarbageCollectionMessage,
|
|
46
48
|
GarbageCollectionMessageType,
|
|
49
|
+
disableAutoRecoveryKey,
|
|
47
50
|
} from "./gcDefinitions";
|
|
48
51
|
import {
|
|
49
52
|
cloneGCData,
|
|
@@ -54,7 +57,10 @@ import {
|
|
|
54
57
|
import { runGarbageCollection } from "./gcReferenceGraphAlgorithm";
|
|
55
58
|
import { IGarbageCollectionSnapshotData, IGarbageCollectionState } from "./gcSummaryDefinitions";
|
|
56
59
|
import { GCSummaryStateTracker } from "./gcSummaryStateTracker";
|
|
57
|
-
import {
|
|
60
|
+
import {
|
|
61
|
+
UnreferencedStateTracker,
|
|
62
|
+
UnreferencedStateTrackerMap,
|
|
63
|
+
} from "./gcUnreferencedStateTracker";
|
|
58
64
|
import { GCTelemetryTracker } from "./gcTelemetry";
|
|
59
65
|
|
|
60
66
|
/**
|
|
@@ -108,8 +114,15 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
108
114
|
private readonly initializeGCStateFromBaseSnapshotP: Promise<void>;
|
|
109
115
|
// The GC details generated from the base snapshot.
|
|
110
116
|
private readonly baseGCDetailsP: Promise<IGarbageCollectionDetailsBase>;
|
|
111
|
-
|
|
112
|
-
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Map of node ids to their unreferenced state tracker
|
|
120
|
+
* NOTE: The set of keys in this map is considered as the set of unreferenced nodes
|
|
121
|
+
* as of the last GC run. So in between runs, nothing should be added or removed.
|
|
122
|
+
*/
|
|
123
|
+
private readonly unreferencedNodesState: UnreferencedStateTrackerMap =
|
|
124
|
+
new UnreferencedStateTrackerMap();
|
|
125
|
+
|
|
113
126
|
// The Timer responsible for closing the container when the session has expired
|
|
114
127
|
private sessionExpiryTimer: Timer | undefined;
|
|
115
128
|
|
|
@@ -261,7 +274,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
261
274
|
const currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();
|
|
262
275
|
assert(
|
|
263
276
|
currentReferenceTimestampMs !== undefined,
|
|
264
|
-
|
|
277
|
+
0x8a4 /* Trying to initialize GC state without current timestamp */,
|
|
265
278
|
);
|
|
266
279
|
|
|
267
280
|
/**
|
|
@@ -590,16 +603,10 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
590
603
|
): { tombstoneReadyNodeIds: Set<string>; sweepReadyNodeIds: Set<string> } {
|
|
591
604
|
// 1. Marks all referenced nodes by clearing their unreferenced tracker, if any.
|
|
592
605
|
for (const nodeId of allReferencedNodeIds) {
|
|
593
|
-
|
|
594
|
-
if (nodeStateTracker !== undefined) {
|
|
595
|
-
// Stop tracking so as to clear out any running timers.
|
|
596
|
-
nodeStateTracker.stopTracking();
|
|
597
|
-
// Delete the node as we don't need to track it any more.
|
|
598
|
-
this.unreferencedNodesState.delete(nodeId);
|
|
599
|
-
}
|
|
606
|
+
this.unreferencedNodesState.delete(nodeId);
|
|
600
607
|
}
|
|
601
608
|
|
|
602
|
-
// 2. Mark unreferenced nodes in this run by starting unreferenced tracking for them.
|
|
609
|
+
// 2. Mark unreferenced nodes in this run by starting or updating unreferenced tracking for them.
|
|
603
610
|
const tombstoneReadyNodeIds: Set<string> = new Set();
|
|
604
611
|
const sweepReadyNodeIds: Set<string> = new Set();
|
|
605
612
|
for (const nodeId of gcResult.deletedNodeIds) {
|
|
@@ -854,21 +861,33 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
854
861
|
* @param local - Whether it was send by this client.
|
|
855
862
|
*/
|
|
856
863
|
public processMessage(message: ContainerRuntimeGCMessage, local: boolean) {
|
|
857
|
-
|
|
858
|
-
|
|
864
|
+
const gcMessageType = message.contents.type;
|
|
865
|
+
switch (gcMessageType) {
|
|
866
|
+
case GarbageCollectionMessageType.Sweep: {
|
|
859
867
|
// Delete the nodes whose ids are present in the contents.
|
|
860
868
|
this.deleteSweepReadyNodes(message.contents.deletedNodeIds);
|
|
861
869
|
break;
|
|
862
870
|
}
|
|
871
|
+
case GarbageCollectionMessageType.TombstoneLoaded: {
|
|
872
|
+
if (this.mc.config.getBoolean(disableAutoRecoveryKey) === true) {
|
|
873
|
+
break;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
// Mark the node as referenced to ensure it isn't Swept
|
|
877
|
+
const tombstonedNodePath = message.contents.nodePath;
|
|
878
|
+
this.addedOutboundReference("/", tombstonedNodePath);
|
|
879
|
+
|
|
880
|
+
break;
|
|
881
|
+
}
|
|
863
882
|
default: {
|
|
864
883
|
if (
|
|
865
884
|
!compatBehaviorAllowsGCMessageType(
|
|
866
|
-
|
|
885
|
+
gcMessageType,
|
|
867
886
|
message.compatDetails?.behavior,
|
|
868
887
|
)
|
|
869
888
|
) {
|
|
870
889
|
const error = DataProcessingError.create(
|
|
871
|
-
`Garbage collection message of unknown type ${
|
|
890
|
+
`Garbage collection message of unknown type ${gcMessageType}`,
|
|
872
891
|
"processMessage",
|
|
873
892
|
);
|
|
874
893
|
throw error;
|
|
@@ -909,13 +928,9 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
909
928
|
|
|
910
929
|
// Clear unreferenced state tracking for deleted nodes.
|
|
911
930
|
for (const nodeId of deletedNodeIds) {
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
nodeStateTracker.stopTracking();
|
|
916
|
-
// Delete the node as we don't need to track it any more.
|
|
917
|
-
this.unreferencedNodesState.delete(nodeId);
|
|
918
|
-
}
|
|
931
|
+
// Usually we avoid modifying the set of unreferencedNodesState keys in between GC runs,
|
|
932
|
+
// but this is ok since this node won't exist at all in the next GC run.
|
|
933
|
+
this.unreferencedNodesState.delete(nodeId);
|
|
919
934
|
this.deletedNodes.add(nodeId);
|
|
920
935
|
}
|
|
921
936
|
}
|
|
@@ -957,6 +972,15 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
957
972
|
headers: headerData,
|
|
958
973
|
});
|
|
959
974
|
|
|
975
|
+
// Any time we log a Tombstone Loaded error (via Telemetry Tracker),
|
|
976
|
+
// we want to also trigger autorecovery to avoid the object being deleted
|
|
977
|
+
// Note: We don't need to trigger on "Changed" because any change will cause the object
|
|
978
|
+
// to be loaded by the Summarizer, and auto-recovery will be triggered then.
|
|
979
|
+
if (isTombstoned && reason === "Loaded") {
|
|
980
|
+
// Note that when a DataStore and its DDS are all loaded, each will trigger AutoRecovery for itself.
|
|
981
|
+
this.triggerAutoRecovery(nodePath);
|
|
982
|
+
}
|
|
983
|
+
|
|
960
984
|
const nodeType = this.runtime.getNodeType(nodePath);
|
|
961
985
|
|
|
962
986
|
// Unless this is a Loaded event for a Blob or DataStore, we're done after telemetry tracking
|
|
@@ -965,7 +989,6 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
965
989
|
}
|
|
966
990
|
|
|
967
991
|
const errorRequest: IRequest = request ?? { url: nodePath };
|
|
968
|
-
// If the object is tombstoned and tombstone enforcement is configured, throw an error.
|
|
969
992
|
if (isTombstoned && this.throwOnTombstoneLoad && headerData?.allowTombstone !== true) {
|
|
970
993
|
// The requested data store is removed by gc. Create a 404 gc response exception.
|
|
971
994
|
throw responseToException(
|
|
@@ -993,18 +1016,58 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
993
1016
|
}
|
|
994
1017
|
}
|
|
995
1018
|
|
|
1019
|
+
/**
|
|
1020
|
+
* The given node should have its unreferenced state reset in the next GC,
|
|
1021
|
+
* even if the true GC graph shows it is unreferenced. This will
|
|
1022
|
+
* prevent it from being deleted by Sweep (after the Grace Period).
|
|
1023
|
+
*
|
|
1024
|
+
* Submit a GC op indicating that the Tombstone with the given path has been loaded.
|
|
1025
|
+
* Broadcasting this information in the op stream allows the Summarizer to reset unreferenced state
|
|
1026
|
+
* before runnint GC next.
|
|
1027
|
+
*/
|
|
1028
|
+
private triggerAutoRecovery(nodePath: string) {
|
|
1029
|
+
if (this.mc.config.getBoolean(disableAutoRecoveryKey) === true) {
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// Use compat behavior "Ignore" since this is an optimization to opportunistically protect
|
|
1034
|
+
// objects from deletion, so it's fine for older clients to ignore this op.
|
|
1035
|
+
const containerGCMessage: ContainerRuntimeGCMessage = {
|
|
1036
|
+
type: ContainerMessageType.GC,
|
|
1037
|
+
contents: {
|
|
1038
|
+
type: "TombstoneLoaded",
|
|
1039
|
+
nodePath,
|
|
1040
|
+
},
|
|
1041
|
+
compatDetails: { behavior: "Ignore" },
|
|
1042
|
+
};
|
|
1043
|
+
this.submitMessage(containerGCMessage);
|
|
1044
|
+
}
|
|
1045
|
+
|
|
996
1046
|
/**
|
|
997
1047
|
* Called when an outbound reference is added to a node. This is used to identify all nodes that have been
|
|
998
1048
|
* referenced between summaries so that their unreferenced timestamp can be reset.
|
|
999
1049
|
*
|
|
1000
1050
|
* @param fromNodePath - The node from which the reference is added.
|
|
1001
1051
|
* @param toNodePath - The node to which the reference is added.
|
|
1052
|
+
* @param autorecovery - This reference is added artificially, for autorecovery. Used for logging.
|
|
1002
1053
|
*/
|
|
1003
|
-
public addedOutboundReference(fromNodePath: string, toNodePath: string) {
|
|
1054
|
+
public addedOutboundReference(fromNodePath: string, toNodePath: string, autorecovery?: true) {
|
|
1004
1055
|
if (!this.configs.shouldRunGC) {
|
|
1005
1056
|
return;
|
|
1006
1057
|
}
|
|
1007
1058
|
|
|
1059
|
+
if (!toNodePath.startsWith("/")) {
|
|
1060
|
+
// A long time ago we stored handles with relatives paths. We don't expect to see these cases though
|
|
1061
|
+
// because GC was enabled only after we made the switch to always using absolute paths.
|
|
1062
|
+
this.mc.logger.sendErrorEvent({
|
|
1063
|
+
eventName: "InvalidRelativeOutboundRoute",
|
|
1064
|
+
...tagCodeArtifacts({ fromId: fromNodePath, id: toNodePath }),
|
|
1065
|
+
});
|
|
1066
|
+
return;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
assert(fromNodePath.startsWith("/"), 0x8a5 /* fromNodePath must be an absolute path */);
|
|
1070
|
+
|
|
1008
1071
|
const outboundRoutes = this.newReferencesSinceLastRun.get(fromNodePath) ?? [];
|
|
1009
1072
|
outboundRoutes.push(toNodePath);
|
|
1010
1073
|
this.newReferencesSinceLastRun.set(fromNodePath, outboundRoutes);
|
|
@@ -1018,7 +1081,14 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1018
1081
|
isTombstoned: this.tombstones.includes(toNodePath),
|
|
1019
1082
|
lastSummaryTime: this.getLastSummaryTimestampMs(),
|
|
1020
1083
|
fromId: fromNodePath,
|
|
1084
|
+
autorecovery,
|
|
1021
1085
|
});
|
|
1086
|
+
|
|
1087
|
+
// This node is referenced - Clear its unreferenced state
|
|
1088
|
+
// But don't delete the node id from the map yet.
|
|
1089
|
+
// When generating GC stats, the set of nodes in here is used as the baseline for
|
|
1090
|
+
// what was unreferenced in the last GC run.
|
|
1091
|
+
this.unreferencedNodesState.get(toNodePath)?.stopTracking();
|
|
1022
1092
|
}
|
|
1023
1093
|
|
|
1024
1094
|
/**
|
|
@@ -1052,17 +1122,17 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1052
1122
|
updatedAttachmentBlobCount: 0,
|
|
1053
1123
|
};
|
|
1054
1124
|
|
|
1055
|
-
const updateNodeStats = (nodeId: string,
|
|
1125
|
+
const updateNodeStats = (nodeId: string, isReferenced: boolean) => {
|
|
1056
1126
|
markPhaseStats.nodeCount++;
|
|
1057
1127
|
// If there is no previous GC data, every node's state is generated and is considered as updated.
|
|
1058
1128
|
// Otherwise, find out if any node went from referenced to unreferenced or vice-versa.
|
|
1129
|
+
const wasNotReferenced = this.unreferencedNodesState.has(nodeId);
|
|
1059
1130
|
const stateUpdated =
|
|
1060
|
-
this.gcDataFromLastRun === undefined ||
|
|
1061
|
-
this.unreferencedNodesState.has(nodeId) === referenced;
|
|
1131
|
+
this.gcDataFromLastRun === undefined || wasNotReferenced === isReferenced;
|
|
1062
1132
|
if (stateUpdated) {
|
|
1063
1133
|
markPhaseStats.updatedNodeCount++;
|
|
1064
1134
|
}
|
|
1065
|
-
if (!
|
|
1135
|
+
if (!isReferenced) {
|
|
1066
1136
|
markPhaseStats.unrefNodeCount++;
|
|
1067
1137
|
}
|
|
1068
1138
|
|
|
@@ -1071,7 +1141,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1071
1141
|
if (stateUpdated) {
|
|
1072
1142
|
markPhaseStats.updatedDataStoreCount++;
|
|
1073
1143
|
}
|
|
1074
|
-
if (!
|
|
1144
|
+
if (!isReferenced) {
|
|
1075
1145
|
markPhaseStats.unrefDataStoreCount++;
|
|
1076
1146
|
}
|
|
1077
1147
|
}
|
|
@@ -1080,7 +1150,7 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1080
1150
|
if (stateUpdated) {
|
|
1081
1151
|
markPhaseStats.updatedAttachmentBlobCount++;
|
|
1082
1152
|
}
|
|
1083
|
-
if (!
|
|
1153
|
+
if (!isReferenced) {
|
|
1084
1154
|
markPhaseStats.unrefAttachmentBlobCount++;
|
|
1085
1155
|
}
|
|
1086
1156
|
}
|
|
@@ -1120,9 +1190,25 @@ export class GarbageCollector implements IGarbageCollector {
|
|
|
1120
1190
|
deletedAttachmentBlobCount: 0,
|
|
1121
1191
|
};
|
|
1122
1192
|
|
|
1193
|
+
// The runtime can't reliably identify the type of deleted nodes. So, get the type here. This should
|
|
1194
|
+
// be good enough because the only types that participate in GC today are data stores, DDSes and blobs.
|
|
1195
|
+
const getDeletedNodeType = (nodeId: string): GCNodeType => {
|
|
1196
|
+
const pathParts = nodeId.split("/");
|
|
1197
|
+
if (pathParts[1] === BlobManager.basePath) {
|
|
1198
|
+
return GCNodeType.Blob;
|
|
1199
|
+
}
|
|
1200
|
+
if (pathParts.length === 2) {
|
|
1201
|
+
return GCNodeType.DataStore;
|
|
1202
|
+
}
|
|
1203
|
+
if (pathParts.length === 3) {
|
|
1204
|
+
return GCNodeType.SubDataStore;
|
|
1205
|
+
}
|
|
1206
|
+
return GCNodeType.Other;
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1123
1209
|
for (const nodeId of deletedNodes) {
|
|
1124
1210
|
sweepPhaseStats.deletedNodeCount++;
|
|
1125
|
-
const nodeType =
|
|
1211
|
+
const nodeType = getDeletedNodeType(nodeId);
|
|
1126
1212
|
if (nodeType === GCNodeType.DataStore) {
|
|
1127
1213
|
sweepPhaseStats.deletedDataStoreCount++;
|
|
1128
1214
|
} else if (nodeType === GCNodeType.Blob) {
|
package/src/gc/gcDefinitions.ts
CHANGED
|
@@ -74,6 +74,10 @@ export const gcVersionUpgradeToV4Key = "Fluid.GarbageCollection.GCVersionUpgrade
|
|
|
74
74
|
export const disableDatastoreSweepKey = "Fluid.GarbageCollection.DisableDataStoreSweep";
|
|
75
75
|
/** Config key to disable GC sweep for attachment blobs. */
|
|
76
76
|
export const disableAttachmentBlobSweepKey = "Fluid.GarbageCollection.DisableAttachmentBlobSweep";
|
|
77
|
+
/** Config key to revert new paradigm of detecting outbound routes in ContainerRuntime layer (use true) */
|
|
78
|
+
export const detectOutboundRoutesViaDDSKey = "Fluid.GarbageCollection.DetectOutboundRoutesViaDDS";
|
|
79
|
+
/** Config key to disable auto-recovery mechanism that protects Tombstones that are loaded from being swept (use true) */
|
|
80
|
+
export const disableAutoRecoveryKey = "Fluid.GarbageCollection.DisableAutoRecovery";
|
|
77
81
|
|
|
78
82
|
// One day in milliseconds.
|
|
79
83
|
export const oneDayMs = 1 * 24 * 60 * 60 * 1000;
|
|
@@ -251,6 +255,8 @@ export type GCNodeType = (typeof GCNodeType)[keyof typeof GCNodeType];
|
|
|
251
255
|
export const GarbageCollectionMessageType = {
|
|
252
256
|
/** Message sent directing GC to delete the given nodes */
|
|
253
257
|
Sweep: "Sweep",
|
|
258
|
+
/** Message sent notifying GC that a Tombstoned object was Loaded */
|
|
259
|
+
TombstoneLoaded: "TombstoneLoaded",
|
|
254
260
|
} as const;
|
|
255
261
|
|
|
256
262
|
/**
|
|
@@ -264,16 +270,28 @@ export type GarbageCollectionMessageType =
|
|
|
264
270
|
* @internal
|
|
265
271
|
*/
|
|
266
272
|
export interface ISweepMessage {
|
|
267
|
-
|
|
268
|
-
|
|
273
|
+
/** @see GarbageCollectionMessageType.Sweep */
|
|
274
|
+
type: typeof GarbageCollectionMessageType.Sweep;
|
|
275
|
+
/** The ids of nodes that are deleted. */
|
|
269
276
|
deletedNodeIds: string[];
|
|
270
277
|
}
|
|
271
278
|
|
|
279
|
+
/**
|
|
280
|
+
* The GC TombstoneLoaded message.
|
|
281
|
+
* @internal
|
|
282
|
+
*/
|
|
283
|
+
export interface ITombstoneLoadedMessage {
|
|
284
|
+
/** @see GarbageCollectionMessageType.TombstoneLoaded */
|
|
285
|
+
type: typeof GarbageCollectionMessageType.TombstoneLoaded;
|
|
286
|
+
/** The id of Tombstoned node that was loaded. */
|
|
287
|
+
nodePath: string;
|
|
288
|
+
}
|
|
289
|
+
|
|
272
290
|
/**
|
|
273
291
|
* Type for a message to be used for sending / received garbage collection messages.
|
|
274
292
|
* @internal
|
|
275
293
|
*/
|
|
276
|
-
export type GarbageCollectionMessage = ISweepMessage;
|
|
294
|
+
export type GarbageCollectionMessage = ISweepMessage | ITombstoneLoadedMessage;
|
|
277
295
|
|
|
278
296
|
/**
|
|
279
297
|
* Defines the APIs for the runtime object to be passed to the garbage collector.
|
package/src/gc/gcTelemetry.ts
CHANGED
|
@@ -63,6 +63,7 @@ interface INodeUsageProps extends ICommonProps {
|
|
|
63
63
|
currentReferenceTimestampMs: number | undefined;
|
|
64
64
|
packagePath: readonly string[] | undefined;
|
|
65
65
|
fromId?: string;
|
|
66
|
+
autorecovery?: true;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
/**
|
|
@@ -189,8 +190,6 @@ export class GCTelemetryTracker {
|
|
|
189
190
|
};
|
|
190
191
|
|
|
191
192
|
// If the node that is used is tombstoned, log a tombstone telemetry.
|
|
192
|
-
// Note that this is done before checking if "nodeStateTracker" is undefined below because unreferenced
|
|
193
|
-
// tracking may not have yet been enabled. That happens only after the client transitions to write mode.
|
|
194
193
|
if (nodeUsageProps.isTombstoned) {
|
|
195
194
|
this.logTombstoneUsageTelemetry(nodeUsageProps, unrefEventProps, nodeType, usageType);
|
|
196
195
|
}
|
|
@@ -25,6 +25,17 @@ class TimerWithNoDefaultTimeout extends Timer {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
/** The collection of UnreferencedStateTrackers for all unreferenced nodes. Ensures stopTracking is called when deleting */
|
|
29
|
+
export class UnreferencedStateTrackerMap extends Map<string, UnreferencedStateTracker> {
|
|
30
|
+
/** Delete the given key, and stop tracking if that node was actually unreferenced */
|
|
31
|
+
delete(key: string): boolean {
|
|
32
|
+
// Stop tracking so as to clear out any running timers.
|
|
33
|
+
this.get(key)?.stopTracking();
|
|
34
|
+
// Delete the node as we don't need to track it any more.
|
|
35
|
+
return super.delete(key);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
/**
|
|
29
40
|
* Helper class that tracks the state of an unreferenced node such as the time it was unreferenced and if it can
|
|
30
41
|
* be tombstoned or deleted by the sweep phase.
|
package/src/gc/index.ts
CHANGED
|
@@ -33,10 +33,13 @@ export {
|
|
|
33
33
|
runSweepKey,
|
|
34
34
|
stableGCVersion,
|
|
35
35
|
disableAttachmentBlobSweepKey,
|
|
36
|
+
disableAutoRecoveryKey,
|
|
36
37
|
disableDatastoreSweepKey,
|
|
38
|
+
detectOutboundRoutesViaDDSKey,
|
|
37
39
|
UnreferencedState,
|
|
38
40
|
throwOnTombstoneLoadOverrideKey,
|
|
39
41
|
GarbageCollectionMessage,
|
|
42
|
+
ISweepMessage,
|
|
40
43
|
} from "./gcDefinitions";
|
|
41
44
|
export {
|
|
42
45
|
cloneGCData,
|
package/src/index.ts
CHANGED
|
@@ -30,9 +30,11 @@ export {
|
|
|
30
30
|
IContainerRuntimeMessageCompatDetails,
|
|
31
31
|
CompatModeBehavior,
|
|
32
32
|
RecentlyAddedContainerRuntimeMessageDetails,
|
|
33
|
+
UnknownContainerRuntimeMessage,
|
|
33
34
|
} from "./messageTypes";
|
|
34
35
|
export { IBlobManagerLoadInfo } from "./blobManager";
|
|
35
36
|
export { FluidDataStoreRegistry } from "./dataStoreRegistry";
|
|
37
|
+
export { detectOutboundReferences } from "./dataStores";
|
|
36
38
|
export {
|
|
37
39
|
GCNodeType,
|
|
38
40
|
IGCMetadata,
|
package/src/messageTypes.ts
CHANGED
|
@@ -133,7 +133,7 @@ export type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<
|
|
|
133
133
|
>;
|
|
134
134
|
|
|
135
135
|
/**
|
|
136
|
-
* Represents an unrecognized
|
|
136
|
+
* Represents an unrecognized TypedContainerRuntimeMessage, e.g. a message from a future version of the container runtime.
|
|
137
137
|
* @internal
|
|
138
138
|
*/
|
|
139
139
|
export interface UnknownContainerRuntimeMessage
|
package/src/packageVersion.ts
CHANGED