@fluidframework/container-runtime 0.57.0-51086 → 0.57.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.
Files changed (46) hide show
  1. package/dist/containerRuntime.d.ts +2 -2
  2. package/dist/containerRuntime.d.ts.map +1 -1
  3. package/dist/containerRuntime.js +12 -20
  4. package/dist/containerRuntime.js.map +1 -1
  5. package/dist/dataStoreContext.d.ts +4 -0
  6. package/dist/dataStoreContext.d.ts.map +1 -1
  7. package/dist/dataStoreContext.js +1 -0
  8. package/dist/dataStoreContext.js.map +1 -1
  9. package/dist/dataStores.d.ts +1 -1
  10. package/dist/dataStores.d.ts.map +1 -1
  11. package/dist/dataStores.js +2 -2
  12. package/dist/dataStores.js.map +1 -1
  13. package/dist/garbageCollection.d.ts +24 -11
  14. package/dist/garbageCollection.d.ts.map +1 -1
  15. package/dist/garbageCollection.js +94 -53
  16. package/dist/garbageCollection.js.map +1 -1
  17. package/dist/packageVersion.d.ts +1 -1
  18. package/dist/packageVersion.d.ts.map +1 -1
  19. package/dist/packageVersion.js +1 -1
  20. package/dist/packageVersion.js.map +1 -1
  21. package/lib/containerRuntime.d.ts +2 -2
  22. package/lib/containerRuntime.d.ts.map +1 -1
  23. package/lib/containerRuntime.js +12 -20
  24. package/lib/containerRuntime.js.map +1 -1
  25. package/lib/dataStoreContext.d.ts +4 -0
  26. package/lib/dataStoreContext.d.ts.map +1 -1
  27. package/lib/dataStoreContext.js +1 -0
  28. package/lib/dataStoreContext.js.map +1 -1
  29. package/lib/dataStores.d.ts +1 -1
  30. package/lib/dataStores.d.ts.map +1 -1
  31. package/lib/dataStores.js +2 -2
  32. package/lib/dataStores.js.map +1 -1
  33. package/lib/garbageCollection.d.ts +24 -11
  34. package/lib/garbageCollection.d.ts.map +1 -1
  35. package/lib/garbageCollection.js +94 -53
  36. package/lib/garbageCollection.js.map +1 -1
  37. package/lib/packageVersion.d.ts +1 -1
  38. package/lib/packageVersion.d.ts.map +1 -1
  39. package/lib/packageVersion.js +1 -1
  40. package/lib/packageVersion.js.map +1 -1
  41. package/package.json +13 -13
  42. package/src/containerRuntime.ts +29 -25
  43. package/src/dataStoreContext.ts +5 -0
  44. package/src/dataStores.ts +8 -3
  45. package/src/garbageCollection.ts +114 -57
  46. package/src/packageVersion.ts +1 -1
