@fluidframework/container-runtime 2.0.0-internal.1.4.2 → 2.0.0-internal.2.0.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/batchManager.d.ts +2 -3
- package/dist/batchManager.d.ts.map +1 -1
- package/dist/batchManager.js +3 -8
- package/dist/batchManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +43 -16
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +107 -83
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +4 -20
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +17 -47
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +2 -5
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +3 -11
- package/dist/dataStores.js.map +1 -1
- package/dist/garbageCollection.d.ts +1 -10
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +43 -51
- package/dist/garbageCollection.js.map +1 -1
- package/dist/gcSweepReadyUsageDetection.d.ts.map +1 -1
- package/dist/gcSweepReadyUsageDetection.js +3 -12
- package/dist/gcSweepReadyUsageDetection.js.map +1 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/index.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 +6 -26
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +42 -62
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/scheduleManager.js.map +1 -1
- package/dist/summarizer.js +7 -2
- package/dist/summarizer.js.map +1 -1
- package/dist/summarizerTypes.d.ts +19 -2
- package/dist/summarizerTypes.d.ts.map +1 -1
- package/dist/summarizerTypes.js.map +1 -1
- package/dist/summaryFormat.d.ts +4 -2
- package/dist/summaryFormat.d.ts.map +1 -1
- package/dist/summaryFormat.js.map +1 -1
- package/dist/summaryManager.d.ts.map +1 -1
- package/dist/summaryManager.js +10 -6
- package/dist/summaryManager.js.map +1 -1
- package/lib/batchManager.d.ts +2 -3
- package/lib/batchManager.d.ts.map +1 -1
- package/lib/batchManager.js +3 -8
- package/lib/batchManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +43 -16
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +108 -84
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +4 -20
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +18 -48
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +2 -5
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +3 -11
- package/lib/dataStores.js.map +1 -1
- package/lib/garbageCollection.d.ts +1 -10
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +42 -50
- package/lib/garbageCollection.js.map +1 -1
- package/lib/gcSweepReadyUsageDetection.d.ts.map +1 -1
- package/lib/gcSweepReadyUsageDetection.js +3 -12
- package/lib/gcSweepReadyUsageDetection.js.map +1 -1
- package/lib/index.d.ts +3 -5
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -2
- package/lib/index.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 +6 -26
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +42 -62
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/scheduleManager.js.map +1 -1
- package/lib/summarizer.js +7 -2
- package/lib/summarizer.js.map +1 -1
- package/lib/summarizerTypes.d.ts +19 -2
- package/lib/summarizerTypes.d.ts.map +1 -1
- package/lib/summarizerTypes.js.map +1 -1
- package/lib/summaryFormat.d.ts +4 -2
- package/lib/summaryFormat.d.ts.map +1 -1
- package/lib/summaryFormat.js.map +1 -1
- package/lib/summaryManager.d.ts.map +1 -1
- package/lib/summaryManager.js +10 -6
- package/lib/summaryManager.js.map +1 -1
- package/package.json +40 -38
- package/src/batchManager.ts +7 -11
- package/src/containerRuntime.ts +149 -102
- package/src/dataStoreContext.ts +20 -62
- package/src/dataStores.ts +2 -10
- package/src/garbageCollection.ts +45 -55
- package/src/gcSweepReadyUsageDetection.ts +2 -10
- package/src/index.ts +2 -3
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +57 -96
- package/src/scheduleManager.ts +1 -0
- package/src/summarizer.ts +6 -6
- package/src/summarizerTypes.ts +20 -7
- package/src/summaryFormat.ts +4 -2
- package/src/summaryManager.ts +18 -7
package/lib/dataStores.js
CHANGED
|
@@ -22,7 +22,7 @@ import { GCNodeType } from "./garbageCollection";
|
|
|
22
22
|
* but eventually could be hosted on any channel once we formalize the channel api boundary.
|
|
23
23
|
*/
|
|
24
24
|
export class DataStores {
|
|
25
|
-
constructor(baseSnapshot, runtime, submitAttachFn, getCreateChildSummarizerNodeFn, deleteChildSummarizerNodeFn, baseLogger, getBaseGCDetails, gcNodeUpdated, aliasMap,
|
|
25
|
+
constructor(baseSnapshot, runtime, submitAttachFn, getCreateChildSummarizerNodeFn, deleteChildSummarizerNodeFn, baseLogger, getBaseGCDetails, gcNodeUpdated, aliasMap, contexts = new DataStoreContexts(baseLogger)) {
|
|
26
26
|
this.baseSnapshot = baseSnapshot;
|
|
27
27
|
this.runtime = runtime;
|
|
28
28
|
this.submitAttachFn = submitAttachFn;
|
|
@@ -30,7 +30,6 @@ export class DataStores {
|
|
|
30
30
|
this.deleteChildSummarizerNodeFn = deleteChildSummarizerNodeFn;
|
|
31
31
|
this.gcNodeUpdated = gcNodeUpdated;
|
|
32
32
|
this.aliasMap = aliasMap;
|
|
33
|
-
this.writeGCDataAtRoot = writeGCDataAtRoot;
|
|
34
33
|
this.contexts = contexts;
|
|
35
34
|
// Stores tracked by the Domain
|
|
36
35
|
this.pendingAttach = new Map();
|
|
@@ -77,7 +76,6 @@ export class DataStores {
|
|
|
77
76
|
storage: this.runtime.storage,
|
|
78
77
|
scope: this.runtime.scope,
|
|
79
78
|
createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(key, { type: CreateSummarizerNodeSource.FromSummary }),
|
|
80
|
-
writeGCDataAtRoot: this.writeGCDataAtRoot,
|
|
81
79
|
});
|
|
82
80
|
}
|
|
83
81
|
else {
|
|
@@ -95,7 +93,6 @@ export class DataStores {
|
|
|
95
93
|
makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(key),
|
|
96
94
|
snapshotTree,
|
|
97
95
|
isRootDataStore: undefined,
|
|
98
|
-
writeGCDataAtRoot: this.writeGCDataAtRoot,
|
|
99
96
|
});
|
|
100
97
|
}
|
|
101
98
|
this.contexts.addBoundOrRemoted(dataStoreContext);
|
|
@@ -160,7 +157,6 @@ export class DataStores {
|
|
|
160
157
|
entries: [createAttributesBlob(pkg, true /* isRootDataStore */)],
|
|
161
158
|
},
|
|
162
159
|
}),
|
|
163
|
-
writeGCDataAtRoot: this.writeGCDataAtRoot,
|
|
164
160
|
pkg,
|
|
165
161
|
});
|
|
166
162
|
this.contexts.addBoundOrRemoted(remoteFluidDataStoreContext);
|
|
@@ -231,7 +227,6 @@ export class DataStores {
|
|
|
231
227
|
makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),
|
|
232
228
|
snapshotTree: undefined,
|
|
233
229
|
isRootDataStore: isRoot,
|
|
234
|
-
writeGCDataAtRoot: this.writeGCDataAtRoot,
|
|
235
230
|
});
|
|
236
231
|
this.contexts.addUnbound(context);
|
|
237
232
|
return context;
|
|
@@ -248,7 +243,6 @@ export class DataStores {
|
|
|
248
243
|
makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),
|
|
249
244
|
snapshotTree: undefined,
|
|
250
245
|
isRootDataStore: false,
|
|
251
|
-
writeGCDataAtRoot: this.writeGCDataAtRoot,
|
|
252
246
|
createProps: props,
|
|
253
247
|
});
|
|
254
248
|
this.contexts.addUnbound(context);
|
|
@@ -438,10 +432,8 @@ export class DataStores {
|
|
|
438
432
|
/**
|
|
439
433
|
* After GC has run, called to notify this Container's data stores of routes that are used in it.
|
|
440
434
|
* @param usedRoutes - The routes that are used in all data stores in this Container.
|
|
441
|
-
* @param gcTimestamp - The time when GC was run that generated these used routes. If any node node becomes
|
|
442
|
-
* unreferenced as part of this GC run, this should be used to update the time when it happens.
|
|
443
435
|
*/
|
|
444
|
-
updateUsedRoutes(usedRoutes
|
|
436
|
+
updateUsedRoutes(usedRoutes) {
|
|
445
437
|
var _a;
|
|
446
438
|
// Get a map of data store ids to routes used in it.
|
|
447
439
|
const usedDataStoreRoutes = unpackChildNodesUsedRoutes(usedRoutes);
|
|
@@ -451,7 +443,7 @@ export class DataStores {
|
|
|
451
443
|
}
|
|
452
444
|
// Update the used routes in each data store. Used routes is empty for unused data stores.
|
|
453
445
|
for (const [contextId, context] of this.contexts) {
|
|
454
|
-
context.updateUsedRoutes((_a = usedDataStoreRoutes.get(contextId)) !== null && _a !== void 0 ? _a : []
|
|
446
|
+
context.updateUsedRoutes((_a = usedDataStoreRoutes.get(contextId)) !== null && _a !== void 0 ? _a : []);
|
|
455
447
|
}
|
|
456
448
|
}
|
|
457
449
|
/**
|
package/lib/dataStores.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataStores.js","sourceRoot":"","sources":["../src/dataStores.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger, ITelemetryBaseLogger, IDisposable } from \"@fluidframework/common-definitions\";\nimport { DataCorruptionError, extractSafePropertiesFromMessage } from \"@fluidframework/container-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { FluidObjectHandle } from \"@fluidframework/datastore\";\nimport {\n ISequencedDocumentMessage,\n ISnapshotTree,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n AliasResult,\n channelsTreeName,\n CreateChildSummarizerNodeFn,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n IAttachMessage,\n IEnvelope,\n IFluidDataStoreContextDetached,\n IGarbageCollectionData,\n IGarbageCollectionDetailsBase,\n IInboundSignalMessage,\n InboundAttachMessage,\n ISummarizeResult,\n ISummaryTreeWithStats,\n ITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n convertSnapshotTreeToSummaryTree,\n convertToSummaryTree,\n create404Response,\n responseToException,\n SummaryTreeBuilder,\n} from \"@fluidframework/runtime-utils\";\nimport { ChildLogger, LoggingError, TelemetryDataTag } from \"@fluidframework/telemetry-utils\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { BlobCacheStorageService, buildSnapshotTree } from \"@fluidframework/driver-utils\";\nimport { assert, Lazy, LazyPromise } from \"@fluidframework/common-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { GCDataBuilder, unpackChildNodesUsedRoutes } from \"@fluidframework/garbage-collector\";\nimport { DataStoreContexts } from \"./dataStoreContexts\";\nimport { ContainerRuntime } from \"./containerRuntime\";\nimport {\n FluidDataStoreContext,\n RemoteFluidDataStoreContext,\n LocalFluidDataStoreContext,\n createAttributesBlob,\n LocalDetachedFluidDataStoreContext,\n} from \"./dataStoreContext\";\nimport { IContainerRuntimeMetadata, nonDataStorePaths, rootHasIsolatedChannels } from \"./summaryFormat\";\nimport { IDataStoreAliasMessage, isDataStoreAliasMessage } from \"./dataStore\";\nimport { GCNodeType } from \"./garbageCollection\";\n\ntype PendingAliasResolve = (success: boolean) => void;\n\n/**\n * This class encapsulates data store handling. Currently it is only used by the container runtime,\n * but eventually could be hosted on any channel once we formalize the channel api boundary.\n */\nexport class DataStores implements IDisposable {\n // Stores tracked by the Domain\n private readonly pendingAttach = new Map<string, IAttachMessage>();\n // 0.24 back-compat attachingBeforeSummary\n public readonly attachOpFiredForDataStore = new Set<string>();\n\n private readonly logger: ITelemetryLogger;\n\n private readonly disposeOnce = new Lazy<void>(() => this.contexts.dispose());\n\n public readonly containerLoadStats: {\n // number of dataStores during loadContainer\n readonly containerLoadDataStoreCount: number;\n // number of unreferenced dataStores during loadContainer\n readonly referencedDataStoreCount: number;\n };\n\n // Stores the ids of new data stores between two GC runs. This is used to notify the garbage collector of new\n // root data stores that are added.\n private dataStoresSinceLastGC: string[] = [];\n // The handle to the container runtime. This is used mainly for GC purposes to represent outbound reference from\n // the container runtime to other nodes.\n private readonly containerRuntimeHandle: IFluidHandle;\n private readonly pendingAliasMap: Map<string, Promise<AliasResult>> = new Map<string, Promise<AliasResult>>();\n\n constructor(\n private readonly baseSnapshot: ISnapshotTree | undefined,\n private readonly runtime: ContainerRuntime,\n private readonly submitAttachFn: (attachContent: any) => void,\n private readonly getCreateChildSummarizerNodeFn:\n (id: string, createParam: CreateChildSummarizerNodeParam) => CreateChildSummarizerNodeFn,\n private readonly deleteChildSummarizerNodeFn: (id: string) => void,\n baseLogger: ITelemetryBaseLogger,\n getBaseGCDetails: () => Promise<Map<string, IGarbageCollectionDetailsBase>>,\n private readonly gcNodeUpdated: (\n nodePath: string, timestampMs: number, packagePath?: readonly string[]) => void,\n private readonly aliasMap: Map<string, string>,\n private readonly writeGCDataAtRoot: boolean,\n private readonly contexts: DataStoreContexts = new DataStoreContexts(baseLogger),\n ) {\n this.logger = ChildLogger.create(baseLogger);\n this.containerRuntimeHandle = new FluidObjectHandle(this.runtime, \"/\", this.runtime.IFluidHandleContext);\n\n const baseGCDetailsP = new LazyPromise(async () => {\n return getBaseGCDetails();\n });\n // Returns the base GC details for the data store with the given id.\n const dataStoreBaseGCDetails = async (dataStoreId: string) => {\n const baseGCDetails = await baseGCDetailsP;\n return baseGCDetails.get(dataStoreId);\n };\n\n // Extract stores stored inside the snapshot\n const fluidDataStores = new Map<string, ISnapshotTree>();\n if (baseSnapshot) {\n for (const [key, value] of Object.entries(baseSnapshot.trees)) {\n fluidDataStores.set(key, value);\n }\n }\n\n let unreferencedDataStoreCount = 0;\n // Create a context for each of them\n for (const [key, value] of fluidDataStores) {\n let dataStoreContext: FluidDataStoreContext;\n\n // counting number of unreferenced data stores\n if (value.unreferenced) {\n unreferencedDataStoreCount++;\n }\n // If we have a detached container, then create local data store contexts.\n if (this.runtime.attachState !== AttachState.Detached) {\n dataStoreContext = new RemoteFluidDataStoreContext({\n id: key,\n snapshotTree: value,\n getBaseGCDetails: async () => dataStoreBaseGCDetails(key),\n runtime: this.runtime,\n storage: this.runtime.storage,\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n key,\n { type: CreateSummarizerNodeSource.FromSummary },\n ),\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n });\n } else {\n if (typeof value !== \"object\") {\n throw new LoggingError(\"Snapshot should be there to load from!!\");\n }\n const snapshotTree = value;\n dataStoreContext = new LocalFluidDataStoreContext({\n id: key,\n pkg: undefined,\n runtime: this.runtime,\n storage: this.runtime.storage,\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n key,\n { type: CreateSummarizerNodeSource.FromSummary },\n ),\n makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(key),\n snapshotTree,\n isRootDataStore: undefined,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n });\n }\n this.contexts.addBoundOrRemoted(dataStoreContext);\n }\n this.containerLoadStats = {\n containerLoadDataStoreCount: fluidDataStores.size,\n referencedDataStoreCount: fluidDataStores.size - unreferencedDataStoreCount,\n };\n }\n\n public get aliases(): ReadonlyMap<string, string> {\n return this.aliasMap;\n }\n\n public get pendingAliases(): Map<string, Promise<AliasResult>> {\n return this.pendingAliasMap;\n }\n\n public async waitIfPendingAlias(maybeAlias: string): Promise<AliasResult> {\n const pendingAliasPromise = this.pendingAliases.get(maybeAlias);\n return pendingAliasPromise === undefined ? \"Success\" : pendingAliasPromise;\n }\n\n public processAttachMessage(message: ISequencedDocumentMessage, local: boolean) {\n const attachMessage = message.contents as InboundAttachMessage;\n\n this.dataStoresSinceLastGC.push(attachMessage.id);\n\n // The local object has already been attached\n if (local) {\n assert(this.pendingAttach.has(attachMessage.id),\n 0x15e /* \"Local object does not have matching attach message id\" */);\n this.contexts.get(attachMessage.id)?.emit(\"attached\");\n this.pendingAttach.delete(attachMessage.id);\n return;\n }\n\n // If a non-local operation then go and create the object, otherwise mark it as officially attached.\n if (this.alreadyProcessed(attachMessage.id)) {\n // TODO: dataStoreId may require a different tag from PackageData #7488\n const error = new DataCorruptionError(\n // pre-0.58 error message: duplicateDataStoreCreatedWithExistingId\n \"Duplicate DataStore created with existing id\",\n {\n ...extractSafePropertiesFromMessage(message),\n dataStoreId: {\n value: attachMessage.id,\n tag: TelemetryDataTag.CodeArtifact,\n },\n },\n );\n throw error;\n }\n\n const flatBlobs = new Map<string, ArrayBufferLike>();\n let snapshotTree: ISnapshotTree | undefined;\n if (attachMessage.snapshot) {\n snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatBlobs);\n }\n\n // Include the type of attach message which is the pkg of the store to be\n // used by RemoteFluidDataStoreContext in case it is not in the snapshot.\n const pkg = [attachMessage.type];\n const remoteFluidDataStoreContext = new RemoteFluidDataStoreContext({\n id: attachMessage.id,\n snapshotTree,\n // New data stores begin with empty GC details since GC hasn't run on them yet.\n getBaseGCDetails: async () => { return {}; },\n runtime: this.runtime,\n storage: new BlobCacheStorageService(this.runtime.storage, flatBlobs),\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n attachMessage.id,\n {\n type: CreateSummarizerNodeSource.FromAttach,\n sequenceNumber: message.sequenceNumber,\n snapshot: attachMessage.snapshot ?? {\n entries: [createAttributesBlob(\n pkg,\n true /* isRootDataStore */,\n )],\n },\n },\n ),\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n pkg,\n });\n\n this.contexts.addBoundOrRemoted(remoteFluidDataStoreContext);\n }\n\n public processAliasMessage(\n message: ISequencedDocumentMessage,\n localOpMetadata: unknown,\n local: boolean,\n ): void {\n const aliasMessage = message.contents as IDataStoreAliasMessage;\n if (!isDataStoreAliasMessage(aliasMessage)) {\n throw new DataCorruptionError(\n \"malformedDataStoreAliasMessage\",\n {\n ...extractSafePropertiesFromMessage(message),\n },\n );\n }\n\n const resolve = localOpMetadata as PendingAliasResolve;\n const aliasResult = this.processAliasMessageCore(aliasMessage);\n if (local) {\n resolve(aliasResult);\n }\n }\n\n public processAliasMessageCore(aliasMessage: IDataStoreAliasMessage): boolean {\n if (this.alreadyProcessed(aliasMessage.alias)) {\n return false;\n }\n\n const context = this.contexts.get(aliasMessage.internalId);\n if (context === undefined) {\n this.logger.sendErrorEvent({\n eventName: \"AliasFluidDataStoreNotFound\",\n fluidDataStoreId: aliasMessage.internalId,\n });\n return false;\n }\n\n const handle = new FluidObjectHandle(\n context,\n aliasMessage.internalId,\n this.runtime.IFluidHandleContext,\n );\n this.runtime.addedGCOutboundReference(this.containerRuntimeHandle, handle);\n\n this.aliasMap.set(aliasMessage.alias, context.id);\n context.setInMemoryRoot();\n return true;\n }\n\n private alreadyProcessed(id: string): boolean {\n return this.aliasMap.get(id) !== undefined || this.contexts.get(id) !== undefined;\n }\n\n /**\n * Make the data stores locally visible in the container graph by moving the data store context from unbound to\n * bound list. This data store can now be reached from the root.\n * @param id - The id of the data store context to make visible.\n */\n private makeDataStoreLocallyVisible(id: string): void {\n const localContext = this.contexts.getUnbound(id);\n assert(!!localContext, 0x15f /* \"Could not find unbound context to bind\" */);\n\n /**\n * If the container is not detached, it is globally visible to all clients. This data store should also be\n * globally visible. Move it to attaching state and send an \"attach\" op for it.\n * If the container is detached, this data store will be part of the summary that makes the container attached.\n */\n if (this.runtime.attachState !== AttachState.Detached) {\n localContext.emit(\"attaching\");\n const message = localContext.generateAttachMessage();\n\n this.pendingAttach.set(id, message);\n this.submitAttachFn(message);\n this.attachOpFiredForDataStore.add(id);\n }\n\n this.contexts.bind(id);\n }\n\n public createDetachedDataStoreCore(\n pkg: Readonly<string[]>,\n isRoot: boolean,\n id = uuid()): IFluidDataStoreContextDetached {\n assert(!id.includes(\"/\"), 0x30c /* Id cannot contain slashes */);\n\n const context = new LocalDetachedFluidDataStoreContext({\n id,\n pkg,\n runtime: this.runtime,\n storage: this.runtime.storage,\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n id,\n { type: CreateSummarizerNodeSource.Local },\n ),\n makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),\n snapshotTree: undefined,\n isRootDataStore: isRoot,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n });\n this.contexts.addUnbound(context);\n return context;\n }\n\n public _createFluidDataStoreContext(pkg: string[], id: string, props?: any) {\n assert(!id.includes(\"/\"), 0x30d /* Id cannot contain slashes */);\n const context = new LocalFluidDataStoreContext({\n id,\n pkg,\n runtime: this.runtime,\n storage: this.runtime.storage,\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n id,\n { type: CreateSummarizerNodeSource.Local },\n ),\n makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),\n snapshotTree: undefined,\n isRootDataStore: false,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n createProps: props,\n });\n this.contexts.addUnbound(context);\n return context;\n }\n\n public get disposed() { return this.disposeOnce.evaluated; }\n public readonly dispose = () => this.disposeOnce.value;\n\n public resubmitDataStoreOp(content: any, localOpMetadata: unknown) {\n const envelope = content as IEnvelope;\n const context = this.contexts.get(envelope.address);\n assert(!!context, 0x160 /* \"There should be a store context for the op\" */);\n context.reSubmit(envelope.contents, localOpMetadata);\n }\n\n public rollbackDataStoreOp(content: any, localOpMetadata: unknown) {\n const envelope = content as IEnvelope;\n const context = this.contexts.get(envelope.address);\n assert(!!context, 0x2e8 /* \"There should be a store context for the op\" */);\n context.rollback(envelope.contents, localOpMetadata);\n }\n\n public async applyStashedOp(content: any): Promise<unknown> {\n const envelope = content as IEnvelope;\n const context = this.contexts.get(envelope.address);\n assert(!!context, 0x161 /* \"There should be a store context for the op\" */);\n return context.applyStashedOp(envelope.contents);\n }\n\n public async applyStashedAttachOp(message: IAttachMessage) {\n this.pendingAttach.set(message.id, message);\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n this.processAttachMessage({ contents: message } as ISequencedDocumentMessage, false);\n }\n\n public processFluidDataStoreOp(message: ISequencedDocumentMessage, local: boolean, localMessageMetadata: unknown) {\n const envelope = message.contents as IEnvelope;\n const transformed = { ...message, contents: envelope.contents };\n const context = this.contexts.get(envelope.address);\n assert(!!context, 0x162 /* \"There should be a store context for the op\" */);\n context.process(transformed, local, localMessageMetadata);\n\n // Notify that a GC node for the data store changed. This is used to detect if a deleted data store is\n // being used.\n this.gcNodeUpdated(\n `/${envelope.address}`,\n message.timestamp,\n context.isLoaded ? context.packagePath : undefined,\n );\n }\n\n public async getDataStore(id: string, wait: boolean): Promise<FluidDataStoreContext> {\n const context = await this.contexts.getBoundOrRemoted(id, wait);\n if (context === undefined) {\n // The requested data store does not exits. Throw a 404 response exception.\n const request = { url: id };\n throw responseToException(create404Response(request), request);\n }\n\n return context;\n }\n\n public processSignal(address: string, message: IInboundSignalMessage, local: boolean) {\n const context = this.contexts.get(address);\n if (!context) {\n // Attach message may not have been processed yet\n assert(!local, 0x163 /* \"Missing datastore for local signal\" */);\n this.logger.sendTelemetryEvent({\n eventName: \"SignalFluidDataStoreNotFound\",\n fluidDataStoreId: {\n value: address,\n tag: TelemetryDataTag.CodeArtifact,\n },\n });\n return;\n }\n\n context.processSignal(message, local);\n }\n\n public setConnectionState(connected: boolean, clientId?: string) {\n for (const [fluidDataStore, context] of this.contexts) {\n try {\n context.setConnectionState(connected, clientId);\n } catch (error) {\n this.logger.sendErrorEvent({\n eventName: \"SetConnectionStateError\",\n clientId,\n fluidDataStore,\n }, error);\n }\n }\n }\n\n public setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {\n const eventName = attachState === AttachState.Attaching ? \"attaching\" : \"attached\";\n for (const [, context] of this.contexts) {\n // Fire only for bounded stores.\n if (!this.contexts.isNotBound(context.id)) {\n context.emit(eventName);\n }\n }\n }\n\n public get size(): number {\n return this.contexts.size;\n }\n\n public async summarize(\n fullTree: boolean,\n trackState: boolean,\n telemetryContext?: ITelemetryContext,\n ): Promise<ISummaryTreeWithStats> {\n const summaryBuilder = new SummaryTreeBuilder();\n\n // Iterate over each store and ask it to snapshot\n await Promise.all(Array.from(this.contexts)\n .filter(([_, context]) => {\n // Summarizer works only with clients with no local changes!\n assert(context.attachState !== AttachState.Attaching,\n 0x165 /* \"Summarizer cannot work if client has local changes\" */);\n return context.attachState === AttachState.Attached;\n }).map(async ([contextId, context]) => {\n const contextSummary = await context.summarize(fullTree, trackState, telemetryContext);\n summaryBuilder.addWithStats(contextId, contextSummary);\n }));\n\n return summaryBuilder.getSummaryTree();\n }\n\n public createSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {\n const builder = new SummaryTreeBuilder();\n // Attaching graph of some stores can cause other stores to get bound too.\n // So keep taking summary until no new stores get bound.\n let notBoundContextsLength: number;\n do {\n const builderTree = builder.summary.tree;\n notBoundContextsLength = this.contexts.notBoundLength();\n // Iterate over each data store and ask it to snapshot\n Array.from(this.contexts)\n .filter(([key, _]) =>\n // Take summary of bounded data stores only, make sure we haven't summarized them already\n // and no attach op has been fired for that data store because for loader versions <= 0.24\n // we set attach state as \"attaching\" before taking createNew summary.\n !(this.contexts.isNotBound(key)\n || builderTree[key]\n || this.attachOpFiredForDataStore.has(key)),\n )\n .map(([key, value]) => {\n let dataStoreSummary: ISummarizeResult;\n if (value.isLoaded) {\n const snapshot = value.generateAttachMessage().snapshot;\n dataStoreSummary = convertToSummaryTree(snapshot, true);\n } else {\n // If this data store is not yet loaded, then there should be no changes in the snapshot from\n // which it was created as it is detached container. So just use the previous snapshot.\n assert(!!this.baseSnapshot,\n 0x166 /* \"BaseSnapshot should be there as detached container loaded from snapshot\" */);\n dataStoreSummary = convertSnapshotTreeToSummaryTree(this.baseSnapshot.trees[key]);\n }\n builder.addWithStats(key, dataStoreSummary);\n });\n } while (notBoundContextsLength !== this.contexts.notBoundLength());\n\n return builder.getSummaryTree();\n }\n\n /**\n * Before GC runs, called by the garbage collector to update any pending GC state.\n * The garbage collector needs to know all outbound references that are added. Since root data stores are not\n * explicitly marked as referenced, notify GC of new root data stores that were added since the last GC run.\n */\n public async updateStateBeforeGC(): Promise<void> {\n for (const id of this.dataStoresSinceLastGC) {\n const context = this.contexts.get(id);\n assert(context !== undefined, 0x2b6 /* Missing data store context */);\n if (await context.isRoot()) {\n // A root data store is basically a reference from the container runtime to the data store.\n const handle = new FluidObjectHandle(context, id, this.runtime.IFluidHandleContext);\n this.runtime.addedGCOutboundReference(this.containerRuntimeHandle, handle);\n }\n }\n this.dataStoresSinceLastGC = [];\n }\n\n /**\n * Generates data used for garbage collection. It does the following:\n *\n * 1. Calls into each child data store context to get its GC data.\n *\n * 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be\n * identified as belonging to the child.\n *\n * 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent\n * the GC data of this channel.\n *\n * @param fullGC - true to bypass optimizations and force full generation of GC data.\n */\n public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n const builder = new GCDataBuilder();\n // Iterate over each store and get their GC data.\n await Promise.all(Array.from(this.contexts)\n .filter(([_, context]) => {\n // Get GC data only for attached contexts. Detached contexts are not connected in the GC reference\n // graph so any references they might have won't be connected as well.\n return context.attachState === AttachState.Attached;\n }).map(async ([contextId, context]) => {\n const contextGCData = await context.getGCData(fullGC);\n // Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.\n // This also gradually builds the id of each node to be a path from the root.\n builder.prefixAndAddNodes(contextId, contextGCData.gcNodes);\n }));\n\n // Get the outbound routes and add a GC node for this channel.\n builder.addNode(\"/\", await this.getOutboundRoutes());\n return builder.getGCData();\n }\n\n /**\n * After GC has run, called to notify this Container's data stores of routes that are used in it.\n * @param usedRoutes - The routes that are used in all data stores in this Container.\n * @param gcTimestamp - The time when GC was run that generated these used routes. If any node node becomes\n * unreferenced as part of this GC run, this should be used to update the time when it happens.\n */\n public updateUsedRoutes(usedRoutes: string[], gcTimestamp?: number) {\n // Get a map of data store ids to routes used in it.\n const usedDataStoreRoutes = unpackChildNodesUsedRoutes(usedRoutes);\n\n // Verify that the used routes are correct.\n for (const [id] of usedDataStoreRoutes) {\n assert(this.contexts.has(id), 0x167 /* \"Used route does not belong to any known data store\" */);\n }\n\n // Update the used routes in each data store. Used routes is empty for unused data stores.\n for (const [contextId, context] of this.contexts) {\n context.updateUsedRoutes(usedDataStoreRoutes.get(contextId) ?? [], gcTimestamp);\n }\n }\n\n /**\n * When running GC in test mode, this is called to delete objects whose routes are unused. This enables testing\n * scenarios with accessing deleted content.\n * @param unusedRoutes - The routes that are unused in all data stores in this Container.\n */\n public deleteUnusedRoutes(unusedRoutes: string[]) {\n for (const route of unusedRoutes) {\n const pathParts = route.split(\"/\");\n // Delete data store only if its route (/datastoreId) is in unusedRoutes. We don't want to delete a data\n // store based on its DDS being unused.\n if (pathParts.length > 2) {\n continue;\n }\n const dataStoreId = pathParts[1];\n assert(this.contexts.has(dataStoreId), 0x2d7 /* No data store with specified id */);\n // Delete the contexts of unused data stores.\n this.contexts.delete(dataStoreId);\n // Delete the summarizer node of the unused data stores.\n this.deleteChildSummarizerNodeFn(dataStoreId);\n }\n }\n\n /**\n * Returns the outbound routes of this channel. Only root data stores are considered referenced and their paths are\n * part of outbound routes.\n */\n private async getOutboundRoutes(): Promise<string[]> {\n const outboundRoutes: string[] = [];\n for (const [contextId, context] of this.contexts) {\n const isRootDataStore = await context.isRoot();\n if (isRootDataStore) {\n outboundRoutes.push(`/${contextId}`);\n }\n }\n return outboundRoutes;\n }\n\n /**\n * Called by GC to retrieve the package path of a data store node with the given path.\n */\n public async getDataStorePackagePath(nodePath: string): Promise<readonly string[] | undefined> {\n // If the node belongs to a data store, return its package path. For DDSes, we return the package path of the\n // data store that contains it.\n const context = this.contexts.get(nodePath.split(\"/\")[1]);\n return (await context?.getInitialSnapshotDetails())?.pkg;\n }\n\n /**\n * Called by GC to determine if a node is for a data store or for an object within a data store (for e.g. DDS).\n * @returns the GC node type if the node belongs to a data store or object within data store, undefined otherwise.\n */\n public getGCNodeType(nodePath: string): GCNodeType | undefined {\n const pathParts = nodePath.split(\"/\");\n if (!this.contexts.has(pathParts[1])) {\n return undefined;\n }\n\n // Data stores paths are of the format \"/dataStoreId\".\n // Sub data store paths are of the format \"/dataStoreId/subPath/...\".\n if (pathParts.length === 2) {\n return GCNodeType.DataStore;\n }\n return GCNodeType.SubDataStore;\n }\n}\n\nexport function getSummaryForDatastores(\n snapshot: ISnapshotTree | undefined,\n metadata?: IContainerRuntimeMetadata,\n): ISnapshotTree | undefined {\n if (!snapshot) {\n return undefined;\n }\n\n if (rootHasIsolatedChannels(metadata)) {\n const datastoresSnapshot = snapshot.trees[channelsTreeName];\n assert(!!datastoresSnapshot, 0x168 /* Expected tree in snapshot not found */);\n return datastoresSnapshot;\n } else {\n // back-compat: strip out all non-datastore paths before giving to DataStores object.\n const datastoresTrees: ISnapshotTree[\"trees\"] = {};\n for (const [key, value] of Object.entries(snapshot.trees)) {\n if (!nonDataStorePaths.includes(key)) {\n datastoresTrees[key] = value;\n }\n }\n return {\n ...snapshot,\n trees: datastoresTrees,\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dataStores.js","sourceRoot":"","sources":["../src/dataStores.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger, ITelemetryBaseLogger, IDisposable } from \"@fluidframework/common-definitions\";\nimport { DataCorruptionError, extractSafePropertiesFromMessage } from \"@fluidframework/container-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { FluidObjectHandle } from \"@fluidframework/datastore\";\nimport {\n ISequencedDocumentMessage,\n ISnapshotTree,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n AliasResult,\n channelsTreeName,\n CreateChildSummarizerNodeFn,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n IAttachMessage,\n IEnvelope,\n IFluidDataStoreContextDetached,\n IGarbageCollectionData,\n IGarbageCollectionDetailsBase,\n IInboundSignalMessage,\n InboundAttachMessage,\n ISummarizeResult,\n ISummaryTreeWithStats,\n ITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n convertSnapshotTreeToSummaryTree,\n convertToSummaryTree,\n create404Response,\n responseToException,\n SummaryTreeBuilder,\n} from \"@fluidframework/runtime-utils\";\nimport { ChildLogger, LoggingError, TelemetryDataTag } from \"@fluidframework/telemetry-utils\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { BlobCacheStorageService, buildSnapshotTree } from \"@fluidframework/driver-utils\";\nimport { assert, Lazy, LazyPromise } from \"@fluidframework/common-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { GCDataBuilder, unpackChildNodesUsedRoutes } from \"@fluidframework/garbage-collector\";\nimport { DataStoreContexts } from \"./dataStoreContexts\";\nimport { ContainerRuntime } from \"./containerRuntime\";\nimport {\n FluidDataStoreContext,\n RemoteFluidDataStoreContext,\n LocalFluidDataStoreContext,\n createAttributesBlob,\n LocalDetachedFluidDataStoreContext,\n} from \"./dataStoreContext\";\nimport { IContainerRuntimeMetadata, nonDataStorePaths, rootHasIsolatedChannels } from \"./summaryFormat\";\nimport { IDataStoreAliasMessage, isDataStoreAliasMessage } from \"./dataStore\";\nimport { GCNodeType } from \"./garbageCollection\";\n\ntype PendingAliasResolve = (success: boolean) => void;\n\n/**\n * This class encapsulates data store handling. Currently it is only used by the container runtime,\n * but eventually could be hosted on any channel once we formalize the channel api boundary.\n */\nexport class DataStores implements IDisposable {\n // Stores tracked by the Domain\n private readonly pendingAttach = new Map<string, IAttachMessage>();\n // 0.24 back-compat attachingBeforeSummary\n public readonly attachOpFiredForDataStore = new Set<string>();\n\n private readonly logger: ITelemetryLogger;\n\n private readonly disposeOnce = new Lazy<void>(() => this.contexts.dispose());\n\n public readonly containerLoadStats: {\n // number of dataStores during loadContainer\n readonly containerLoadDataStoreCount: number;\n // number of unreferenced dataStores during loadContainer\n readonly referencedDataStoreCount: number;\n };\n\n // Stores the ids of new data stores between two GC runs. This is used to notify the garbage collector of new\n // root data stores that are added.\n private dataStoresSinceLastGC: string[] = [];\n // The handle to the container runtime. This is used mainly for GC purposes to represent outbound reference from\n // the container runtime to other nodes.\n private readonly containerRuntimeHandle: IFluidHandle;\n private readonly pendingAliasMap: Map<string, Promise<AliasResult>> = new Map<string, Promise<AliasResult>>();\n\n constructor(\n private readonly baseSnapshot: ISnapshotTree | undefined,\n private readonly runtime: ContainerRuntime,\n private readonly submitAttachFn: (attachContent: any) => void,\n private readonly getCreateChildSummarizerNodeFn:\n (id: string, createParam: CreateChildSummarizerNodeParam) => CreateChildSummarizerNodeFn,\n private readonly deleteChildSummarizerNodeFn: (id: string) => void,\n baseLogger: ITelemetryBaseLogger,\n getBaseGCDetails: () => Promise<Map<string, IGarbageCollectionDetailsBase>>,\n private readonly gcNodeUpdated: (\n nodePath: string, timestampMs: number, packagePath?: readonly string[]) => void,\n private readonly aliasMap: Map<string, string>,\n private readonly contexts: DataStoreContexts = new DataStoreContexts(baseLogger),\n ) {\n this.logger = ChildLogger.create(baseLogger);\n this.containerRuntimeHandle = new FluidObjectHandle(this.runtime, \"/\", this.runtime.IFluidHandleContext);\n\n const baseGCDetailsP = new LazyPromise(async () => {\n return getBaseGCDetails();\n });\n // Returns the base GC details for the data store with the given id.\n const dataStoreBaseGCDetails = async (dataStoreId: string) => {\n const baseGCDetails = await baseGCDetailsP;\n return baseGCDetails.get(dataStoreId);\n };\n\n // Extract stores stored inside the snapshot\n const fluidDataStores = new Map<string, ISnapshotTree>();\n if (baseSnapshot) {\n for (const [key, value] of Object.entries(baseSnapshot.trees)) {\n fluidDataStores.set(key, value);\n }\n }\n\n let unreferencedDataStoreCount = 0;\n // Create a context for each of them\n for (const [key, value] of fluidDataStores) {\n let dataStoreContext: FluidDataStoreContext;\n\n // counting number of unreferenced data stores\n if (value.unreferenced) {\n unreferencedDataStoreCount++;\n }\n // If we have a detached container, then create local data store contexts.\n if (this.runtime.attachState !== AttachState.Detached) {\n dataStoreContext = new RemoteFluidDataStoreContext({\n id: key,\n snapshotTree: value,\n getBaseGCDetails: async () => dataStoreBaseGCDetails(key),\n runtime: this.runtime,\n storage: this.runtime.storage,\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n key,\n { type: CreateSummarizerNodeSource.FromSummary },\n ),\n });\n } else {\n if (typeof value !== \"object\") {\n throw new LoggingError(\"Snapshot should be there to load from!!\");\n }\n const snapshotTree = value;\n dataStoreContext = new LocalFluidDataStoreContext({\n id: key,\n pkg: undefined,\n runtime: this.runtime,\n storage: this.runtime.storage,\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n key,\n { type: CreateSummarizerNodeSource.FromSummary },\n ),\n makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(key),\n snapshotTree,\n isRootDataStore: undefined,\n });\n }\n this.contexts.addBoundOrRemoted(dataStoreContext);\n }\n this.containerLoadStats = {\n containerLoadDataStoreCount: fluidDataStores.size,\n referencedDataStoreCount: fluidDataStores.size - unreferencedDataStoreCount,\n };\n }\n\n public get aliases(): ReadonlyMap<string, string> {\n return this.aliasMap;\n }\n\n public get pendingAliases(): Map<string, Promise<AliasResult>> {\n return this.pendingAliasMap;\n }\n\n public async waitIfPendingAlias(maybeAlias: string): Promise<AliasResult> {\n const pendingAliasPromise = this.pendingAliases.get(maybeAlias);\n return pendingAliasPromise === undefined ? \"Success\" : pendingAliasPromise;\n }\n\n public processAttachMessage(message: ISequencedDocumentMessage, local: boolean) {\n const attachMessage = message.contents as InboundAttachMessage;\n\n this.dataStoresSinceLastGC.push(attachMessage.id);\n\n // The local object has already been attached\n if (local) {\n assert(this.pendingAttach.has(attachMessage.id),\n 0x15e /* \"Local object does not have matching attach message id\" */);\n this.contexts.get(attachMessage.id)?.emit(\"attached\");\n this.pendingAttach.delete(attachMessage.id);\n return;\n }\n\n // If a non-local operation then go and create the object, otherwise mark it as officially attached.\n if (this.alreadyProcessed(attachMessage.id)) {\n // TODO: dataStoreId may require a different tag from PackageData #7488\n const error = new DataCorruptionError(\n // pre-0.58 error message: duplicateDataStoreCreatedWithExistingId\n \"Duplicate DataStore created with existing id\",\n {\n ...extractSafePropertiesFromMessage(message),\n dataStoreId: {\n value: attachMessage.id,\n tag: TelemetryDataTag.CodeArtifact,\n },\n },\n );\n throw error;\n }\n\n const flatBlobs = new Map<string, ArrayBufferLike>();\n let snapshotTree: ISnapshotTree | undefined;\n if (attachMessage.snapshot) {\n snapshotTree = buildSnapshotTree(attachMessage.snapshot.entries, flatBlobs);\n }\n\n // Include the type of attach message which is the pkg of the store to be\n // used by RemoteFluidDataStoreContext in case it is not in the snapshot.\n const pkg = [attachMessage.type];\n const remoteFluidDataStoreContext = new RemoteFluidDataStoreContext({\n id: attachMessage.id,\n snapshotTree,\n // New data stores begin with empty GC details since GC hasn't run on them yet.\n getBaseGCDetails: async () => { return {}; },\n runtime: this.runtime,\n storage: new BlobCacheStorageService(this.runtime.storage, flatBlobs),\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n attachMessage.id,\n {\n type: CreateSummarizerNodeSource.FromAttach,\n sequenceNumber: message.sequenceNumber,\n snapshot: attachMessage.snapshot ?? {\n entries: [createAttributesBlob(\n pkg,\n true /* isRootDataStore */,\n )],\n },\n },\n ),\n pkg,\n });\n\n this.contexts.addBoundOrRemoted(remoteFluidDataStoreContext);\n }\n\n public processAliasMessage(\n message: ISequencedDocumentMessage,\n localOpMetadata: unknown,\n local: boolean,\n ): void {\n const aliasMessage = message.contents as IDataStoreAliasMessage;\n if (!isDataStoreAliasMessage(aliasMessage)) {\n throw new DataCorruptionError(\n \"malformedDataStoreAliasMessage\",\n {\n ...extractSafePropertiesFromMessage(message),\n },\n );\n }\n\n const resolve = localOpMetadata as PendingAliasResolve;\n const aliasResult = this.processAliasMessageCore(aliasMessage);\n if (local) {\n resolve(aliasResult);\n }\n }\n\n public processAliasMessageCore(aliasMessage: IDataStoreAliasMessage): boolean {\n if (this.alreadyProcessed(aliasMessage.alias)) {\n return false;\n }\n\n const context = this.contexts.get(aliasMessage.internalId);\n if (context === undefined) {\n this.logger.sendErrorEvent({\n eventName: \"AliasFluidDataStoreNotFound\",\n fluidDataStoreId: aliasMessage.internalId,\n });\n return false;\n }\n\n const handle = new FluidObjectHandle(\n context,\n aliasMessage.internalId,\n this.runtime.IFluidHandleContext,\n );\n this.runtime.addedGCOutboundReference(this.containerRuntimeHandle, handle);\n\n this.aliasMap.set(aliasMessage.alias, context.id);\n context.setInMemoryRoot();\n return true;\n }\n\n private alreadyProcessed(id: string): boolean {\n return this.aliasMap.get(id) !== undefined || this.contexts.get(id) !== undefined;\n }\n\n /**\n * Make the data stores locally visible in the container graph by moving the data store context from unbound to\n * bound list. This data store can now be reached from the root.\n * @param id - The id of the data store context to make visible.\n */\n private makeDataStoreLocallyVisible(id: string): void {\n const localContext = this.contexts.getUnbound(id);\n assert(!!localContext, 0x15f /* \"Could not find unbound context to bind\" */);\n\n /**\n * If the container is not detached, it is globally visible to all clients. This data store should also be\n * globally visible. Move it to attaching state and send an \"attach\" op for it.\n * If the container is detached, this data store will be part of the summary that makes the container attached.\n */\n if (this.runtime.attachState !== AttachState.Detached) {\n localContext.emit(\"attaching\");\n const message = localContext.generateAttachMessage();\n\n this.pendingAttach.set(id, message);\n this.submitAttachFn(message);\n this.attachOpFiredForDataStore.add(id);\n }\n\n this.contexts.bind(id);\n }\n\n public createDetachedDataStoreCore(\n pkg: Readonly<string[]>,\n isRoot: boolean,\n id = uuid()): IFluidDataStoreContextDetached {\n assert(!id.includes(\"/\"), 0x30c /* Id cannot contain slashes */);\n\n const context = new LocalDetachedFluidDataStoreContext({\n id,\n pkg,\n runtime: this.runtime,\n storage: this.runtime.storage,\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n id,\n { type: CreateSummarizerNodeSource.Local },\n ),\n makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),\n snapshotTree: undefined,\n isRootDataStore: isRoot,\n });\n this.contexts.addUnbound(context);\n return context;\n }\n\n public _createFluidDataStoreContext(pkg: string[], id: string, props?: any) {\n assert(!id.includes(\"/\"), 0x30d /* Id cannot contain slashes */);\n const context = new LocalFluidDataStoreContext({\n id,\n pkg,\n runtime: this.runtime,\n storage: this.runtime.storage,\n scope: this.runtime.scope,\n createSummarizerNodeFn: this.getCreateChildSummarizerNodeFn(\n id,\n { type: CreateSummarizerNodeSource.Local },\n ),\n makeLocallyVisibleFn: () => this.makeDataStoreLocallyVisible(id),\n snapshotTree: undefined,\n isRootDataStore: false,\n createProps: props,\n });\n this.contexts.addUnbound(context);\n return context;\n }\n\n public get disposed() { return this.disposeOnce.evaluated; }\n public readonly dispose = () => this.disposeOnce.value;\n\n public resubmitDataStoreOp(content: any, localOpMetadata: unknown) {\n const envelope = content as IEnvelope;\n const context = this.contexts.get(envelope.address);\n assert(!!context, 0x160 /* \"There should be a store context for the op\" */);\n context.reSubmit(envelope.contents, localOpMetadata);\n }\n\n public rollbackDataStoreOp(content: any, localOpMetadata: unknown) {\n const envelope = content as IEnvelope;\n const context = this.contexts.get(envelope.address);\n assert(!!context, 0x2e8 /* \"There should be a store context for the op\" */);\n context.rollback(envelope.contents, localOpMetadata);\n }\n\n public async applyStashedOp(content: any): Promise<unknown> {\n const envelope = content as IEnvelope;\n const context = this.contexts.get(envelope.address);\n assert(!!context, 0x161 /* \"There should be a store context for the op\" */);\n return context.applyStashedOp(envelope.contents);\n }\n\n public async applyStashedAttachOp(message: IAttachMessage) {\n this.pendingAttach.set(message.id, message);\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n this.processAttachMessage({ contents: message } as ISequencedDocumentMessage, false);\n }\n\n public processFluidDataStoreOp(message: ISequencedDocumentMessage, local: boolean, localMessageMetadata: unknown) {\n const envelope = message.contents as IEnvelope;\n const transformed = { ...message, contents: envelope.contents };\n const context = this.contexts.get(envelope.address);\n assert(!!context, 0x162 /* \"There should be a store context for the op\" */);\n context.process(transformed, local, localMessageMetadata);\n\n // Notify that a GC node for the data store changed. This is used to detect if a deleted data store is\n // being used.\n this.gcNodeUpdated(\n `/${envelope.address}`,\n message.timestamp,\n context.isLoaded ? context.packagePath : undefined,\n );\n }\n\n public async getDataStore(id: string, wait: boolean): Promise<FluidDataStoreContext> {\n const context = await this.contexts.getBoundOrRemoted(id, wait);\n if (context === undefined) {\n // The requested data store does not exits. Throw a 404 response exception.\n const request = { url: id };\n throw responseToException(create404Response(request), request);\n }\n\n return context;\n }\n\n public processSignal(address: string, message: IInboundSignalMessage, local: boolean) {\n const context = this.contexts.get(address);\n if (!context) {\n // Attach message may not have been processed yet\n assert(!local, 0x163 /* \"Missing datastore for local signal\" */);\n this.logger.sendTelemetryEvent({\n eventName: \"SignalFluidDataStoreNotFound\",\n fluidDataStoreId: {\n value: address,\n tag: TelemetryDataTag.CodeArtifact,\n },\n });\n return;\n }\n\n context.processSignal(message, local);\n }\n\n public setConnectionState(connected: boolean, clientId?: string) {\n for (const [fluidDataStore, context] of this.contexts) {\n try {\n context.setConnectionState(connected, clientId);\n } catch (error) {\n this.logger.sendErrorEvent({\n eventName: \"SetConnectionStateError\",\n clientId,\n fluidDataStore,\n }, error);\n }\n }\n }\n\n public setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {\n const eventName = attachState === AttachState.Attaching ? \"attaching\" : \"attached\";\n for (const [, context] of this.contexts) {\n // Fire only for bounded stores.\n if (!this.contexts.isNotBound(context.id)) {\n context.emit(eventName);\n }\n }\n }\n\n public get size(): number {\n return this.contexts.size;\n }\n\n public async summarize(\n fullTree: boolean,\n trackState: boolean,\n telemetryContext?: ITelemetryContext,\n ): Promise<ISummaryTreeWithStats> {\n const summaryBuilder = new SummaryTreeBuilder();\n\n // Iterate over each store and ask it to snapshot\n await Promise.all(Array.from(this.contexts)\n .filter(([_, context]) => {\n // Summarizer works only with clients with no local changes!\n assert(context.attachState !== AttachState.Attaching,\n 0x165 /* \"Summarizer cannot work if client has local changes\" */);\n return context.attachState === AttachState.Attached;\n }).map(async ([contextId, context]) => {\n const contextSummary = await context.summarize(fullTree, trackState, telemetryContext);\n summaryBuilder.addWithStats(contextId, contextSummary);\n }));\n\n return summaryBuilder.getSummaryTree();\n }\n\n public createSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {\n const builder = new SummaryTreeBuilder();\n // Attaching graph of some stores can cause other stores to get bound too.\n // So keep taking summary until no new stores get bound.\n let notBoundContextsLength: number;\n do {\n const builderTree = builder.summary.tree;\n notBoundContextsLength = this.contexts.notBoundLength();\n // Iterate over each data store and ask it to snapshot\n Array.from(this.contexts)\n .filter(([key, _]) =>\n // Take summary of bounded data stores only, make sure we haven't summarized them already\n // and no attach op has been fired for that data store because for loader versions <= 0.24\n // we set attach state as \"attaching\" before taking createNew summary.\n !(this.contexts.isNotBound(key)\n || builderTree[key]\n || this.attachOpFiredForDataStore.has(key)),\n )\n .map(([key, value]) => {\n let dataStoreSummary: ISummarizeResult;\n if (value.isLoaded) {\n const snapshot = value.generateAttachMessage().snapshot;\n dataStoreSummary = convertToSummaryTree(snapshot, true);\n } else {\n // If this data store is not yet loaded, then there should be no changes in the snapshot from\n // which it was created as it is detached container. So just use the previous snapshot.\n assert(!!this.baseSnapshot,\n 0x166 /* \"BaseSnapshot should be there as detached container loaded from snapshot\" */);\n dataStoreSummary = convertSnapshotTreeToSummaryTree(this.baseSnapshot.trees[key]);\n }\n builder.addWithStats(key, dataStoreSummary);\n });\n } while (notBoundContextsLength !== this.contexts.notBoundLength());\n\n return builder.getSummaryTree();\n }\n\n /**\n * Before GC runs, called by the garbage collector to update any pending GC state.\n * The garbage collector needs to know all outbound references that are added. Since root data stores are not\n * explicitly marked as referenced, notify GC of new root data stores that were added since the last GC run.\n */\n public async updateStateBeforeGC(): Promise<void> {\n for (const id of this.dataStoresSinceLastGC) {\n const context = this.contexts.get(id);\n assert(context !== undefined, 0x2b6 /* Missing data store context */);\n if (await context.isRoot()) {\n // A root data store is basically a reference from the container runtime to the data store.\n const handle = new FluidObjectHandle(context, id, this.runtime.IFluidHandleContext);\n this.runtime.addedGCOutboundReference(this.containerRuntimeHandle, handle);\n }\n }\n this.dataStoresSinceLastGC = [];\n }\n\n /**\n * Generates data used for garbage collection. It does the following:\n *\n * 1. Calls into each child data store context to get its GC data.\n *\n * 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be\n * identified as belonging to the child.\n *\n * 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent\n * the GC data of this channel.\n *\n * @param fullGC - true to bypass optimizations and force full generation of GC data.\n */\n public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n const builder = new GCDataBuilder();\n // Iterate over each store and get their GC data.\n await Promise.all(Array.from(this.contexts)\n .filter(([_, context]) => {\n // Get GC data only for attached contexts. Detached contexts are not connected in the GC reference\n // graph so any references they might have won't be connected as well.\n return context.attachState === AttachState.Attached;\n }).map(async ([contextId, context]) => {\n const contextGCData = await context.getGCData(fullGC);\n // Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.\n // This also gradually builds the id of each node to be a path from the root.\n builder.prefixAndAddNodes(contextId, contextGCData.gcNodes);\n }));\n\n // Get the outbound routes and add a GC node for this channel.\n builder.addNode(\"/\", await this.getOutboundRoutes());\n return builder.getGCData();\n }\n\n /**\n * After GC has run, called to notify this Container's data stores of routes that are used in it.\n * @param usedRoutes - The routes that are used in all data stores in this Container.\n */\n public updateUsedRoutes(usedRoutes: string[]) {\n // Get a map of data store ids to routes used in it.\n const usedDataStoreRoutes = unpackChildNodesUsedRoutes(usedRoutes);\n\n // Verify that the used routes are correct.\n for (const [id] of usedDataStoreRoutes) {\n assert(this.contexts.has(id), 0x167 /* \"Used route does not belong to any known data store\" */);\n }\n\n // Update the used routes in each data store. Used routes is empty for unused data stores.\n for (const [contextId, context] of this.contexts) {\n context.updateUsedRoutes(usedDataStoreRoutes.get(contextId) ?? []);\n }\n }\n\n /**\n * When running GC in test mode, this is called to delete objects whose routes are unused. This enables testing\n * scenarios with accessing deleted content.\n * @param unusedRoutes - The routes that are unused in all data stores in this Container.\n */\n public deleteUnusedRoutes(unusedRoutes: string[]) {\n for (const route of unusedRoutes) {\n const pathParts = route.split(\"/\");\n // Delete data store only if its route (/datastoreId) is in unusedRoutes. We don't want to delete a data\n // store based on its DDS being unused.\n if (pathParts.length > 2) {\n continue;\n }\n const dataStoreId = pathParts[1];\n assert(this.contexts.has(dataStoreId), 0x2d7 /* No data store with specified id */);\n // Delete the contexts of unused data stores.\n this.contexts.delete(dataStoreId);\n // Delete the summarizer node of the unused data stores.\n this.deleteChildSummarizerNodeFn(dataStoreId);\n }\n }\n\n /**\n * Returns the outbound routes of this channel. Only root data stores are considered referenced and their paths are\n * part of outbound routes.\n */\n private async getOutboundRoutes(): Promise<string[]> {\n const outboundRoutes: string[] = [];\n for (const [contextId, context] of this.contexts) {\n const isRootDataStore = await context.isRoot();\n if (isRootDataStore) {\n outboundRoutes.push(`/${contextId}`);\n }\n }\n return outboundRoutes;\n }\n\n /**\n * Called by GC to retrieve the package path of a data store node with the given path.\n */\n public async getDataStorePackagePath(nodePath: string): Promise<readonly string[] | undefined> {\n // If the node belongs to a data store, return its package path. For DDSes, we return the package path of the\n // data store that contains it.\n const context = this.contexts.get(nodePath.split(\"/\")[1]);\n return (await context?.getInitialSnapshotDetails())?.pkg;\n }\n\n /**\n * Called by GC to determine if a node is for a data store or for an object within a data store (for e.g. DDS).\n * @returns the GC node type if the node belongs to a data store or object within data store, undefined otherwise.\n */\n public getGCNodeType(nodePath: string): GCNodeType | undefined {\n const pathParts = nodePath.split(\"/\");\n if (!this.contexts.has(pathParts[1])) {\n return undefined;\n }\n\n // Data stores paths are of the format \"/dataStoreId\".\n // Sub data store paths are of the format \"/dataStoreId/subPath/...\".\n if (pathParts.length === 2) {\n return GCNodeType.DataStore;\n }\n return GCNodeType.SubDataStore;\n }\n}\n\nexport function getSummaryForDatastores(\n snapshot: ISnapshotTree | undefined,\n metadata?: IContainerRuntimeMetadata,\n): ISnapshotTree | undefined {\n if (!snapshot) {\n return undefined;\n }\n\n if (rootHasIsolatedChannels(metadata)) {\n const datastoresSnapshot = snapshot.trees[channelsTreeName];\n assert(!!datastoresSnapshot, 0x168 /* Expected tree in snapshot not found */);\n return datastoresSnapshot;\n } else {\n // back-compat: strip out all non-datastore paths before giving to DataStores object.\n const datastoresTrees: ISnapshotTree[\"trees\"] = {};\n for (const [key, value] of Object.entries(snapshot.trees)) {\n if (!nonDataStorePaths.includes(key)) {\n datastoresTrees[key] = value;\n }\n }\n return {\n ...snapshot,\n trees: datastoresTrees,\n };\n }\n}\n"]}
|
|
@@ -16,7 +16,6 @@ export declare const runGCKey = "Fluid.GarbageCollection.RunGC";
|
|
|
16
16
|
export declare const runSweepKey = "Fluid.GarbageCollection.RunSweep";
|
|
17
17
|
export declare const gcTestModeKey = "Fluid.GarbageCollection.GCTestMode";
|
|
18
18
|
export declare const runSessionExpiryKey = "Fluid.GarbageCollection.RunSessionExpiry";
|
|
19
|
-
export declare const disableSessionExpiryKey = "Fluid.GarbageCollection.DisableSessionExpiry";
|
|
20
19
|
export declare const trackGCStateKey = "Fluid.GarbageCollection.TrackGCState";
|
|
21
20
|
export declare const disableSweepLogKey = "Fluid.GarbageCollection.DisableSweepLog";
|
|
22
21
|
export declare const oneDayMs: number;
|
|
@@ -58,7 +57,7 @@ export interface IGarbageCollectionRuntime {
|
|
|
58
57
|
/** Returns the garbage collection data of the runtime. */
|
|
59
58
|
getGCData(fullGC?: boolean): Promise<IGarbageCollectionData>;
|
|
60
59
|
/** After GC has run, called to notify the runtime of routes that are used in it. */
|
|
61
|
-
updateUsedRoutes(usedRoutes: string[]
|
|
60
|
+
updateUsedRoutes(usedRoutes: string[]): void;
|
|
62
61
|
/** After GC has run, called to delete objects in the runtime whose routes are unused. */
|
|
63
62
|
deleteUnusedRoutes(unusedRoutes: string[]): void;
|
|
64
63
|
/** Returns a referenced timestamp to be used to track unreferenced nodes. */
|
|
@@ -74,8 +73,6 @@ export interface IGarbageCollector {
|
|
|
74
73
|
readonly shouldRunGC: boolean;
|
|
75
74
|
/** Tells whether the GC state in summary needs to be reset in the next summary. */
|
|
76
75
|
readonly summaryStateNeedsReset: boolean;
|
|
77
|
-
/** Tells whether GC data should be written to the root of the summary tree. */
|
|
78
|
-
readonly writeDataAtRoot: boolean;
|
|
79
76
|
readonly trackGCState: boolean;
|
|
80
77
|
/** Run garbage collection and update the reference / used state of the system. */
|
|
81
78
|
collectGarbage(options: {
|
|
@@ -112,7 +109,6 @@ export interface IGarbageCollectorCreateParams {
|
|
|
112
109
|
readonly readAndParseBlob: ReadAndParseBlob;
|
|
113
110
|
readonly activeConnection: () => boolean;
|
|
114
111
|
readonly getContainerDiagnosticId: () => string;
|
|
115
|
-
readonly snapshotCacheExpiryMs?: number;
|
|
116
112
|
}
|
|
117
113
|
/** The state of node that is unreferenced. */
|
|
118
114
|
export declare const UnreferencedState: {
|
|
@@ -213,11 +209,6 @@ export declare class GarbageCollector implements IGarbageCollector {
|
|
|
213
209
|
readonly trackGCState: boolean;
|
|
214
210
|
private readonly testMode;
|
|
215
211
|
private readonly mc;
|
|
216
|
-
/**
|
|
217
|
-
* Tells whether the GC data should be written to the root of the summary tree.
|
|
218
|
-
*/
|
|
219
|
-
private _writeDataAtRoot;
|
|
220
|
-
get writeDataAtRoot(): boolean;
|
|
221
212
|
/**
|
|
222
213
|
* Tells whether the initial GC state needs to be reset. This can happen under 2 conditions:
|
|
223
214
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../src/garbageCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAA8B,MAAM,oCAAoC,CAAC;AAElG,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,EAEH,sBAAsB,EAEtB,6BAA6B,EAC7B,gBAAgB,EAChB,iBAAiB,EAEpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAEH,gBAAgB,EAChB,oBAAoB,EAEvB,MAAM,+BAA+B,CAAC;AASvC,OAAO,EAAE,iBAAiB,EAAkB,MAAM,oBAAoB,CAAC;AAGvE,OAAO,EAGH,yBAAyB,EAIzB,WAAW,EACd,MAAM,iBAAiB,CAAC;AAMzB,eAAO,MAAM,SAAS,OAAO,CAAC;AAE9B,eAAO,MAAM,YAAY,SAAS,CAAC;AAGnC,eAAO,MAAM,QAAQ,kCAAkC,CAAC;AAExD,eAAO,MAAM,WAAW,qCAAqC,CAAC;AAE9D,eAAO,MAAM,aAAa,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../src/garbageCollection.ts"],"names":[],"mappings":"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"}
|
package/lib/garbageCollection.js
CHANGED
|
@@ -36,12 +36,8 @@ export const runGCKey = "Fluid.GarbageCollection.RunGC";
|
|
|
36
36
|
export const runSweepKey = "Fluid.GarbageCollection.RunSweep";
|
|
37
37
|
// Feature gate key to turn GC test mode on / off.
|
|
38
38
|
export const gcTestModeKey = "Fluid.GarbageCollection.GCTestMode";
|
|
39
|
-
// Feature gate key to write GC data at the root of the summary tree.
|
|
40
|
-
const writeAtRootKey = "Fluid.GarbageCollection.WriteDataAtRoot";
|
|
41
39
|
// Feature gate key to expire a session after a set period of time.
|
|
42
40
|
export const runSessionExpiryKey = "Fluid.GarbageCollection.RunSessionExpiry";
|
|
43
|
-
// Feature gate key to disable expiring session after a set period of time, even if expiry value is present.
|
|
44
|
-
export const disableSessionExpiryKey = "Fluid.GarbageCollection.DisableSessionExpiry";
|
|
45
41
|
// Feature gate key to write the gc blob as a handle if the data is the same.
|
|
46
42
|
export const trackGCStateKey = "Fluid.GarbageCollection.TrackGCState";
|
|
47
43
|
// Feature gate key to turn GC sweep log off.
|
|
@@ -162,10 +158,6 @@ export class UnreferencedStateTracker {
|
|
|
162
158
|
export class GarbageCollector {
|
|
163
159
|
constructor(createParams) {
|
|
164
160
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
165
|
-
/**
|
|
166
|
-
* Tells whether the GC data should be written to the root of the summary tree.
|
|
167
|
-
*/
|
|
168
|
-
this._writeDataAtRoot = true;
|
|
169
161
|
/**
|
|
170
162
|
* Tells whether the initial GC state needs to be reset. This can happen under 2 conditions:
|
|
171
163
|
*
|
|
@@ -205,6 +197,20 @@ export class GarbageCollector {
|
|
|
205
197
|
this.mc = loggerToMonitoringContext(ChildLogger.create(createParams.baseLogger, "GarbageCollector", { all: { completedGCRuns: () => this.completedRuns } }));
|
|
206
198
|
this.sweepReadyUsageHandler = new SweepReadyUsageDetectionHandler(createParams.getContainerDiagnosticId(), this.mc, this.runtime.closeFn);
|
|
207
199
|
let prevSummaryGCVersion;
|
|
200
|
+
/**
|
|
201
|
+
* Sweep timeout is the time after which unreferenced content can be swept.
|
|
202
|
+
* Sweep timeout = session expiry timeout + snapshot cache expiry timeout + one day buffer.
|
|
203
|
+
*
|
|
204
|
+
* The snapshot cache expiry timeout cannot be known precisely but the upper bound is 5 days.
|
|
205
|
+
* The buffer is added to account for any clock skew or other edge cases.
|
|
206
|
+
* We use server timestamps throughout so the skew should be minimal but make it 1 day to be safe.
|
|
207
|
+
*/
|
|
208
|
+
function computeSweepTimeout(sessionExpiryTimeoutMs) {
|
|
209
|
+
const maxSnapshotCacheExpiryMs = 5 * oneDayMs;
|
|
210
|
+
const bufferMs = oneDayMs;
|
|
211
|
+
return sessionExpiryTimeoutMs &&
|
|
212
|
+
(sessionExpiryTimeoutMs + maxSnapshotCacheExpiryMs + bufferMs);
|
|
213
|
+
}
|
|
208
214
|
/**
|
|
209
215
|
* The following GC state is enabled during container creation and cannot be changed throughout its lifetime:
|
|
210
216
|
* 1. Whether running GC mark phase is allowed or not.
|
|
@@ -219,6 +225,8 @@ export class GarbageCollector {
|
|
|
219
225
|
this.gcEnabled = prevSummaryGCVersion > 0;
|
|
220
226
|
this.sweepEnabled = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.sweepEnabled) !== null && _a !== void 0 ? _a : false;
|
|
221
227
|
this.sessionExpiryTimeoutMs = metadata === null || metadata === void 0 ? void 0 : metadata.sessionExpiryTimeoutMs;
|
|
228
|
+
this.sweepTimeoutMs =
|
|
229
|
+
(_b = metadata === null || metadata === void 0 ? void 0 : metadata.sweepTimeoutMs) !== null && _b !== void 0 ? _b : computeSweepTimeout(this.sessionExpiryTimeoutMs); // Backfill old documents that didn't persist this
|
|
222
230
|
}
|
|
223
231
|
else {
|
|
224
232
|
// Sweep should not be enabled without enabling GC mark phase. We could silently disable sweep in this
|
|
@@ -226,36 +234,28 @@ export class GarbageCollector {
|
|
|
226
234
|
if (this.gcOptions.sweepAllowed && this.gcOptions.gcAllowed === false) {
|
|
227
235
|
throw new UsageError("GC sweep phase cannot be enabled without enabling GC mark phase");
|
|
228
236
|
}
|
|
237
|
+
// This Test Override only applies for new containers
|
|
238
|
+
const testOverrideSweepTimeoutMs = this.mc.config.getNumber("Fluid.GarbageCollection.TestOverride.SweepTimeoutMs");
|
|
229
239
|
// For new documents, GC is enabled by default. It can be explicitly disabled by setting the gcAllowed
|
|
230
240
|
// flag in GC options to false.
|
|
231
241
|
this.gcEnabled = this.gcOptions.gcAllowed !== false;
|
|
232
242
|
// The sweep phase has to be explicitly enabled by setting the sweepAllowed flag in GC options to true.
|
|
233
|
-
|
|
243
|
+
// ...unless we're using the TestOverride
|
|
244
|
+
this.sweepEnabled = this.gcOptions.sweepAllowed === true || testOverrideSweepTimeoutMs !== undefined;
|
|
234
245
|
// Set the Session Expiry only if the flag is enabled and GC is enabled.
|
|
235
246
|
if (this.mc.config.getBoolean(runSessionExpiryKey) && this.gcEnabled) {
|
|
236
|
-
this.sessionExpiryTimeoutMs = (
|
|
247
|
+
this.sessionExpiryTimeoutMs = (_c = this.gcOptions.sessionExpiryTimeoutMs) !== null && _c !== void 0 ? _c : defaultSessionExpiryDurationMs;
|
|
237
248
|
}
|
|
249
|
+
this.sweepTimeoutMs =
|
|
250
|
+
testOverrideSweepTimeoutMs !== null && testOverrideSweepTimeoutMs !== void 0 ? testOverrideSweepTimeoutMs : computeSweepTimeout(this.sessionExpiryTimeoutMs);
|
|
238
251
|
}
|
|
239
252
|
// If session expiry is enabled, we need to close the container when the session expiry timeout expires.
|
|
240
|
-
if (this.sessionExpiryTimeoutMs !== undefined
|
|
253
|
+
if (this.sessionExpiryTimeoutMs !== undefined) {
|
|
241
254
|
// If Test Override config is set, override Session Expiry timeout.
|
|
242
255
|
const overrideSessionExpiryTimeoutMs = this.mc.config.getNumber("Fluid.GarbageCollection.TestOverride.SessionExpiryMs");
|
|
243
256
|
const timeoutMs = overrideSessionExpiryTimeoutMs !== null && overrideSessionExpiryTimeoutMs !== void 0 ? overrideSessionExpiryTimeoutMs : this.sessionExpiryTimeoutMs;
|
|
244
257
|
this.sessionExpiryTimer = new Timer(timeoutMs, () => { this.runtime.closeFn(new ClientSessionExpiredError(`Client session expired.`, timeoutMs)); });
|
|
245
258
|
this.sessionExpiryTimer.start();
|
|
246
|
-
// TEMPORARY: Hardcode a default of 5 days which will be >= the policy's value in the ODSP driver.
|
|
247
|
-
// This unblocks the Sweep Log (see logSweepEvents function).
|
|
248
|
-
// This will be removed before sweep is fully implemented.
|
|
249
|
-
const snapshotCacheExpiryMs = (_c = createParams.snapshotCacheExpiryMs) !== null && _c !== void 0 ? _c : 5 * 24 * 60 * 60 * 1000;
|
|
250
|
-
/**
|
|
251
|
-
* Sweep timeout is the time after which unreferenced content can be swept.
|
|
252
|
-
* Sweep timeout = session expiry timeout + snapshot cache expiry timeout + one day buffer. The buffer is
|
|
253
|
-
* added to account for any clock skew. We use server timestamps throughout so the skew should be minimal
|
|
254
|
-
* but make it one day to be safe.
|
|
255
|
-
*/
|
|
256
|
-
if (snapshotCacheExpiryMs !== undefined) {
|
|
257
|
-
this.sweepTimeoutMs = this.sessionExpiryTimeoutMs + snapshotCacheExpiryMs + oneDayMs;
|
|
258
|
-
}
|
|
259
259
|
}
|
|
260
260
|
// For existing document, the latest summary is the one that we loaded from. So, use its GC version as the
|
|
261
261
|
// latest tracked GC version. For new documents, we will be writing the first summary with the current version.
|
|
@@ -278,33 +278,29 @@ export class GarbageCollector {
|
|
|
278
278
|
* Whether sweep should run or not. The following conditions have to be met to run sweep:
|
|
279
279
|
*
|
|
280
280
|
* 1. Overall GC or mark phase must be enabled (this.shouldRunGC).
|
|
281
|
-
*
|
|
282
281
|
* 2. Sweep timeout should be available. Without this, we wouldn't know when an object should be deleted.
|
|
283
|
-
*
|
|
284
|
-
*
|
|
282
|
+
* 3. The driver must implement the policy limiting the age of snapshots used for loading. Otherwise
|
|
283
|
+
* the Sweep Timeout calculation is not valid. We use the persisted value to ensure consistency over time.
|
|
284
|
+
* 4. Sweep should be enabled for this container (this.sweepEnabled). This can be overridden via runSweep
|
|
285
285
|
* feature flag.
|
|
286
286
|
*/
|
|
287
|
-
this.shouldRunSweep =
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
this.shouldRunSweep =
|
|
288
|
+
this.shouldRunGC
|
|
289
|
+
&& this.sweepTimeoutMs !== undefined
|
|
290
|
+
&& ((_e = this.mc.config.getBoolean(runSweepKey)) !== null && _e !== void 0 ? _e : this.sweepEnabled);
|
|
291
291
|
this.trackGCState = this.mc.config.getBoolean(trackGCStateKey) === true;
|
|
292
292
|
// Override inactive timeout if test config or gc options to override it is set.
|
|
293
|
-
this.inactiveTimeoutMs = (
|
|
293
|
+
this.inactiveTimeoutMs = (_g = (_f = this.mc.config.getNumber("Fluid.GarbageCollection.TestOverride.InactiveTimeoutMs")) !== null && _f !== void 0 ? _f : this.gcOptions.inactiveTimeoutMs) !== null && _g !== void 0 ? _g : defaultInactiveTimeoutMs;
|
|
294
294
|
// Inactive timeout must be greater than sweep timeout since a node goes from active -> inactive -> sweep ready.
|
|
295
295
|
if (this.sweepTimeoutMs !== undefined && this.inactiveTimeoutMs > this.sweepTimeoutMs) {
|
|
296
296
|
throw new UsageError("inactive timeout should not be greater than the sweep timeout");
|
|
297
297
|
}
|
|
298
298
|
// Whether we are running in test mode. In this mode, unreferenced nodes are immediately deleted.
|
|
299
|
-
this.testMode = (
|
|
300
|
-
// GC state
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
// contain GC tree and GC is enabled.
|
|
305
|
-
const gcTreePresent = (baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.trees[gcTreeKey]) !== undefined;
|
|
306
|
-
this.initialStateNeedsReset = gcTreePresent !== this.shouldRunGC;
|
|
307
|
-
}
|
|
299
|
+
this.testMode = (_h = this.mc.config.getBoolean(gcTestModeKey)) !== null && _h !== void 0 ? _h : this.gcOptions.runGCInTestMode === true;
|
|
300
|
+
// The GC state needs to be reset if the base snapshot contains GC tree and GC is disabled or it doesn't
|
|
301
|
+
// contain GC tree and GC is enabled.
|
|
302
|
+
const gcTreePresent = (baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.trees[gcTreeKey]) !== undefined;
|
|
303
|
+
this.initialStateNeedsReset = gcTreePresent !== this.shouldRunGC;
|
|
308
304
|
// Get the GC state from the GC blob in the base snapshot. Use LazyPromise because we only want to do
|
|
309
305
|
// this once since it involves fetching blobs from storage which is expensive.
|
|
310
306
|
const baseSummaryStateP = new LazyPromise(async () => {
|
|
@@ -316,8 +312,6 @@ export class GarbageCollector {
|
|
|
316
312
|
// For newer documents, GC data should be present in the GC tree in the root of the snapshot.
|
|
317
313
|
const gcSnapshotTree = baseSnapshot.trees[gcTreeKey];
|
|
318
314
|
if (gcSnapshotTree !== undefined) {
|
|
319
|
-
// If the GC tree is written at root, we should also do the same.
|
|
320
|
-
this._writeDataAtRoot = true;
|
|
321
315
|
const baseGCState = await getGCStateFromSnapshot(gcSnapshotTree, readAndParseBlob);
|
|
322
316
|
if (this.trackGCState) {
|
|
323
317
|
this.latestSerializedSummaryState = JSON.stringify(generateSortedGCState(baseGCState));
|
|
@@ -465,12 +459,9 @@ export class GarbageCollector {
|
|
|
465
459
|
return this.initialStateNeedsReset ||
|
|
466
460
|
(this.shouldRunGC && this.latestSummaryGCVersion !== this.currentGCVersion);
|
|
467
461
|
}
|
|
468
|
-
get writeDataAtRoot() {
|
|
469
|
-
return this._writeDataAtRoot;
|
|
470
|
-
}
|
|
471
462
|
/** Returns a list of all the configurations for garbage collection. */
|
|
472
463
|
get configs() {
|
|
473
|
-
return Object.assign({ gcEnabled: this.gcEnabled, sweepEnabled: this.sweepEnabled, runGC: this.shouldRunGC, runSweep: this.shouldRunSweep,
|
|
464
|
+
return Object.assign({ gcEnabled: this.gcEnabled, sweepEnabled: this.sweepEnabled, runGC: this.shouldRunGC, runSweep: this.shouldRunSweep, testMode: this.testMode, sessionExpiry: this.sessionExpiryTimeoutMs, sweepTimeout: this.sweepTimeoutMs, inactiveTimeout: this.inactiveTimeoutMs, trackGCState: this.trackGCState }, this.gcOptions);
|
|
474
465
|
}
|
|
475
466
|
/**
|
|
476
467
|
* Called when the connection state of the runtime changes, i.e., it connects or disconnects. GC subscribes to this
|
|
@@ -525,7 +516,7 @@ export class GarbageCollector {
|
|
|
525
516
|
const gcData = await this.runtime.getGCData(fullGC);
|
|
526
517
|
const gcResult = runGarbageCollection(gcData.gcNodes, ["/"]);
|
|
527
518
|
const gcStats = await this.runPostGCSteps(gcData, gcResult, logger, currentReferenceTimestampMs);
|
|
528
|
-
event.end(Object.assign({}, gcStats));
|
|
519
|
+
event.end(Object.assign(Object.assign({}, gcStats), { timestamp: currentReferenceTimestampMs }));
|
|
529
520
|
this.completedRuns++;
|
|
530
521
|
return gcStats;
|
|
531
522
|
}, { end: true, cancel: "error" });
|
|
@@ -545,7 +536,7 @@ export class GarbageCollector {
|
|
|
545
536
|
this.updateStateSinceLastRun(gcData, logger);
|
|
546
537
|
// Update the current state and update the runtime of all routes or ids that used as per the GC run.
|
|
547
538
|
this.updateCurrentState(gcData, gcResult, currentReferenceTimestampMs);
|
|
548
|
-
this.runtime.updateUsedRoutes(gcResult.referencedNodeIds
|
|
539
|
+
this.runtime.updateUsedRoutes(gcResult.referencedNodeIds);
|
|
549
540
|
// Log events for objects that are ready to be deleted by sweep. When we have sweep enabled, we will
|
|
550
541
|
// delete these objects here instead.
|
|
551
542
|
this.logSweepEvents(logger, currentReferenceTimestampMs);
|
|
@@ -613,6 +604,7 @@ export class GarbageCollector {
|
|
|
613
604
|
gcFeature: this.gcEnabled ? this.currentGCVersion : 0,
|
|
614
605
|
sessionExpiryTimeoutMs: this.sessionExpiryTimeoutMs,
|
|
615
606
|
sweepEnabled: this.sweepEnabled,
|
|
607
|
+
sweepTimeoutMs: this.sweepTimeoutMs,
|
|
616
608
|
};
|
|
617
609
|
}
|
|
618
610
|
/**
|
|
@@ -753,7 +745,7 @@ export class GarbageCollector {
|
|
|
753
745
|
}
|
|
754
746
|
// Find any references that haven't been identified correctly.
|
|
755
747
|
const missingExplicitReferences = this.findMissingExplicitReferences(currentGCData, this.previousGCDataFromLastRun, this.newReferencesSinceLastRun);
|
|
756
|
-
if (
|
|
748
|
+
if (missingExplicitReferences.length > 0) {
|
|
757
749
|
missingExplicitReferences.forEach((missingExplicitReference) => {
|
|
758
750
|
const event = {
|
|
759
751
|
eventName: "gcUnknownOutboundReferences",
|