@fluidframework/container-runtime 2.0.0-internal.2.3.1 → 2.0.0-internal.2.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/dist/blobManager.d.ts +3 -1
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +35 -2
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +2 -2
- package/dist/containerRuntime.js.map +1 -1
- package/dist/garbageCollection.d.ts +15 -7
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +96 -36
- package/dist/garbageCollection.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/summarizer.js.map +1 -1
- package/lib/blobManager.d.ts +3 -1
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +35 -2
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +2 -2
- package/lib/containerRuntime.js.map +1 -1
- package/lib/garbageCollection.d.ts +15 -7
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +97 -37
- package/lib/garbageCollection.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/summarizer.js.map +1 -1
- package/package.json +37 -20
- package/src/blobManager.ts +41 -2
- package/src/containerRuntime.ts +2 -1
- package/src/garbageCollection.ts +103 -34
- package/src/packageVersion.ts +1 -1
- package/src/summarizer.ts +1 -1
|
@@ -85,6 +85,8 @@ export interface IGarbageCollector {
|
|
|
85
85
|
nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", timestampMs?: number, packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
|
|
86
86
|
/** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */
|
|
87
87
|
addedOutboundReference(fromNodePath: string, toNodePath: string): void;
|
|
88
|
+
/** Returns true if this node has been deleted by GC during sweep phase. */
|
|
89
|
+
isNodeDeleted(nodePath: string): boolean;
|
|
88
90
|
setConnectionState(connected: boolean, clientId?: string): void;
|
|
89
91
|
dispose(): void;
|
|
90
92
|
}
|
|
@@ -227,6 +229,7 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
227
229
|
private gcDataFromLastRun;
|
|
228
230
|
private readonly newReferencesSinceLastRun;
|
|
229
231
|
private tombstones;
|
|
232
|
+
private deletedNodes;
|
|
230
233
|
/**
|
|
231
234
|
* Keeps track of the GC data from the latest summary successfully submitted to and acked from the server.
|
|
232
235
|
*/
|
|
@@ -265,9 +268,8 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
265
268
|
private readonly sweepReadyUsageHandler;
|
|
266
269
|
protected constructor(createParams: IGarbageCollectorCreateParams);
|
|
267
270
|
/**
|
|
268
|
-
* Called during container initialization. Initialize the tombstone state
|
|
269
|
-
*
|
|
270
|
-
* in use or not.
|
|
271
|
+
* Called during container initialization. Initialize from the tombstone state in the base snapshot. This is done
|
|
272
|
+
* during initialization so that deleted or tombstoned objects are marked as such before they are loaded or used.
|
|
271
273
|
*/
|
|
272
274
|
initializeBaseState(): Promise<void>;
|
|
273
275
|
/**
|
|
@@ -307,11 +309,12 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
307
309
|
*/
|
|
308
310
|
summarize(fullTree: boolean, trackState: boolean, telemetryContext?: ITelemetryContext): ISummarizeResult | undefined;
|
|
309
311
|
/**
|
|
310
|
-
* Builds the GC summary tree which contains GC state and
|
|
311
|
-
* If trackState is false,
|
|
312
|
-
* If trackState is true,
|
|
312
|
+
* Builds the GC summary tree which contains GC state, deleted nodes and tombstones.
|
|
313
|
+
* If trackState is false, all of GC state, deleted nodes and tombstones are written as summary blobs.
|
|
314
|
+
* If trackState is true, only states that changed are written. Rest are written as handles.
|
|
313
315
|
* @param serializedGCState - The GC state serialized as string.
|
|
314
|
-
* @param serializedTombstones -
|
|
316
|
+
* @param serializedTombstones - The tombstone state serialized as string.
|
|
317
|
+
* @param serializedDeletedNodes - Deleted nodes serialized as string.
|
|
315
318
|
* @param trackState - Whether we are tracking GC state across summaries.
|
|
316
319
|
* @returns the GC summary tree.
|
|
317
320
|
*/
|
|
@@ -344,6 +347,11 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
344
347
|
* @param toNodePath - The node to which the reference is added.
|
|
345
348
|
*/
|
|
346
349
|
addedOutboundReference(fromNodePath: string, toNodePath: string): void;
|
|
350
|
+
/**
|
|
351
|
+
* Returns whether a node with the given path has been deleted or not. This can be used by the runtime to identify
|
|
352
|
+
* cases where objects are used after they are deleted and throw / log errors accordingly.
|
|
353
|
+
*/
|
|
354
|
+
isNodeDeleted(nodePath: string): boolean;
|
|
347
355
|
dispose(): void;
|
|
348
356
|
/**
|
|
349
357
|
* Updates the state of the system as per the current GC run. It does the following:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../src/garbageCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AASjE,OAAO,EAAE,aAAa,EAAe,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAIH,sBAAsB,EACtB,6BAA6B,EAG7B,gBAAgB,EAChB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../src/garbageCollection.ts"],"names":[],"mappings":"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"}
|
package/lib/garbageCollection.js
CHANGED
|
@@ -17,7 +17,7 @@ import { assert, LazyPromise, Timer } from "@fluidframework/common-utils";
|
|
|
17
17
|
import { ClientSessionExpiredError, DataProcessingError, UsageError } from "@fluidframework/container-utils";
|
|
18
18
|
import { cloneGCData, concatGarbageCollectionData, getGCDataFromSnapshot, runGarbageCollection, trimLeadingSlashes, } from "@fluidframework/garbage-collector";
|
|
19
19
|
import { SummaryType } from "@fluidframework/protocol-definitions";
|
|
20
|
-
import { gcTreeKey, gcBlobPrefix, gcTombstoneBlobKey, } from "@fluidframework/runtime-definitions";
|
|
20
|
+
import { gcTreeKey, gcBlobPrefix, gcTombstoneBlobKey, gcDeletedBlobKey, } from "@fluidframework/runtime-definitions";
|
|
21
21
|
import { mergeStats, packagePathToTelemetryProperty, SummaryTreeBuilder, } from "@fluidframework/runtime-utils";
|
|
22
22
|
import { ChildLogger, generateStack, loggerToMonitoringContext, PerformanceEvent, TelemetryDataTag, } from "@fluidframework/telemetry-utils";
|
|
23
23
|
import { RuntimeHeaders } from "./containerRuntime";
|
|
@@ -141,7 +141,10 @@ export class GarbageCollector {
|
|
|
141
141
|
// Keeps a list of references (edges in the GC graph) between GC runs. Each entry has a node id and a list of
|
|
142
142
|
// outbound routes from that node.
|
|
143
143
|
this.newReferencesSinceLastRun = new Map();
|
|
144
|
+
// A list of nodes that have been tombstoned.
|
|
144
145
|
this.tombstones = [];
|
|
146
|
+
// A list of nodes that have been deleted during sweep phase.
|
|
147
|
+
this.deletedNodes = new Set();
|
|
145
148
|
// Map of node ids to their unreferenced state tracker.
|
|
146
149
|
this.unreferencedNodesState = new Map();
|
|
147
150
|
// Keeps track of unreferenced events that are logged for a node. This is used to limit the log generation to one
|
|
@@ -210,8 +213,7 @@ export class GarbageCollector {
|
|
|
210
213
|
// flag in GC options to false.
|
|
211
214
|
this.gcEnabled = this.gcOptions.gcAllowed !== false;
|
|
212
215
|
// The sweep phase has to be explicitly enabled by setting the sweepAllowed flag in GC options to true.
|
|
213
|
-
|
|
214
|
-
this.sweepEnabled = this.gcOptions.sweepAllowed === true || testOverrideSweepTimeoutMs !== undefined;
|
|
216
|
+
this.sweepEnabled = this.gcOptions.sweepAllowed === true;
|
|
215
217
|
// Set the Session Expiry only if the flag is enabled and GC is enabled.
|
|
216
218
|
if (this.mc.config.getBoolean(runSessionExpiryKey) && this.gcEnabled) {
|
|
217
219
|
this.sessionExpiryTimeoutMs = (_c = this.gcOptions.sessionExpiryTimeoutMs) !== null && _c !== void 0 ? _c : defaultSessionExpiryDurationMs;
|
|
@@ -267,8 +269,9 @@ export class GarbageCollector {
|
|
|
267
269
|
}
|
|
268
270
|
// Whether we are running in test mode. In this mode, unreferenced nodes are immediately deleted.
|
|
269
271
|
this.testMode = (_h = this.mc.config.getBoolean(gcTestModeKey)) !== null && _h !== void 0 ? _h : this.gcOptions.runGCInTestMode === true;
|
|
270
|
-
// Whether we are running in tombstone mode. This is
|
|
271
|
-
|
|
272
|
+
// Whether we are running in tombstone mode. This is enabled by default if sweep won't run. It can be disabled
|
|
273
|
+
// via feature flags.
|
|
274
|
+
this.tombstoneMode = !this.shouldRunSweep && this.mc.config.getBoolean(disableTombstoneKey) !== true;
|
|
272
275
|
// If GC ran in the container that generated the base snapshot, it will have a GC tree.
|
|
273
276
|
this.wasGCRunInLatestSummary = (baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.trees[gcTreeKey]) !== undefined;
|
|
274
277
|
// Get the GC data from the base snapshot. Use LazyPromise because we only want to do this once since it
|
|
@@ -318,7 +321,9 @@ export class GarbageCollector {
|
|
|
318
321
|
}
|
|
319
322
|
// If there is only one node (root node just added above), either GC is disabled or we are loading from
|
|
320
323
|
// the first summary generated by detached container. In both cases, GC was not run - return undefined.
|
|
321
|
-
return Object.keys(gcState.gcNodes).length === 1
|
|
324
|
+
return Object.keys(gcState.gcNodes).length === 1
|
|
325
|
+
? undefined
|
|
326
|
+
: { gcState, tombstones: undefined, deletedNodes: undefined };
|
|
322
327
|
}
|
|
323
328
|
catch (error) {
|
|
324
329
|
const dpe = DataProcessingError.wrapIfUnrecognized(error, "FailedToInitializeGC");
|
|
@@ -431,24 +436,31 @@ export class GarbageCollector {
|
|
|
431
436
|
return Object.assign({ gcEnabled: this.gcEnabled, sweepEnabled: this.sweepEnabled, runGC: this.shouldRunGC, runSweep: this.shouldRunSweep, testMode: this.testMode, tombstoneMode: this.tombstoneMode, sessionExpiry: this.sessionExpiryTimeoutMs, sweepTimeout: this.sweepTimeoutMs, inactiveTimeout: this.inactiveTimeoutMs, trackGCState: this.trackGCState }, this.gcOptions);
|
|
432
437
|
}
|
|
433
438
|
/**
|
|
434
|
-
* Called during container initialization. Initialize the tombstone state
|
|
435
|
-
*
|
|
436
|
-
* in use or not.
|
|
439
|
+
* Called during container initialization. Initialize from the tombstone state in the base snapshot. This is done
|
|
440
|
+
* during initialization so that deleted or tombstoned objects are marked as such before they are loaded or used.
|
|
437
441
|
*/
|
|
438
442
|
async initializeBaseState() {
|
|
439
443
|
const baseSnapshotData = await this.baseSnapshotDataP;
|
|
440
444
|
/**
|
|
441
|
-
* The base snapshot data
|
|
445
|
+
* The base snapshot data will not be present if the container is loaded from:
|
|
442
446
|
* 1. The first summary created by the detached container.
|
|
443
447
|
* 2. A summary that was generated with GC disabled.
|
|
444
448
|
* 3. A summary that was generated before GC even existed.
|
|
445
|
-
* 4. A summary that was generated with tombstone feature disabled.
|
|
446
449
|
*/
|
|
447
|
-
if (
|
|
450
|
+
if (baseSnapshotData === undefined) {
|
|
448
451
|
return;
|
|
449
452
|
}
|
|
450
|
-
|
|
451
|
-
|
|
453
|
+
// Initialize the deleted nodes from the snapshot. This is done irrespective of whether sweep is enabled or not
|
|
454
|
+
// to identify deleted nodes' usage.
|
|
455
|
+
if (baseSnapshotData.deletedNodes !== undefined) {
|
|
456
|
+
this.deletedNodes = new Set(baseSnapshotData.deletedNodes);
|
|
457
|
+
}
|
|
458
|
+
// If running in tombstone mode, initialize the tombstone state from the snapshot. Also, notify the runtime of
|
|
459
|
+
// tombstone routes.
|
|
460
|
+
if (this.tombstoneMode && baseSnapshotData.tombstones !== undefined) {
|
|
461
|
+
this.tombstones = Array.from(baseSnapshotData.tombstones);
|
|
462
|
+
this.runtime.updateTombstonedRoutes(this.tombstones);
|
|
463
|
+
}
|
|
452
464
|
}
|
|
453
465
|
/**
|
|
454
466
|
* Update state from the given snapshot data. This is done during load and during refreshing state from a snapshot.
|
|
@@ -475,9 +487,30 @@ export class GarbageCollector {
|
|
|
475
487
|
}
|
|
476
488
|
;
|
|
477
489
|
this.unreferencedNodesState.clear();
|
|
478
|
-
// If
|
|
479
|
-
//
|
|
480
|
-
|
|
490
|
+
// If running sweep, the tombstone state represents the list of nodes that have been deleted during sweep.
|
|
491
|
+
// If running in tombstone mode, the tombstone state represents the list of nodes that have been marked as
|
|
492
|
+
// tombstones.
|
|
493
|
+
// If this call is because we are refreshing from a snapshot due to an ack, it is likely that the GC state
|
|
494
|
+
// in the snapshot is newer than this client's. And so, the deleted / tombstone nodes need to be updated.
|
|
495
|
+
if (this.shouldRunSweep) {
|
|
496
|
+
const snapshotDeletedNodes = (snapshotData === null || snapshotData === void 0 ? void 0 : snapshotData.tombstones) ? new Set(snapshotData.tombstones) : undefined;
|
|
497
|
+
// If the snapshot contains deleted nodes that are not yet deleted by this client, ask the runtime to
|
|
498
|
+
// delete them.
|
|
499
|
+
if (snapshotDeletedNodes !== undefined) {
|
|
500
|
+
const newDeletedNodes = [];
|
|
501
|
+
for (const nodeId of snapshotDeletedNodes) {
|
|
502
|
+
if (!this.deletedNodes.has(nodeId)) {
|
|
503
|
+
newDeletedNodes.push(nodeId);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
if (newDeletedNodes.length > 0) {
|
|
507
|
+
// Call container runtime to delete these nodes and add deleted nodes to this.deletedNodes.
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
else if (this.tombstoneMode) {
|
|
512
|
+
// The snapshot may contain more or fewer tombstone nodes than this client. Update tombstone state and
|
|
513
|
+
// notify the runtime to update its state as well.
|
|
481
514
|
this.tombstones = (snapshotData === null || snapshotData === void 0 ? void 0 : snapshotData.tombstones) ? Array.from(snapshotData.tombstones) : [];
|
|
482
515
|
this.runtime.updateTombstonedRoutes(this.tombstones);
|
|
483
516
|
}
|
|
@@ -502,6 +535,7 @@ export class GarbageCollector {
|
|
|
502
535
|
this.latestSummaryData = {
|
|
503
536
|
serializedGCState: JSON.stringify(generateSortedGCState(snapshotData.gcState)),
|
|
504
537
|
serializedTombstones: JSON.stringify(snapshotData.tombstones),
|
|
538
|
+
serializedDeletedNodes: JSON.stringify(snapshotData.deletedNodes),
|
|
505
539
|
};
|
|
506
540
|
}
|
|
507
541
|
}
|
|
@@ -621,17 +655,25 @@ export class GarbageCollector {
|
|
|
621
655
|
};
|
|
622
656
|
}
|
|
623
657
|
const serializedGCState = JSON.stringify(generateSortedGCState(gcState));
|
|
658
|
+
// Serialize and write deleted nodes, if any. This is done irrespective of whether sweep is enabled or not so
|
|
659
|
+
// to identify deleted nodes' usage.
|
|
660
|
+
const serializedDeletedNodes = this.deletedNodes.size > 0
|
|
661
|
+
? JSON.stringify(Array.from(this.deletedNodes).sort())
|
|
662
|
+
: undefined;
|
|
663
|
+
// If running in tombstone mode, serialize and write tombstones, if any.
|
|
624
664
|
const serializedTombstones = this.tombstoneMode
|
|
625
665
|
? (this.tombstones.length > 0 ? JSON.stringify(this.tombstones.sort()) : undefined)
|
|
626
666
|
: undefined;
|
|
627
667
|
/**
|
|
628
|
-
* Incremental summary of GC data - If
|
|
629
|
-
*
|
|
668
|
+
* Incremental summary of GC data - If none of GC state, deleted nodes or tombstones changed since last summary,
|
|
669
|
+
* write summary handle instead of summary tree for GC.
|
|
670
|
+
* Otherwise, write the GC summary tree. In the tree, for each of these that changed, write a summary blob and
|
|
671
|
+
* for each of these that did not change, write a summary handle.
|
|
630
672
|
*/
|
|
631
673
|
if (this.trackGCState) {
|
|
632
|
-
this.pendingSummaryData = { serializedGCState, serializedTombstones };
|
|
674
|
+
this.pendingSummaryData = { serializedGCState, serializedTombstones, serializedDeletedNodes };
|
|
633
675
|
if (trackState && !fullTree && this.latestSummaryData !== undefined) {
|
|
634
|
-
// If
|
|
676
|
+
// If nothing changed since last summary, send a summary handle for the entire GC data.
|
|
635
677
|
if (this.latestSummaryData.serializedGCState === serializedGCState
|
|
636
678
|
&& this.latestSummaryData.serializedTombstones === serializedTombstones) {
|
|
637
679
|
const stats = mergeStats();
|
|
@@ -645,24 +687,25 @@ export class GarbageCollector {
|
|
|
645
687
|
stats,
|
|
646
688
|
};
|
|
647
689
|
}
|
|
648
|
-
// If
|
|
649
|
-
return this.buildGCSummaryTree(serializedGCState, serializedTombstones, true /* trackState */);
|
|
690
|
+
// If some state changed, build a GC summary tree.
|
|
691
|
+
return this.buildGCSummaryTree(serializedGCState, serializedTombstones, serializedDeletedNodes, true /* trackState */);
|
|
650
692
|
}
|
|
651
693
|
}
|
|
652
694
|
// If not tracking GC state, build a GC summary tree without any summary handles.
|
|
653
|
-
return this.buildGCSummaryTree(serializedGCState, serializedTombstones, false /* trackState */);
|
|
695
|
+
return this.buildGCSummaryTree(serializedGCState, serializedTombstones, serializedDeletedNodes, false /* trackState */);
|
|
654
696
|
}
|
|
655
697
|
/**
|
|
656
|
-
* Builds the GC summary tree which contains GC state and
|
|
657
|
-
* If trackState is false,
|
|
658
|
-
* If trackState is true,
|
|
698
|
+
* Builds the GC summary tree which contains GC state, deleted nodes and tombstones.
|
|
699
|
+
* If trackState is false, all of GC state, deleted nodes and tombstones are written as summary blobs.
|
|
700
|
+
* If trackState is true, only states that changed are written. Rest are written as handles.
|
|
659
701
|
* @param serializedGCState - The GC state serialized as string.
|
|
660
|
-
* @param serializedTombstones -
|
|
702
|
+
* @param serializedTombstones - The tombstone state serialized as string.
|
|
703
|
+
* @param serializedDeletedNodes - Deleted nodes serialized as string.
|
|
661
704
|
* @param trackState - Whether we are tracking GC state across summaries.
|
|
662
705
|
* @returns the GC summary tree.
|
|
663
706
|
*/
|
|
664
|
-
buildGCSummaryTree(serializedGCState, serializedTombstones, trackState) {
|
|
665
|
-
var _a, _b;
|
|
707
|
+
buildGCSummaryTree(serializedGCState, serializedTombstones, serializedDeletedNodes, trackState) {
|
|
708
|
+
var _a, _b, _c;
|
|
666
709
|
const gcStateBlobKey = `${gcBlobPrefix}_root`;
|
|
667
710
|
const builder = new SummaryTreeBuilder();
|
|
668
711
|
// If the GC state hasn't changed, write a summary handle, else write a summary blob for it.
|
|
@@ -672,16 +715,26 @@ export class GarbageCollector {
|
|
|
672
715
|
else {
|
|
673
716
|
builder.addBlob(gcStateBlobKey, serializedGCState);
|
|
674
717
|
}
|
|
675
|
-
// If
|
|
676
|
-
|
|
718
|
+
// If tombstones exist, write a summary handle if it hasn't changed. If it has changed, write a
|
|
719
|
+
// summary blob.
|
|
720
|
+
if (serializedTombstones !== undefined) {
|
|
721
|
+
if (((_b = this.latestSummaryData) === null || _b === void 0 ? void 0 : _b.serializedTombstones) === serializedTombstones && trackState) {
|
|
722
|
+
builder.addHandle(gcTombstoneBlobKey, SummaryType.Blob, `/${gcTreeKey}/${gcTombstoneBlobKey}`);
|
|
723
|
+
}
|
|
724
|
+
else {
|
|
725
|
+
builder.addBlob(gcTombstoneBlobKey, serializedTombstones);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
// If there are no deleted nodes, return the summary tree.
|
|
729
|
+
if (serializedDeletedNodes === undefined) {
|
|
677
730
|
return builder.getSummaryTree();
|
|
678
731
|
}
|
|
679
|
-
// If the
|
|
680
|
-
if (((
|
|
681
|
-
builder.addHandle(
|
|
732
|
+
// If the deleted nodes hasn't changed, write a summary handle, else write a summary blob for it.
|
|
733
|
+
if (((_c = this.latestSummaryData) === null || _c === void 0 ? void 0 : _c.serializedDeletedNodes) === serializedDeletedNodes && trackState) {
|
|
734
|
+
builder.addHandle(gcDeletedBlobKey, SummaryType.Blob, `/${gcTreeKey}/${gcDeletedBlobKey}`);
|
|
682
735
|
}
|
|
683
736
|
else {
|
|
684
|
-
builder.addBlob(
|
|
737
|
+
builder.addBlob(gcDeletedBlobKey, serializedDeletedNodes);
|
|
685
738
|
}
|
|
686
739
|
return builder.getSummaryTree();
|
|
687
740
|
}
|
|
@@ -806,6 +859,13 @@ export class GarbageCollector {
|
|
|
806
859
|
}, undefined /* packagePath */);
|
|
807
860
|
}
|
|
808
861
|
}
|
|
862
|
+
/**
|
|
863
|
+
* Returns whether a node with the given path has been deleted or not. This can be used by the runtime to identify
|
|
864
|
+
* cases where objects are used after they are deleted and throw / log errors accordingly.
|
|
865
|
+
*/
|
|
866
|
+
isNodeDeleted(nodePath) {
|
|
867
|
+
return this.deletedNodes.has(nodePath);
|
|
868
|
+
}
|
|
809
869
|
dispose() {
|
|
810
870
|
var _a;
|
|
811
871
|
(_a = this.sessionExpiryTimer) === null || _a === void 0 ? void 0 : _a.clear();
|
|
@@ -1117,7 +1177,7 @@ export class GarbageCollector {
|
|
|
1117
1177
|
this.mc.logger.sendErrorEvent(event);
|
|
1118
1178
|
}
|
|
1119
1179
|
}
|
|
1120
|
-
// If SweepReady Usage Detection is
|
|
1180
|
+
// If SweepReady Usage Detection is enabled, the handler may close the interactive container.
|
|
1121
1181
|
// Once Sweep is fully implemented, this will be removed since the objects will be gone
|
|
1122
1182
|
// and errors will arise elsewhere in the runtime
|
|
1123
1183
|
if (state === UnreferencedState.SweepReady) {
|