@@ -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 channelsTreeName,\n CreateChildSummarizerNodeFn,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n IAttachMessage,\n IEnvelope,\n IFluidDataStoreChannel,\n IFluidDataStoreContextDetached,\n IGarbageCollectionData,\n IGarbageCollectionDetailsBase,\n IInboundSignalMessage,\n InboundAttachMessage,\n ISummarizeResult,\n ISummaryTreeWithStats,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n convertSnapshotTreeToSummaryTree,\n convertToSummaryTree,\n create404Response,\n responseToException,\n SummaryTreeBuilder,\n} from \"@fluidframework/runtime-utils\";\nimport { ChildLogger, 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\";\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\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 dataStoreChanged: (dataStorePath: string, 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 disableIsolatedChannels: this.runtime.disableIsolatedChannels,\n });\n } else {\n if (typeof value !== \"object\") {\n throw new Error(\"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 bindChannelFn: (cr: IFluidDataStoreChannel) => this.bindFluidDataStore(cr),\n snapshotTree,\n isRootDataStore: undefined,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n disableIsolatedChannels: this.runtime.disableIsolatedChannels,\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 aliases(): ReadonlyMap<string, string> {\n return this.aliasMap;\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 \"duplicateDataStoreCreatedWithExistingId\",\n {\n ...extractSafePropertiesFromMessage(message),\n dataStoreId: {\n value: attachMessage.id,\n tag: TelemetryDataTag.PackageData,\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 this.runtime.disableIsolatedChannels,\n )],\n },\n },\n ),\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n disableIsolatedChannels: this.runtime.disableIsolatedChannels,\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 currentContext = this.contexts.get(aliasMessage.internalId);\n if (currentContext === undefined) {\n this.logger.sendErrorEvent({\n eventName: \"AliasFluidDataStoreNotFound\",\n fluidDataStoreId: aliasMessage.internalId,\n });\n return false;\n }\n\n this.aliasMap.set(aliasMessage.alias, currentContext.id);\n currentContext.setRoot();\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 public bindFluidDataStore(fluidDataStoreRuntime: IFluidDataStoreChannel): void {\n const id = fluidDataStoreRuntime.id;\n const localContext = this.contexts.getUnbound(id);\n assert(!!localContext, 0x15f /* \"Could not find unbound context to bind\" */);\n\n // If the container is detached, we don't need to send OP or add to pending attach because\n // we will summarize it while uploading the create new summary and make it known to other\n // clients.\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(fluidDataStoreRuntime.id);\n }\n\n public createDetachedDataStoreCore(\n pkg: Readonly<string[]>,\n isRoot: boolean,\n id = uuid()): IFluidDataStoreContextDetached\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 bindChannelFn: (cr: IFluidDataStoreChannel) => this.bindFluidDataStore(cr),\n snapshotTree: undefined,\n isRootDataStore: isRoot,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n disableIsolatedChannels: this.runtime.disableIsolatedChannels,\n });\n this.contexts.addUnbound(context);\n return context;\n }\n\n public _createFluidDataStoreContext(pkg: string[], id: string, isRoot: boolean, props?: any) {\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 bindChannelFn: (cr: IFluidDataStoreChannel) => this.bindFluidDataStore(cr),\n snapshotTree: undefined,\n isRootDataStore: isRoot,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n disableIsolatedChannels: this.runtime.disableIsolatedChannels,\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 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 data store changed. This is used to detect if a deleted data store is being used.\n this.dataStoreChanged(`/${envelope.address}`, context.isLoaded ? context.packagePath : undefined);\n }\n\n public async getDataStore(id: string, wait: boolean): Promise<FluidDataStoreContext> {\n const internalId = this.aliasMap.get(id) ?? id;\n\n const context = await this.contexts.getBoundOrRemoted(internalId, 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: address,\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 let eventName: \"attaching\" | \"attached\";\n if (attachState === AttachState.Attaching) {\n eventName = \"attaching\";\n } else {\n eventName = \"attached\";\n }\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(fullTree: boolean, trackState: boolean): 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);\n summaryBuilder.addWithStats(contextId, contextSummary);\n }));\n\n return summaryBuilder.getSummaryTree();\n }\n\n public createSummary(): 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 with id ${id}` */);\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 * 1. Calls into each child data store context to get its GC data.\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 * 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 * @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 dataStoreId = route.split(\"/\")[1];\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 * Returns the package path of the node with the given path. This is used by GC to log when an inactive / deleted\n * node is used.\n */\n public getNodePackagePath(nodePath: string): readonly string[] | undefined {\n // Currently, only return the data store package path for the node since GC is only interested in data stores.\n const dataStoreId = nodePath.split(\"/\")[1];\n const context = this.contexts.get(dataStoreId);\n assert(context !== undefined, \"Data store with given id does not exist\");\n return context.isLoaded ? context.packagePath : undefined;\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 ${channelsTreeName} tree in snapshot` */);\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":";AAAA;;;GAGG;;;AAGH,qEAAwG;AAExG,yDAA8D;AAK9D,6EAe6C;AAC7C,iEAMuC;AACvC,qEAAgF;AAChF,iFAAoE;AACpE,+DAA0F;AAC1F,+DAAyE;AACzE,+BAAkC;AAClC,yEAA8F;AAC9F,2DAAwD;AAExD,yDAM4B;AAC5B,mDAAwG;AACxG,2CAA8E;AAI7E;;;GAGG;AACJ,MAAa,UAAU;IAwBnB,YACqB,YAAuC,EACvC,OAAyB,EACzB,cAA4C,EAC5C,8BAC2E,EAC3E,2BAAiD,EAClE,UAAgC,EAChC,gBAA2E,EAC1D,gBACuE,EACvE,QAA6B,EAC7B,iBAA0B,EAC1B,WAA8B,IAAI,qCAAiB,CAAC,UAAU,CAAC;QAZ/D,iBAAY,GAAZ,YAAY,CAA2B;QACvC,YAAO,GAAP,OAAO,CAAkB;QACzB,mBAAc,GAAd,cAAc,CAA8B;QAC5C,mCAA8B,GAA9B,8BAA8B,CAC6C;QAC3E,gCAA2B,GAA3B,2BAA2B,CAAsB;QAGjD,qBAAgB,GAAhB,gBAAgB,CACuD;QACvE,aAAQ,GAAR,QAAQ,CAAqB;QAC7B,sBAAiB,GAAjB,iBAAiB,CAAS;QAC1B,aAAQ,GAAR,QAAQ,CAAuD;QApCpF,+BAA+B;QACd,kBAAa,GAAG,IAAI,GAAG,EAA0B,CAAC;QACnE,0CAA0C;QAC1B,8BAAyB,GAAG,IAAI,GAAG,EAAU,CAAC;QAI7C,gBAAW,GAAG,IAAI,mBAAI,CAAO,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAS7E,6GAA6G;QAC7G,mCAAmC;QAC3B,0BAAqB,GAAa,EAAE,CAAC;QAyR7B,YAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;QArQnD,IAAI,CAAC,MAAM,GAAG,6BAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,sBAAsB,GAAG,IAAI,6BAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAEzG,MAAM,cAAc,GAAG,IAAI,0BAAW,CAAC,KAAK,IAAI,EAAE;YAC9C,OAAO,gBAAgB,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,oEAAoE;QACpE,MAAM,sBAAsB,GAAG,KAAK,EAAE,WAAmB,EAAE,EAAE;YACzD,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC;YAC3C,OAAO,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC,CAAC;QAEF,4CAA4C;QAC5C,MAAM,eAAe,GAAG,IAAI,GAAG,EAAyB,CAAC;QACzD,IAAI,YAAY,EAAE;YACd,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;gBAC3D,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;aACnC;SACJ;QAED,IAAI,0BAA0B,GAAG,CAAC,CAAC;QACnC,oCAAoC;QACpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,eAAe,EAAE;YACxC,IAAI,gBAAuC,CAAC;YAE5C,8CAA8C;YAC9C,IAAI,KAAK,CAAC,YAAY,EAAE;gBACpB,0BAA0B,EAAE,CAAC;aAChC;YACD,0EAA0E;YAC1E,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,mCAAW,CAAC,QAAQ,EAAE;gBACnD,gBAAgB,GAAG,IAAI,8CAA2B,CAAC;oBAC/C,EAAE,EAAE,GAAG;oBACP,YAAY,EAAE,KAAK;oBACnB,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,sBAAsB,CAAC,GAAG,CAAC;oBACzD,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;oBAC7B,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;oBACzB,sBAAsB,EAAE,IAAI,CAAC,8BAA8B,CACvD,GAAG,EACH,EAAE,IAAI,EAAE,gDAA0B,CAAC,WAAW,EAAE,CACnD;oBACD,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;oBACzC,uBAAuB,EAAE,IAAI,CAAC,OAAO,CAAC,uBAAuB;iBAChE,CAAC,CAAC;aACN;iBAAM;gBACH,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;oBAC3B,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;iBAC9D;gBACD,MAAM,YAAY,GAAG,KAAK,CAAC;gBAC3B,gBAAgB,GAAG,IAAI,6CAA0B,CAAC;oBAC9C,EAAE,EAAE,GAAG;oBACP,GAAG,EAAE,SAAS;oBACd,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;oBAC7B,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;oBACzB,sBAAsB,EAAE,IAAI,CAAC,8BAA8B,CACvD,GAAG,EACH,EAAE,IAAI,EAAE,gDAA0B,CAAC,WAAW,EAAE,CACnD;oBACD,aAAa,EAAE,CAAC,EAA0B,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;oBAC1E,YAAY;oBACZ,eAAe,EAAE,SAAS;oBAC1B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;oBACzC,uBAAuB,EAAE,IAAI,CAAC,OAAO,CAAC,uBAAuB;iBAChE,CAAC,CAAC;aACN;YACD,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;SACrD;QACD,IAAI,CAAC,kBAAkB,GAAG;YACtB,2BAA2B,EAAE,eAAe,CAAC,IAAI;YACjD,wBAAwB,EAAE,eAAe,CAAC,IAAI,GAAG,0BAA0B;SAC9E,CAAC;IACN,CAAC;IAEM,OAAO;QACV,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAEM,oBAAoB,CAAC,OAAkC,EAAE,KAAc;;QAC1E,MAAM,aAAa,GAAG,OAAO,CAAC,QAAgC,CAAC;QAE/D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAElD,6CAA6C;QAC7C,IAAI,KAAK,EAAE;YACP,qBAAM,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,EAC3C,KAAK,CAAC,6DAA6D,CAAC,CAAC;YACzE,MAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC,0CAAE,IAAI,CAAC,UAAU,EAAE;YACtD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAC5C,OAAO;SACV;QAEA,oGAAoG;QACrG,IAAI,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE;YACzC,uEAAuE;YACvE,MAAM,KAAK,GAAG,IAAI,qCAAmB,CACjC,yCAAyC,kCAElC,kDAAgC,CAAC,OAAO,CAAC,KAC5C,WAAW,EAAE;oBACT,KAAK,EAAE,aAAa,CAAC,EAAE;oBACvB,GAAG,EAAE,kCAAgB,CAAC,WAAW;iBACpC,IAER,CAAC;YACF,MAAM,KAAK,CAAC;SACf;QAED,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;QACrD,IAAI,YAAuC,CAAC;QAC5C,IAAI,aAAa,CAAC,QAAQ,EAAE;YACxB,YAAY,GAAG,gCAAiB,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;SAC/E;QAED,yEAAyE;QACzE,yEAAyE;QACzE,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,2BAA2B,GAAG,IAAI,8CAA2B,CAAC;YAChE,EAAE,EAAE,aAAa,CAAC,EAAE;YACpB,YAAY;YACZ,+EAA+E;YAC/E,gBAAgB,EAAE,KAAK,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5C,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,sCAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC;YACrE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;YACzB,sBAAsB,EAAE,IAAI,CAAC,8BAA8B,CACvD,aAAa,CAAC,EAAE,EAChB;gBACI,IAAI,EAAE,gDAA0B,CAAC,UAAU;gBAC3C,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,QAAQ,QAAE,aAAa,CAAC,QAAQ,mCAAI;oBAChC,OAAO,EAAE,CAAC,uCAAoB,CAC1B,GAAG,EACH,IAAI,CAAC,qBAAqB,EAC1B,IAAI,CAAC,OAAO,CAAC,uBAAuB,CACvC,CAAC;iBACL;aACJ,CACJ;YACD,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,uBAAuB,EAAE,IAAI,CAAC,OAAO,CAAC,uBAAuB;YAC7D,GAAG;SACN,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,2BAA2B,CAAC,CAAC;IACjE,CAAC;IAEM,mBAAmB,CACtB,OAAkC,EAClC,eAAwB,EACxB,KAAc;QAEd,MAAM,YAAY,GAAG,OAAO,CAAC,QAAkC,CAAC;QAChE,IAAI,CAAC,mCAAuB,CAAC,YAAY,CAAC,EAAE;YACxC,MAAM,IAAI,qCAAmB,CACzB,gCAAgC,oBAEzB,kDAAgC,CAAC,OAAO,CAAC,EAEnD,CAAC;SACL;QAED,MAAM,OAAO,GAAG,eAAsC,CAAC;QACvD,MAAM,WAAW,GAAG,IAAI,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;QAC/D,IAAI,KAAK,EAAE;YACP,OAAO,CAAC,WAAW,CAAC,CAAC;SACxB;IACL,CAAC;IAEM,uBAAuB,CAAC,YAAoC;QAC/D,IAAI,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE;YAC3C,OAAO,KAAK,CAAC;SAChB;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QAClE,IAAI,cAAc,KAAK,SAAS,EAAE;YAC9B,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;gBACvB,SAAS,EAAE,6BAA6B;gBACxC,gBAAgB,EAAE,YAAY,CAAC,UAAU;aAC5C,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;SAChB;QAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;QACzD,cAAc,CAAC,OAAO,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,gBAAgB,CAAC,EAAU;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC;IACtF,CAAC;IAEM,kBAAkB,CAAC,qBAA6C;QACnE,MAAM,EAAE,GAAG,qBAAqB,CAAC,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClD,qBAAM,CAAC,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAE7E,0FAA0F;QAC1F,yFAAyF;QACzF,WAAW;QACX,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,mCAAW,CAAC,QAAQ,EAAE;YACnD,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC/B,MAAM,OAAO,GAAG,YAAY,CAAC,qBAAqB,EAAE,CAAC;YAErD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YAC7B,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SAC1C;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAEM,2BAA2B,CAC9B,GAAuB,EACvB,MAAe,EACf,EAAE,GAAG,SAAI,EAAE;QAEX,MAAM,OAAO,GAAG,IAAI,qDAAkC,CAAC;YACnD,EAAE;YACF,GAAG;YACH,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;YACzB,sBAAsB,EAAE,IAAI,CAAC,8BAA8B,CACvD,EAAE,EACF,EAAE,IAAI,EAAE,gDAA0B,CAAC,KAAK,EAAE,CAC7C;YACD,aAAa,EAAE,CAAC,EAA0B,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC1E,YAAY,EAAE,SAAS;YACvB,eAAe,EAAE,MAAM;YACvB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,uBAAuB,EAAE,IAAI,CAAC,OAAO,CAAC,uBAAuB;SAChE,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,OAAO,CAAC;IACnB,CAAC;IAEM,4BAA4B,CAAC,GAAa,EAAE,EAAU,EAAE,MAAe,EAAE,KAAW;QACvF,MAAM,OAAO,GAAG,IAAI,6CAA0B,CAAC;YAC3C,EAAE;YACF,GAAG;YACH,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO;YAC7B,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;YACzB,sBAAsB,EAAE,IAAI,CAAC,8BAA8B,CACvD,EAAE,EACF,EAAE,IAAI,EAAE,gDAA0B,CAAC,KAAK,EAAE,CAC7C;YACD,aAAa,EAAE,CAAC,EAA0B,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC1E,YAAY,EAAE,SAAS;YACvB,eAAe,EAAE,MAAM;YACvB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,uBAAuB,EAAE,IAAI,CAAC,OAAO,CAAC,uBAAuB;YAC7D,WAAW,EAAE,KAAK;SACrB,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,IAAW,QAAQ,KAAI,OAAO,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA,CAAC;IAGnD,mBAAmB,CAAC,OAAY,EAAE,eAAwB;QAC7D,MAAM,QAAQ,GAAG,OAAoB,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,qBAAM,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAC5E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACzD,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,OAAY;QACpC,MAAM,QAAQ,GAAG,OAAoB,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,qBAAM,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAC5E,OAAO,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC;IAEM,KAAK,CAAC,oBAAoB,CAAC,OAAuB;QACrD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5C,yEAAyE;QACzE,IAAI,CAAC,oBAAoB,CAAC,EAAE,QAAQ,EAAE,OAAO,EAA+B,EAAE,KAAK,CAAC,CAAC;IACzF,CAAC;IAEM,uBAAuB,CAAC,OAAkC,EAAE,KAAc,EAAE,oBAA6B;QAC5G,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAqB,CAAC;QAC/C,MAAM,WAAW,mCAAQ,OAAO,KAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,GAAE,CAAC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,qBAAM,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAC5E,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,oBAAoB,CAAC,CAAC;QAE1D,kGAAkG;QAClG,IAAI,CAAC,gBAAgB,CACjB,IAAI,QAAQ,CAAC,OAAO,EAAE,EACtB,OAAO,CAAC,SAAS,EACjB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CACrD,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,EAAU,EAAE,IAAa;;QAC/C,MAAM,UAAU,SAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,mCAAI,EAAE,CAAC;QAE/C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACxE,IAAI,OAAO,KAAK,SAAS,EAAE;YACvB,2EAA2E;YAC3E,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;YAC5B,MAAM,mCAAmB,CAAC,iCAAiB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;SAClE;QAED,OAAO,OAAO,CAAC;IACnB,CAAC;IAEM,aAAa,CAAC,OAAe,EAAE,OAA8B,EAAE,KAAc;QAChF,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE;YACV,iDAAiD;YACjD,qBAAM,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACjE,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;gBAC3B,SAAS,EAAE,8BAA8B;gBACzC,gBAAgB,EAAE,OAAO;aAC5B,CAAC,CAAC;YACH,OAAO;SACV;QAED,OAAO,CAAC,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IAEM,kBAAkB,CAAC,SAAkB,EAAE,QAAiB;QAC3D,KAAK,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE;YACnD,IAAI;gBACA,OAAO,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;aACnD;YAAC,OAAO,KAAK,EAAE;gBACZ,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;oBACvB,SAAS,EAAE,yBAAyB;oBACpC,QAAQ;oBACR,cAAc;iBACjB,EAAE,KAAK,CAAC,CAAC;aACb;SACJ;IACL,CAAC;IAEM,cAAc,CAAC,WAAyD;QAC3E,IAAI,SAAmC,CAAC;QACxC,IAAI,WAAW,KAAK,mCAAW,CAAC,SAAS,EAAE;YACvC,SAAS,GAAG,WAAW,CAAC;SAC3B;aAAM;YACH,SAAS,GAAG,UAAU,CAAC;SAC1B;QACD,KAAK,MAAM,CAAC,EAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE;YACpC,gCAAgC;YAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;gBACvC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aAC3B;SACJ;IACL,CAAC;IAED,IAAW,IAAI;QACX,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC9B,CAAC;IAEM,KAAK,CAAC,SAAS,CAAC,QAAiB,EAAE,UAAmB;QACzD,MAAM,cAAc,GAAG,IAAI,kCAAkB,EAAE,CAAC;QAEhD,iDAAiD;QACjD,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE;YACrB,4DAA4D;YAC5D,qBAAM,CAAC,OAAO,CAAC,WAAW,KAAK,mCAAW,CAAC,SAAS,EAChD,KAAK,CAAC,0DAA0D,CAAC,CAAC;YACtE,OAAO,OAAO,CAAC,WAAW,KAAK,mCAAW,CAAC,QAAQ,CAAC;QACxD,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE;YAClC,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACrE,cAAc,CAAC,YAAY,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC,CAAC;QAER,OAAO,cAAc,CAAC,cAAc,EAAE,CAAC;IAC3C,CAAC;IAEM,aAAa;QAChB,MAAM,OAAO,GAAG,IAAI,kCAAkB,EAAE,CAAC;QACzC,0EAA0E;QAC1E,wDAAwD;QACxD,IAAI,sBAA8B,CAAC;QACnC,GAAG;YACC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;YACzC,sBAAsB,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;YACxD,sDAAsD;YACtD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;iBACpB,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE;YACjB,yFAAyF;YACzF,0FAA0F;YAC1F,sEAAsE;YACtE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;mBACxB,WAAW,CAAC,GAAG,CAAC;mBAChB,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAClD;iBACA,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;gBAClB,IAAI,gBAAkC,CAAC;gBACvC,IAAI,KAAK,CAAC,QAAQ,EAAE;oBAChB,MAAM,QAAQ,GAAG,KAAK,CAAC,qBAAqB,EAAE,CAAC,QAAQ,CAAC;oBACxD,gBAAgB,GAAG,oCAAoB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;iBAC3D;qBAAM;oBACH,6FAA6F;oBAC7F,uFAAuF;oBACvF,qBAAM,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,EACtB,KAAK,CAAC,+EAA+E,CAAC,CAAC;oBAC3F,gBAAgB,GAAG,gDAAgC,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;iBACrF;gBACD,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;YAChD,CAAC,CAAC,CAAC;SACV,QAAQ,sBAAsB,KAAK,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,EAAE;QAEpE,OAAO,OAAO,CAAC,cAAc,EAAE,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,mBAAmB;QAC5B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,qBAAqB,EAAE;YACzC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACtC,qBAAM,CAAC,OAAO,KAAK,SAAS,EAAE,KAAK,CAAC,gDAAgD,CAAC,CAAC;YACtF,IAAI,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE;gBACxB,2FAA2F;gBAC3F,MAAM,MAAM,GAAG,IAAI,6BAAiB,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;gBACpF,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;aAC9E;SACJ;QACD,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC;IACpC,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,SAAS,CAAC,SAAkB,KAAK;QAC1C,MAAM,OAAO,GAAG,IAAI,iCAAa,EAAE,CAAC;QACpC,iDAAiD;QACjD,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,EAAE;YACrB,kGAAkG;YAClG,sEAAsE;YACtE,OAAO,OAAO,CAAC,WAAW,KAAK,mCAAW,CAAC,QAAQ,CAAC;QACxD,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE;YAClC,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACtD,wGAAwG;YACxG,6EAA6E;YAC7E,OAAO,CAAC,iBAAiB,CAAC,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC,CAAC;QAER,8DAA8D;QAC9D,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACrD,OAAO,OAAO,CAAC,SAAS,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACI,gBAAgB,CAAC,UAAoB,EAAE,WAAoB;;QAC9D,oDAAoD;QACpD,MAAM,mBAAmB,GAAG,8CAA0B,CAAC,UAAU,CAAC,CAAC;QAEnE,2CAA2C;QAC3C,KAAK,MAAM,CAAC,EAAE,CAAC,IAAI,mBAAmB,EAAE;YACpC,qBAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,0DAA0D,CAAC,CAAC;SACnG;QAED,0FAA0F;QAC1F,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE;YAC9C,OAAO,CAAC,gBAAgB,OAAC,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,mCAAI,EAAE,EAAE,WAAW,CAAC,CAAC;SACnF;IACL,CAAC;IAED;;;;OAIG;IACI,kBAAkB,CAAC,YAAsB;QAC5C,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE;YAC9B,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACxC,6CAA6C;YAC7C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAClC,wDAAwD;YACxD,IAAI,CAAC,2BAA2B,CAAC,WAAW,CAAC,CAAC;SACjD;IACL,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,iBAAiB;QAC3B,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE;YAC9C,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;YAC/C,IAAI,eAAe,EAAE;gBACjB,cAAc,CAAC,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;aACxC;SACJ;QACD,OAAO,cAAc,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACI,kBAAkB,CAAC,QAAgB;QACtC,8GAA8G;QAC9G,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC/C,qBAAM,CAAC,OAAO,KAAK,SAAS,EAAE,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACrF,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,CAAC;CACJ;AAljBD,gCAkjBC;AAED,SAAgB,uBAAuB,CACnC,QAAmC,EACnC,QAAoC;IAEpC,IAAI,CAAC,QAAQ,EAAE;QACX,OAAO,SAAS,CAAC;KACpB;IAED,IAAI,uCAAuB,CAAC,QAAQ,CAAC,EAAE;QACnC,MAAM,kBAAkB,GAAG,QAAQ,CAAC,KAAK,CAAC,sCAAgB,CAAC,CAAC;QAC5D,qBAAM,CAAC,CAAC,CAAC,kBAAkB,EAAE,KAAK,CAAC,qDAAqD,CAAC,CAAC;QAC1F,OAAO,kBAAkB,CAAC;KAC7B;SAAM;QACH,qFAAqF;QACrF,MAAM,eAAe,GAA2B,EAAE,CAAC;QACnD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;YACvD,IAAI,CAAC,iCAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBAClC,eAAe,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aAChC;SACJ;QACD,uCACO,QAAQ,KACX,KAAK,EAAE,eAAe,IACxB;KACL;AACL,CAAC;AAzBD,0DAyBC","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 channelsTreeName,\n CreateChildSummarizerNodeFn,\n CreateChildSummarizerNodeParam,\n CreateSummarizerNodeSource,\n IAttachMessage,\n IEnvelope,\n IFluidDataStoreChannel,\n IFluidDataStoreContextDetached,\n IGarbageCollectionData,\n IGarbageCollectionDetailsBase,\n IInboundSignalMessage,\n InboundAttachMessage,\n ISummarizeResult,\n ISummaryTreeWithStats,\n} from \"@fluidframework/runtime-definitions\";\nimport {\n convertSnapshotTreeToSummaryTree,\n convertToSummaryTree,\n create404Response,\n responseToException,\n SummaryTreeBuilder,\n} from \"@fluidframework/runtime-utils\";\nimport { ChildLogger, 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\";\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\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 dataStoreChanged: (\n dataStorePath: 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 disableIsolatedChannels: this.runtime.disableIsolatedChannels,\n });\n } else {\n if (typeof value !== \"object\") {\n throw new Error(\"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 bindChannelFn: (cr: IFluidDataStoreChannel) => this.bindFluidDataStore(cr),\n snapshotTree,\n isRootDataStore: undefined,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n disableIsolatedChannels: this.runtime.disableIsolatedChannels,\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 aliases(): ReadonlyMap<string, string> {\n return this.aliasMap;\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 \"duplicateDataStoreCreatedWithExistingId\",\n {\n ...extractSafePropertiesFromMessage(message),\n dataStoreId: {\n value: attachMessage.id,\n tag: TelemetryDataTag.PackageData,\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 this.runtime.disableIsolatedChannels,\n )],\n },\n },\n ),\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n disableIsolatedChannels: this.runtime.disableIsolatedChannels,\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 currentContext = this.contexts.get(aliasMessage.internalId);\n if (currentContext === undefined) {\n this.logger.sendErrorEvent({\n eventName: \"AliasFluidDataStoreNotFound\",\n fluidDataStoreId: aliasMessage.internalId,\n });\n return false;\n }\n\n this.aliasMap.set(aliasMessage.alias, currentContext.id);\n currentContext.setRoot();\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 public bindFluidDataStore(fluidDataStoreRuntime: IFluidDataStoreChannel): void {\n const id = fluidDataStoreRuntime.id;\n const localContext = this.contexts.getUnbound(id);\n assert(!!localContext, 0x15f /* \"Could not find unbound context to bind\" */);\n\n // If the container is detached, we don't need to send OP or add to pending attach because\n // we will summarize it while uploading the create new summary and make it known to other\n // clients.\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(fluidDataStoreRuntime.id);\n }\n\n public createDetachedDataStoreCore(\n pkg: Readonly<string[]>,\n isRoot: boolean,\n id = uuid()): IFluidDataStoreContextDetached\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 bindChannelFn: (cr: IFluidDataStoreChannel) => this.bindFluidDataStore(cr),\n snapshotTree: undefined,\n isRootDataStore: isRoot,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n disableIsolatedChannels: this.runtime.disableIsolatedChannels,\n });\n this.contexts.addUnbound(context);\n return context;\n }\n\n public _createFluidDataStoreContext(pkg: string[], id: string, isRoot: boolean, props?: any) {\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 bindChannelFn: (cr: IFluidDataStoreChannel) => this.bindFluidDataStore(cr),\n snapshotTree: undefined,\n isRootDataStore: isRoot,\n writeGCDataAtRoot: this.writeGCDataAtRoot,\n disableIsolatedChannels: this.runtime.disableIsolatedChannels,\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 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 data store changed. This is used to detect if a deleted data store is being used.\n this.dataStoreChanged(\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 internalId = this.aliasMap.get(id) ?? id;\n\n const context = await this.contexts.getBoundOrRemoted(internalId, 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: address,\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 let eventName: \"attaching\" | \"attached\";\n if (attachState === AttachState.Attaching) {\n eventName = \"attaching\";\n } else {\n eventName = \"attached\";\n }\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(fullTree: boolean, trackState: boolean): 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);\n summaryBuilder.addWithStats(contextId, contextSummary);\n }));\n\n return summaryBuilder.getSummaryTree();\n }\n\n public createSummary(): 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 with id ${id}` */);\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 * 1. Calls into each child data store context to get its GC data.\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 * 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 * @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 dataStoreId = route.split(\"/\")[1];\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 * Returns the package path of the node with the given path. This is used by GC to log when an inactive / deleted\n * node is used.\n */\n public getNodePackagePath(nodePath: string): readonly string[] | undefined {\n // Currently, only return the data store package path for the node since GC is only interested in data stores.\n const dataStoreId = nodePath.split(\"/\")[1];\n const context = this.contexts.get(dataStoreId);\n assert(context !== undefined, 0x2b9 /* \"Data store with given id does not exist\" */);\n return context.isLoaded ? context.packagePath : undefined;\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 ${channelsTreeName} tree in snapshot` */);\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"]}
@@ -35,6 +35,8 @@ export interface IGarbageCollectionRuntime {
35
35
  getGCData(fullGC?: boolean): Promise<IGarbageCollectionData>;
36
36
  /** After GC has run, called to notify the runtime of routes that are used in it. */
37
37
  updateUsedRoutes(usedRoutes: string[], gcTimestamp?: number): void;
38
+ /** Called when the runtime should close because of an error. */
39
+ closeFn(error?: ICriticalContainerError): void;
38
40
  }
39
41
  /** Defines the contract for the garbage collector. */
40
42
  export interface IGarbageCollector {
@@ -66,7 +68,7 @@ export interface IGarbageCollector {
66
68
  /** Called when the latest summary of the system has been refreshed. */
67
69
  latestSummaryStateRefreshed(result: RefreshSummaryResult, readAndParseBlob: ReadAndParseBlob): Promise<void>;
68
70
  /** Called when a node is updated. Used to detect and log when an inactive node is changed or loaded. */
69
- nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
71
+ nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", timestampMs?: number, packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
70
72
  /** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */
71
73
  addedOutboundReference(fromNodePath: string, toNodePath: string): void;
72
74
  dispose(): void;
@@ -82,10 +84,15 @@ export declare class GarbageCollector implements IGarbageCollector {
82
84
  private readonly deleteUnusedRoutes;
83
85
  /** For a given node path, returns the node's package path. */
84
86
  private readonly getNodePackagePath;
85
- /** Returns the current timestamp to be assigned to nodes that become unreferenced. */
86
- private readonly getCurrentTimestampMs;
87
- private readonly closeFn;
88
- static create(provider: IGarbageCollectionRuntime, gcOptions: IGCRuntimeOptions, deleteUnusedRoutes: (unusedRoutes: string[]) => void, getNodePackagePath: (nodeId: string) => readonly string[] | undefined, getCurrentTimestampMs: () => number, closeFn: (error?: ICriticalContainerError) => void, baseSnapshot: ISnapshotTree | undefined, readAndParseBlob: ReadAndParseBlob, baseLogger: ITelemetryLogger, existing: boolean, metadata?: IContainerRuntimeMetadata): IGarbageCollector;
87
+ /**
88
+ * Returns a referenced timestamp to be used to track unreferenced nodes. This is a server generated timestamp
89
+ * and may not be available if there aren't any ops processed yet. If so, we skip tracking unreferenced state
90
+ * such as time when node becomes unreferenced or inactive.
91
+ */
92
+ private readonly getCurrentReferenceTimestampMs;
93
+ /** Returns the timestamp of the last summary generated for this container. */
94
+ private readonly getLastSummaryTimestampMs;
95
+ static create(provider: IGarbageCollectionRuntime, gcOptions: IGCRuntimeOptions, deleteUnusedRoutes: (unusedRoutes: string[]) => void, getNodePackagePath: (nodeId: string) => readonly string[] | undefined, getCurrentReferenceTimestampMs: () => number | undefined, getLastSummaryTimestampMs: () => number | undefined, baseSnapshot: ISnapshotTree | undefined, readAndParseBlob: ReadAndParseBlob, baseLogger: ITelemetryLogger, existing: boolean, metadata?: IContainerRuntimeMetadata): IGarbageCollector;
89
96
  /**
90
97
  * Tells whether GC should be run based on the GC options and local storage flags.
91
98
  */
@@ -149,8 +156,14 @@ export declare class GarbageCollector implements IGarbageCollector {
149
156
  deleteUnusedRoutes: (unusedRoutes: string[]) => void,
150
157
  /** For a given node path, returns the node's package path. */
151
158
  getNodePackagePath: (nodePath: string) => readonly string[] | undefined,
152
- /** Returns the current timestamp to be assigned to nodes that become unreferenced. */
153
- getCurrentTimestampMs: () => number, closeFn: (error?: ICriticalContainerError) => void, baseSnapshot: ISnapshotTree | undefined, readAndParseBlob: ReadAndParseBlob, baseLogger: ITelemetryLogger, existing: boolean, metadata?: IContainerRuntimeMetadata);
159
+ /**
160
+ * Returns a referenced timestamp to be used to track unreferenced nodes. This is a server generated timestamp
161
+ * and may not be available if there aren't any ops processed yet. If so, we skip tracking unreferenced state
162
+ * such as time when node becomes unreferenced or inactive.
163
+ */
164
+ getCurrentReferenceTimestampMs: () => number | undefined,
165
+ /** Returns the timestamp of the last summary generated for this container. */
166
+ getLastSummaryTimestampMs: () => number | undefined, baseSnapshot: ISnapshotTree | undefined, readAndParseBlob: ReadAndParseBlob, baseLogger: ITelemetryLogger, existing: boolean, metadata?: IContainerRuntimeMetadata);
154
167
  /**
155
168
  * Runs garbage collection and udpates the reference / used state of the nodes in the container.
156
169
  * @returns the number of data stores that have been marked as unreferenced.
@@ -183,10 +196,11 @@ export declare class GarbageCollector implements IGarbageCollector {
183
196
  * Called when a node with the given id is updated. If the node is inactive, log an error.
184
197
  * @param nodePath - The id of the node that changed.
185
198
  * @param reason - Whether the node was loaded or changed.
199
+ * @param timestampMs - The timestamp when the node changed.
186
200
  * @param packagePath - The package path of the node. This may not be available if the node hasn't been loaded yet.
187
201
  * @param requestHeaders - If the node was loaded via request path, the headers in the request.
188
202
  */
189
- nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
203
+ nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", timestampMs?: number, packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
190
204
  /**
191
205
  * Called when an outbound reference is added to a node. This is used to identify all nodes that have been
192
206
  * referenced between summaries so that their unreferenced timestamp can be reset.
@@ -207,7 +221,7 @@ export declare class GarbageCollector implements IGarbageCollector {
207
221
  * 3. Clears tracking for nodes that were unreferenced but became referenced in this run.
208
222
  * @param gcData - The data representing the reference graph on which GC is run.
209
223
  * @param gcResult - The result of the GC run on the gcData.
210
- * @param currentTimestampMs - The current timestamp to be used for unreferenced nodes' timestamp.
224
+ * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
211
225
  */
212
226
  private updateCurrentState;
213
227
  /**
@@ -236,8 +250,7 @@ export declare class GarbageCollector implements IGarbageCollector {
236
250
  */
237
251
  private generateStatsAndLogEvents;
238
252
  /**
239
- * Logs an event if a node is inactive and is used. If the package data for the node exists, log immediately. Else,
240
- * queue it and it will be logged the next time GC runs as the package data should be available then.
253
+ * Logs an event if a node is inactive and is used.
241
254
  */
242
255
  private logIfInactive;
243
256
  }
@@ -1 +1 @@
1
- {"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../src/garbageCollection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../src/garbageCollection.ts"],"names":[],"mappings":"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"}
@@ -38,23 +38,41 @@ const defaultSessionExpiryDurationMs = 30 * 24 * 60 * 60 * 1000; // 30 days
38
38
  * the node's state to inactive if it remains unreferenced for a given amount of time (inactiveTimeoutMs).
39
39
  */
40
40
  class UnreferencedStateTracker {
41
- constructor(unreferencedTimestampMs, inactiveTimeoutMs) {
41
+ constructor(unreferencedTimestampMs, inactiveTimeoutMs, currentReferenceTimestampMs) {
42
42
  this.unreferencedTimestampMs = unreferencedTimestampMs;
43
+ this.inactiveTimeoutMs = inactiveTimeoutMs;
43
44
  this._inactive = false;
44
- // If the timeout has already expired, the node should become inactive immediately. Otherwise, start a timer of
45
- // inactiveTimeoutMs after which the node will become inactive.
46
- if (inactiveTimeoutMs <= 0) {
47
- this._inactive = true;
48
- }
49
- else {
50
- this.timer = new common_utils_1.Timer(inactiveTimeoutMs, () => { this._inactive = true; });
51
- this.timer.start();
45
+ // If there is no current reference timestamp, don't track the node's inactive state. This will happen later
46
+ // when updateTracking is called with a reference timestamp.
47
+ if (currentReferenceTimestampMs !== undefined) {
48
+ this.updateTracking(currentReferenceTimestampMs);
52
49
  }
53
50
  }
54
51
  get inactive() {
55
52
  return this._inactive;
56
53
  }
57
- /** Stop tracking this node. Reset the unreferenced timer, if any, and reset inactive state. */
54
+ /**
55
+ * Updates the tracking state based on the provided timestamp.
56
+ */
57
+ updateTracking(currentReferenceTimestampMs) {
58
+ var _a;
59
+ const unreferencedDurationMs = currentReferenceTimestampMs - this.unreferencedTimestampMs;
60
+ // If the timeout has already expired, the node has become inactive.
61
+ if (unreferencedDurationMs > this.inactiveTimeoutMs) {
62
+ this._inactive = true;
63
+ (_a = this.timer) === null || _a === void 0 ? void 0 : _a.clear();
64
+ return;
65
+ }
66
+ // The node isn't inactive yet. Restart a timer for the duration remaining for it to become inactive.
67
+ const remainingDurationMs = this.inactiveTimeoutMs - unreferencedDurationMs;
68
+ if (this.timer === undefined) {
69
+ this.timer = new common_utils_1.Timer(remainingDurationMs, () => { this._inactive = true; });
70
+ }
71
+ this.timer.restart(remainingDurationMs);
72
+ }
73
+ /**
74
+ * Stop tracking this node. Reset the unreferenced timer, if any, and reset inactive state.
75
+ */
58
76
  stopTracking() {
59
77
  var _a;
60
78
  (_a = this.timer) === null || _a === void 0 ? void 0 : _a.clear();
@@ -71,15 +89,21 @@ class GarbageCollector {
71
89
  deleteUnusedRoutes,
72
90
  /** For a given node path, returns the node's package path. */
73
91
  getNodePackagePath,
74
- /** Returns the current timestamp to be assigned to nodes that become unreferenced. */
75
- getCurrentTimestampMs, closeFn, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata) {
92
+ /**
93
+ * Returns a referenced timestamp to be used to track unreferenced nodes. This is a server generated timestamp
94
+ * and may not be available if there aren't any ops processed yet. If so, we skip tracking unreferenced state
95
+ * such as time when node becomes unreferenced or inactive.
96
+ */
97
+ getCurrentReferenceTimestampMs,
98
+ /** Returns the timestamp of the last summary generated for this container. */
99
+ getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata) {
76
100
  var _a, _b, _c, _d, _e;
77
101
  this.provider = provider;
78
102
  this.gcOptions = gcOptions;
79
103
  this.deleteUnusedRoutes = deleteUnusedRoutes;
80
104
  this.getNodePackagePath = getNodePackagePath;
81
- this.getCurrentTimestampMs = getCurrentTimestampMs;
82
- this.closeFn = closeFn;
105
+ this.getCurrentReferenceTimestampMs = getCurrentReferenceTimestampMs;
106
+ this.getLastSummaryTimestampMs = getLastSummaryTimestampMs;
83
107
  /**
84
108
  * Tells whether the GC data should be written to the root of the summary tree.
85
109
  */
@@ -132,7 +156,7 @@ class GarbageCollector {
132
156
  if (this.sessionExpiryTimeoutMs !== undefined) {
133
157
  const timeoutMs = this.sessionExpiryTimeoutMs;
134
158
  setLongTimeout(timeoutMs, () => {
135
- this.closeFn(new container_utils_1.ClientSessionExpiredError(`Client session expired.`, timeoutMs));
159
+ this.provider.closeFn(new container_utils_1.ClientSessionExpiredError(`Client session expired.`, timeoutMs));
136
160
  }, (timer) => {
137
161
  this.sessionExpiryTimer = timer;
138
162
  });
@@ -215,22 +239,21 @@ class GarbageCollector {
215
239
  // very first summary generated by detached container. In both cases, GC was not run - return undefined.
216
240
  return Object.keys(gcState.gcNodes).length === 1 ? undefined : gcState;
217
241
  });
218
- // Set up the initializer which initializes the base GC state from the base snapshot. Use lazy promise because
219
- // we only do this once - the very first time we run GC.
242
+ /**
243
+ * Set up the initializer which initializes the base GC state from the base snapshot. Note that the reference
244
+ * timestamp maybe from old ops which were not summarized and stored in the file. So, the unreferenced state
245
+ * may be out of date. This is fine because the state is updated every time GC runs based on the time then.
246
+ */
220
247
  this.initializeBaseStateP = new common_utils_1.LazyPromise(async () => {
221
- const currentTimestampMs = this.getCurrentTimestampMs();
248
+ const currentReferenceTimestampMs = this.getCurrentReferenceTimestampMs();
222
249
  const baseState = await baseSummaryStateP;
223
250
  if (baseState === undefined) {
224
251
  return;
225
252
  }
226
253
  const gcNodes = {};
227
254
  for (const [nodeId, nodeData] of Object.entries(baseState.gcNodes)) {
228
- const unreferencedTimestampMs = nodeData.unreferencedTimestampMs;
229
- if (unreferencedTimestampMs !== undefined) {
230
- // Get how long it has been since the node was unreferenced. Start a timeout for the remaining time
231
- // left for it to be eligible for deletion.
232
- const unreferencedDurationMs = currentTimestampMs - unreferencedTimestampMs;
233
- this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(unreferencedTimestampMs, this.deleteTimeoutMs - unreferencedDurationMs));
255
+ if (nodeData.unreferencedTimestampMs !== undefined) {
256
+ this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(nodeData.unreferencedTimestampMs, this.deleteTimeoutMs, currentReferenceTimestampMs));
234
257
  }
235
258
  gcNodes[nodeId] = Array.from(nodeData.outboundRoutes);
236
259
  }
@@ -278,8 +301,8 @@ class GarbageCollector {
278
301
  });
279
302
  }
280
303
  }
281
- static create(provider, gcOptions, deleteUnusedRoutes, getNodePackagePath, getCurrentTimestampMs, closeFn, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata) {
282
- return new GarbageCollector(provider, gcOptions, deleteUnusedRoutes, getNodePackagePath, getCurrentTimestampMs, closeFn, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata);
304
+ static create(provider, gcOptions, deleteUnusedRoutes, getNodePackagePath, getCurrentReferenceTimestampMs, getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata) {
305
+ return new GarbageCollector(provider, gcOptions, deleteUnusedRoutes, getNodePackagePath, getCurrentReferenceTimestampMs, getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata);
283
306
  }
284
307
  /**
285
308
  * This tracks two things:
@@ -322,9 +345,9 @@ class GarbageCollector {
322
345
  // the current run. We need to identify than and update their unreferenced state if needed.
323
346
  this.updateStateSinceLastRun(gcData);
324
347
  // Update the current state of the system based on the GC run.
325
- const currentTimestampMs = this.getCurrentTimestampMs();
326
- this.updateCurrentState(gcData, gcResult, currentTimestampMs);
327
- this.provider.updateUsedRoutes(gcResult.referencedNodeIds, currentTimestampMs);
348
+ const currentReferenceTimestampMs = this.getCurrentReferenceTimestampMs();
349
+ this.updateCurrentState(gcData, gcResult, currentReferenceTimestampMs);
350
+ this.provider.updateUsedRoutes(gcResult.referencedNodeIds, currentReferenceTimestampMs);
328
351
  if (runSweep) {
329
352
  // Placeholder for running sweep logic.
330
353
  }
@@ -390,14 +413,15 @@ class GarbageCollector {
390
413
  * Called when a node with the given id is updated. If the node is inactive, log an error.
391
414
  * @param nodePath - The id of the node that changed.
392
415
  * @param reason - Whether the node was loaded or changed.
416
+ * @param timestampMs - The timestamp when the node changed.
393
417
  * @param packagePath - The package path of the node. This may not be available if the node hasn't been loaded yet.
394
418
  * @param requestHeaders - If the node was loaded via request path, the headers in the request.
395
419
  */
396
- nodeUpdated(nodePath, reason, packagePath, requestHeaders) {
420
+ nodeUpdated(nodePath, reason, timestampMs, packagePath, requestHeaders) {
397
421
  if (!this.shouldRunGC) {
398
422
  return;
399
423
  }
400
- this.logIfInactive(reason, nodePath, this.getCurrentTimestampMs(), packagePath, requestHeaders);
424
+ this.logIfInactive(reason, nodePath, timestampMs, packagePath, requestHeaders);
401
425
  }
402
426
  /**
403
427
  * Called when an outbound reference is added to a node. This is used to identify all nodes that have been
@@ -415,7 +439,7 @@ class GarbageCollector {
415
439
  outboundRoutes.push(toNodePath);
416
440
  this.referencesSinceLastRun.set(fromNodePath, outboundRoutes);
417
441
  // If the node that got referenced is inactive, log an event as that may indicate use-after-delete.
418
- this.logIfInactive("Revived", toNodePath, this.getCurrentTimestampMs(), this.getNodePackagePath(toNodePath));
442
+ this.logIfInactive("Revived", toNodePath);
419
443
  }
420
444
  dispose() {
421
445
  if (this.sessionExpiryTimer !== undefined) {
@@ -440,24 +464,11 @@ class GarbageCollector {
440
464
  * 3. Clears tracking for nodes that were unreferenced but became referenced in this run.
441
465
  * @param gcData - The data representing the reference graph on which GC is run.
442
466
  * @param gcResult - The result of the GC run on the gcData.
443
- * @param currentTimestampMs - The current timestamp to be used for unreferenced nodes' timestamp.
467
+ * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
444
468
  */
445
- updateCurrentState(gcData, gcResult, currentTimestampMs) {
469
+ updateCurrentState(gcData, gcResult, currentReferenceTimestampMs) {
446
470
  this.gcDataFromLastRun = garbage_collector_1.cloneGCData(gcData);
447
471
  this.referencesSinceLastRun.clear();
448
- // Iterate through the deleted nodes and start tracking if they became unreferenced in this run.
449
- for (const nodeId of gcResult.deletedNodeIds) {
450
- // The time when the node became unreferenced. This is added to the current GC state.
451
- let unreferencedTimestampMs = currentTimestampMs;
452
- const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
453
- if (nodeStateTracker !== undefined) {
454
- unreferencedTimestampMs = nodeStateTracker.unreferencedTimestampMs;
455
- }
456
- else {
457
- // Start tracking this node as it became unreferenced in this run.
458
- this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(unreferencedTimestampMs, this.deleteTimeoutMs));
459
- }
460
- }
461
472
  // Iterate through the referenced nodes and stop tracking if they were unreferenced before.
462
473
  for (const nodeId of gcResult.referencedNodeIds) {
463
474
  const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
@@ -468,6 +479,28 @@ class GarbageCollector {
468
479
  this.unreferencedNodesState.delete(nodeId);
469
480
  }
470
481
  }
482
+ /**
483
+ * If there is no current reference time, skip tracking when a node becomes unreferenced. This would happen
484
+ * if no ops have been processed ever and we still try to run GC. If so, there is nothing interesting to track
485
+ * anyway.
486
+ */
487
+ if (currentReferenceTimestampMs === undefined) {
488
+ return;
489
+ }
490
+ /**
491
+ * If a node became unreferenced in this run, start tracking it.
492
+ * If a node was already unreferenced, update its tracking information. Since the current reference time is
493
+ * from the ops seen, this will ensure that we keep updating the unreferenced state as time moves forward.
494
+ */
495
+ for (const nodeId of gcResult.deletedNodeIds) {
496
+ const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
497
+ if (nodeStateTracker === undefined) {
498
+ this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(currentReferenceTimestampMs, this.deleteTimeoutMs, currentReferenceTimestampMs));
499
+ }
500
+ else {
501
+ nodeStateTracker.updateTracking(currentReferenceTimestampMs);
502
+ }
503
+ }
471
504
  }
472
505
  /**
473
506
  * Since GC runs periodically, the GC data that is generated only tells us the state of the world at that point in
@@ -631,10 +664,14 @@ class GarbageCollector {
631
664
  return gcStats;
632
665
  }
633
666
  /**
634
- * Logs an event if a node is inactive and is used. If the package data for the node exists, log immediately. Else,
635
- * queue it and it will be logged the next time GC runs as the package data should be available then.
667
+ * Logs an event if a node is inactive and is used.
636
668
  */
637
- logIfInactive(eventSuffix, nodeId, timestampMs, packagePath, requestHeaders) {
669
+ logIfInactive(eventSuffix, nodeId, currentReferenceTimestampMs = this.getCurrentReferenceTimestampMs(), packagePath, requestHeaders) {
670
+ // If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
671
+ // logging as nothing interesting would have happened worth logging.
672
+ if (currentReferenceTimestampMs === undefined) {
673
+ return;
674
+ }
638
675
  const eventName = `inactiveObject_${eventSuffix}`;
639
676
  // We log a particular event for a given node only once so that it is not too noisy.
640
677
  const uniqueEventId = `${nodeId}-${eventName}`;
@@ -644,13 +681,17 @@ class GarbageCollector {
644
681
  const event = {
645
682
  eventName,
646
683
  id: nodeId,
647
- age: timestampMs - nodeState.unreferencedTimestampMs,
684
+ age: currentReferenceTimestampMs - nodeState.unreferencedTimestampMs,
648
685
  timeout: this.deleteTimeoutMs,
686
+ lastSummaryTime: this.getLastSummaryTimestampMs(),
649
687
  externalRequest: requestHeaders === null || requestHeaders === void 0 ? void 0 : requestHeaders[_1.RuntimeHeaders.externalRequest],
650
688
  viaHandle: requestHeaders === null || requestHeaders === void 0 ? void 0 : requestHeaders[_1.RuntimeHeaders.viaHandle],
651
689
  };
652
- if (packagePath !== undefined) {
653
- this.mc.logger.sendErrorEvent(Object.assign(Object.assign({}, event), { pkg: { value: `/${packagePath.join("/")}`, tag: telemetry_utils_1.TelemetryDataTag.PackageData } }));
690
+ // If the package data for the node exists, log immediately. Otherwise, queue it and it will be logged the
691
+ // next time GC runs as the package data should be available then.
692
+ const pkg = packagePath !== null && packagePath !== void 0 ? packagePath : this.getNodePackagePath(nodeId);
693
+ if (pkg !== undefined) {
694
+ this.mc.logger.sendErrorEvent(Object.assign(Object.assign({}, event), { pkg: { value: `/${pkg.join("/")}`, tag: telemetry_utils_1.TelemetryDataTag.PackageData } }));
654
695
  }
655
696
  else {
656
697
  this.pendingEventsQueue.push(event);