@fluidframework/container-runtime 2.0.0-rc.2.0.2 → 2.0.0-rc.2.0.4
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/api-report/container-runtime.api.md +32 -4
- package/dist/channelCollection.d.ts +7 -3
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +80 -22
- package/dist/channelCollection.js.map +1 -1
- package/dist/container-runtime-alpha.d.ts +14 -4
- package/dist/container-runtime-beta.d.ts +6 -0
- package/dist/container-runtime-public.d.ts +6 -0
- package/dist/container-runtime-untrimmed.d.ts +43 -4
- package/dist/containerRuntime.d.ts +6 -0
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +16 -4
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +12 -2
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStoreContexts.d.ts +2 -0
- package/dist/dataStoreContexts.d.ts.map +1 -1
- package/dist/dataStoreContexts.js +7 -0
- package/dist/dataStoreContexts.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts +4 -11
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +45 -29
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +26 -5
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts +5 -4
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +14 -2
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts +13 -2
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +24 -21
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/gc/index.d.ts +2 -2
- package/dist/gc/index.d.ts.map +1 -1
- package/dist/gc/index.js +2 -2
- package/dist/gc/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- 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/lib/channelCollection.d.ts +7 -3
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +82 -24
- package/lib/channelCollection.js.map +1 -1
- package/lib/container-runtime-alpha.d.ts +14 -4
- package/lib/container-runtime-beta.d.ts +6 -0
- package/lib/container-runtime-public.d.ts +6 -0
- package/lib/container-runtime-untrimmed.d.ts +43 -4
- package/lib/containerRuntime.d.ts +6 -0
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +15 -3
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +12 -2
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStoreContexts.d.ts +2 -0
- package/lib/dataStoreContexts.d.ts.map +1 -1
- package/lib/dataStoreContexts.js +7 -0
- package/lib/dataStoreContexts.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts +4 -11
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +47 -31
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +26 -5
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts +5 -4
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +12 -1
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts +13 -2
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +24 -21
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/gc/index.d.ts +2 -2
- package/lib/gc/index.d.ts.map +1 -1
- package/lib/gc/index.js +1 -1
- package/lib/gc/index.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- 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/test/gc/garbageCollection.spec.js +23 -14
- package/lib/test/gc/garbageCollection.spec.js.map +1 -1
- package/lib/test/gc/gcHelpers.spec.js +69 -1
- package/lib/test/gc/gcHelpers.spec.js.map +1 -1
- package/lib/test/gc/gcTelemetry.spec.js +31 -3
- package/lib/test/gc/gcTelemetry.spec.js.map +1 -1
- package/package.json +16 -16
- package/src/channelCollection.ts +107 -43
- package/src/containerRuntime.ts +17 -23
- package/src/dataStoreContext.ts +14 -2
- package/src/dataStoreContexts.ts +12 -0
- package/src/gc/garbageCollection.ts +63 -41
- package/src/gc/gcDefinitions.ts +21 -9
- package/src/gc/gcHelpers.ts +14 -1
- package/src/gc/gcTelemetry.ts +56 -47
- package/src/gc/index.ts +2 -1
- package/src/index.ts +3 -0
- package/src/packageVersion.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcTelemetry.js","sourceRoot":"","sources":["../../src/gc/gcTelemetry.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 { IGarbageCollectionData } from \"@fluidframework/runtime-definitions\";\nimport {\n\tgenerateStack,\n\tITelemetryLoggerExt,\n\tMonitoringContext,\n\ttagCodeArtifacts,\n\ttype ITelemetryGenericEventExt,\n} from \"@fluidframework/telemetry-utils\";\nimport { RuntimeHeaderData } from \"../containerRuntime.js\";\nimport { ICreateContainerMetadata } from \"../summary/index.js\";\nimport {\n\tGCNodeType,\n\tUnreferencedState,\n\tIGarbageCollectorConfigs,\n\tdisableTombstoneKey,\n\tthrowOnTombstoneUsageKey,\n\tthrowOnTombstoneLoadOverrideKey,\n\trunSweepKey,\n\tGCFeatureMatrix,\n} from \"./gcDefinitions.js\";\nimport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker.js\";\n\ntype NodeUsageType = \"Changed\" | \"Loaded\" | \"Revived\";\n\n/** Properties that are common to IUnreferencedEventProps and INodeUsageProps */\ninterface ICommonProps {\n\tusageType: NodeUsageType;\n\tcompletedGCRuns: number;\n\tisTombstoned: boolean;\n\tlastSummaryTime?: number;\n\theaders?: RuntimeHeaderData;\n}\n\n/** The event that is logged when unreferenced node is used after a certain time. */\ninterface IUnreferencedEventProps extends ICreateContainerMetadata, ICommonProps {\n\tstate: UnreferencedState;\n\tid: {\n\t\tvalue: string;\n\t\ttag: string;\n\t};\n\ttype: GCNodeType;\n\tunrefTime: number;\n\tage: number;\n\t// Expanding GC feature matrix. Without doing this, the configs cannot be logged in telemetry directly.\n\tgcConfigs: Omit<IGarbageCollectorConfigs, \"persistedGcFeatureMatrix\"> & {\n\t\t[K in keyof GCFeatureMatrix]: GCFeatureMatrix[K];\n\t};\n\ttimeout?: number;\n\tfromId?: {\n\t\tvalue: string;\n\t\ttag: string;\n\t};\n}\n\n/** Properties passed to nodeUsed function when a node is used. */\ninterface INodeUsageProps extends ICommonProps {\n\tid: string;\n\tcurrentReferenceTimestampMs: number | undefined;\n\tpackagePath: readonly string[] | undefined;\n\tfromId?: string;\n\tautorecovery?: true;\n}\n\n/**\n * Encapsulates the logic that tracks the various telemetry logged by the Garbage Collector.\n *\n * These events are not logged as errors, just generic events, since there can be false positives:\n *\n * 1. inactiveObject telemetry - When an inactive node is used - A node that has been unreferenced for inactiveTimeoutMs.\n * 2. tombstoneReadyObject telemetry - When a tombstone-ready node is used - A node that has been unreferenced for tombstoneTimeoutMs.\n * 3. sweepReadyObject telemetry - When a sweep-ready node is used - A node that has been unreferenced for tombstoneTimeoutMs + sweepGracePeriodMs.\n *\n * These events are logged as errors since they are based on the core GC logic:\n *\n * 1. Tombstone telemetry - When a tombstoned node is used - A node that has been marked as tombstone.\n * 2. Unknown outbound reference telemetry - When a node is referenced but GC was not notified of it when the new reference appeared.\n *\n * Note: The telemetry for a Deleted node being used is logged elsewhere in this package.\n */\nexport class GCTelemetryTracker {\n\t// Keeps track of unreferenced events that are logged for a node. This is used to limit the log generation to one\n\t// per event per node.\n\tprivate readonly loggedUnreferencedEvents: Set<string> = new Set();\n\t// Queue for unreferenced events that should be logged the next time GC runs.\n\tprivate pendingEventsQueue: IUnreferencedEventProps[] = [];\n\n\tconstructor(\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly configs: IGarbageCollectorConfigs,\n\t\tprivate readonly isSummarizerClient: boolean,\n\t\tprivate readonly createContainerMetadata: ICreateContainerMetadata,\n\t\tprivate readonly getNodeType: (nodeId: string) => GCNodeType,\n\t\tprivate readonly getNodeStateTracker: (\n\t\t\tnodeId: string,\n\t\t) => UnreferencedStateTracker | undefined,\n\t\tprivate readonly getNodePackagePath: (\n\t\t\tnodePath: string,\n\t\t) => Promise<readonly string[] | undefined>,\n\t) {}\n\n\t/**\n\t * Returns whether an event should be logged for a node that isn't active anymore. This does not apply to\n\t * tombstoned nodes for which an event is always logged. Some scenarios where we won't log:\n\t * 1. When a DDS is changed. The corresponding data store's event will be logged instead.\n\t * 2. An event is logged only once per container instance per event per node.\n\t */\n\tprivate shouldLogNonActiveEvent(\n\t\tnodeType: GCNodeType,\n\t\tusageType: NodeUsageType,\n\t\tnodeStateTracker: UnreferencedStateTracker,\n\t\tuniqueEventId: string,\n\t) {\n\t\tif (nodeStateTracker.state === UnreferencedState.Active) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (nodeType === GCNodeType.Other) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// For sub data store (DDS) nodes, if they are changed, its data store will also be changed,\n\t\t// so skip logging to make the telemetry less noisy.\n\t\tif (nodeType === GCNodeType.SubDataStore && usageType === \"Changed\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Non-tombstone events are logged once per event per node. A unique id is generated by joining\n\t\t// node state (inactive / sweep ready), node's id and usage (loaded / changed / revived).\n\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Called when a node is used. If the node is not active or tombstoned, log telemetry indicating object is used\n\t * when it should not have been.\n\t */\n\tpublic nodeUsed(nodeUsageProps: INodeUsageProps) {\n\t\t// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip\n\t\t// logging as nothing interesting would have happened worth logging.\n\t\tif (nodeUsageProps.currentReferenceTimestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst nodeStateTracker = this.getNodeStateTracker(nodeUsageProps.id);\n\t\tconst nodeType = this.getNodeType(nodeUsageProps.id);\n\t\tconst timeout = (() => {\n\t\t\tswitch (nodeStateTracker?.state) {\n\t\t\t\tcase UnreferencedState.Inactive:\n\t\t\t\t\treturn this.configs.inactiveTimeoutMs;\n\t\t\t\tcase UnreferencedState.TombstoneReady:\n\t\t\t\t\treturn this.configs.tombstoneTimeoutMs;\n\t\t\t\tcase UnreferencedState.SweepReady:\n\t\t\t\t\treturn (\n\t\t\t\t\t\tthis.configs.tombstoneTimeoutMs &&\n\t\t\t\t\t\tthis.configs.tombstoneTimeoutMs + this.configs.sweepGracePeriodMs\n\t\t\t\t\t);\n\t\t\t\tdefault:\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})();\n\t\tconst {\n\t\t\tusageType,\n\t\t\tcurrentReferenceTimestampMs,\n\t\t\tpackagePath,\n\t\t\tid: untaggedId,\n\t\t\tfromId: untaggedFromId,\n\t\t\t...propsToLog\n\t\t} = nodeUsageProps;\n\t\tconst { persistedGcFeatureMatrix, ...configs } = this.configs;\n\t\tconst unrefEventProps: Omit<IUnreferencedEventProps, \"state\" | \"usageType\"> = {\n\t\t\ttype: nodeType,\n\t\t\tunrefTime: nodeStateTracker?.unreferencedTimestampMs ?? -1,\n\t\t\tage:\n\t\t\t\tnodeStateTracker !== undefined\n\t\t\t\t\t? nodeUsageProps.currentReferenceTimestampMs -\n\t\t\t\t\t nodeStateTracker.unreferencedTimestampMs\n\t\t\t\t\t: -1,\n\t\t\ttimeout,\n\t\t\t...tagCodeArtifacts({ id: untaggedId, fromId: untaggedFromId }),\n\t\t\t...propsToLog,\n\t\t\t...this.createContainerMetadata,\n\t\t\tgcConfigs: { ...configs, ...persistedGcFeatureMatrix },\n\t\t};\n\n\t\t// If the node that is used is tombstoned, log a tombstone telemetry.\n\t\tif (nodeUsageProps.isTombstoned) {\n\t\t\tthis.logTombstoneUsageTelemetry(nodeUsageProps, unrefEventProps, nodeType, usageType);\n\t\t}\n\n\t\t// After logging tombstone telemetry, if the node's unreferenced state is not tracked, there is nothing\n\t\t// else to log.\n\t\tif (nodeStateTracker === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst state = nodeStateTracker.state;\n\t\tconst uniqueEventId = `${state}-${nodeUsageProps.id}-${nodeUsageProps.usageType}`;\n\n\t\tif (\n\t\t\t!this.shouldLogNonActiveEvent(\n\t\t\t\tnodeType,\n\t\t\t\tnodeUsageProps.usageType,\n\t\t\t\tnodeStateTracker,\n\t\t\t\tuniqueEventId,\n\t\t\t)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Add the unique event id so that we don't generate a log for this event again in this session.\n\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\n\t\t// For summarizer client, queue the event so it is logged the next time GC runs if the event is still valid.\n\t\t// For non-summarizer client, log the event now since GC won't run on it. This may result in false positives\n\t\t// but it's a good signal nonetheless and we can consume it with a grain of salt.\n\t\t// Inactive errors are usages of Objects that are unreferenced for at least a period of 7 days.\n\t\t// SweepReady errors are usages of Objects that will be deleted by GC Sweep!\n\t\tif (this.isSummarizerClient) {\n\t\t\tthis.pendingEventsQueue.push({\n\t\t\t\t...unrefEventProps,\n\t\t\t\tusageType: nodeUsageProps.usageType,\n\t\t\t\tstate,\n\t\t\t});\n\t\t} else {\n\t\t\t// For non-summarizer clients, only log \"Loaded\" type events since these objects may not be loaded in the\n\t\t\t// summarizer clients if they are based off of user actions (such as scrolling to content for these objects)\n\t\t\t// Events generated:\n\t\t\t// InactiveObject_Loaded, SweepReadyObject_Loaded\n\t\t\tif (nodeUsageProps.usageType === \"Loaded\") {\n\t\t\t\tconst { id, fromId, headers, gcConfigs, ...detailedProps } = unrefEventProps;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${nodeUsageProps.usageType}`,\n\t\t\t\t\t...tagCodeArtifacts({ pkg: nodeUsageProps.packagePath?.join(\"/\") }),\n\t\t\t\t\tstack: generateStack(),\n\t\t\t\t\tid,\n\t\t\t\t\tfromId,\n\t\t\t\t\theaders: { ...headers },\n\t\t\t\t\tdetails: detailedProps,\n\t\t\t\t\tgcConfigs,\n\t\t\t\t};\n\n\t\t\t\t// These are logged as generic events and not errors because there can be false positives. The Tombstone\n\t\t\t\t// and Delete errors are separately logged and are reliable.\n\t\t\t\tthis.mc.logger.sendTelemetryEvent(event);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Logs telemetry when a tombstoned object is changed, revived or loaded.\n\t */\n\tprivate logTombstoneUsageTelemetry(\n\t\tnodeUsageProps: INodeUsageProps,\n\t\tunrefEventProps: Omit<IUnreferencedEventProps, \"state\" | \"usageType\">,\n\t\tnodeType: GCNodeType,\n\t\tusageType: NodeUsageType,\n\t) {\n\t\t// This will log the following events:\n\t\t// GC_Tombstone_DataStore_Requested, GC_Tombstone_DataStore_Changed, GC_Tombstone_DataStore_Revived\n\t\t// GC_Tombstone_SubDataStore_Requested, GC_Tombstone_SubDataStore_Changed, GC_Tombstone_SubDataStore_Revived\n\t\t// GC_Tombstone_Blob_Requested, GC_Tombstone_Blob_Changed, GC_Tombstone_Blob_Revived\n\t\tconst { id, fromId, headers, gcConfigs, ...detailedProps } = unrefEventProps;\n\t\tconst eventUsageName = usageType === \"Loaded\" ? \"Requested\" : usageType;\n\t\tconst event = {\n\t\t\teventName: `GC_Tombstone_${nodeType}_${eventUsageName}`,\n\t\t\tpkg: tagCodeArtifacts({ pkg: nodeUsageProps.packagePath?.join(\"/\") }).pkg,\n\t\t\tstack: generateStack(),\n\t\t\tid,\n\t\t\tfromId,\n\t\t\theaders: { ...headers },\n\t\t\tdetails: detailedProps,\n\t\t\tgcConfigs,\n\t\t\ttombstoneFlags: {\n\t\t\t\tDisableTombstone: this.mc.config.getBoolean(disableTombstoneKey),\n\t\t\t\tThrowOnTombstoneUsage: this.mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\t\t\tThrowOnTombstoneLoad: this.mc.config.getBoolean(throwOnTombstoneLoadOverrideKey),\n\t\t\t},\n\t\t\tsweepFlags: {\n\t\t\t\tEnableSweepFlag: this.mc.config.getBoolean(runSweepKey),\n\t\t\t},\n\t\t};\n\n\t\tif (\n\t\t\t(usageType === \"Loaded\" &&\n\t\t\t\tthis.configs.throwOnTombstoneLoad &&\n\t\t\t\t!headers?.allowTombstone) ||\n\t\t\t(usageType === \"Changed\" && this.configs.throwOnTombstoneUsage)\n\t\t) {\n\t\t\tthis.mc.logger.sendErrorEvent(event);\n\t\t} else {\n\t\t\tthis.mc.logger.sendTelemetryEvent(event);\n\t\t}\n\t}\n\n\t/**\n\t * Log all new references or outbound routes in the current graph that haven't been explicitly notified to GC.\n\t * The principle is that every new reference or outbound route must be notified to GC via the\n\t * addedOutboundReference method. It it hasn't, its a bug and we want to identify these scenarios.\n\t *\n\t * In more simple terms:\n\t * Missing Explicit References = Current References - Previous References - Explicitly Added References;\n\t *\n\t * @param currentGCData - The GC data (reference graph) from the current GC run.\n\t * @param previousGCData - The GC data (reference graph) from the previous GC run.\n\t * @param explicitReferences - New references added explicity between the previous and the current run.\n\t */\n\tpublic logIfMissingExplicitReferences(\n\t\tcurrentGCData: IGarbageCollectionData,\n\t\tpreviousGCData: IGarbageCollectionData,\n\t\texplicitReferences: Map<string, string[]>,\n\t\tlogger: ITelemetryLoggerExt,\n\t) {\n\t\tfor (const [nodeId, currentOutboundRoutes] of Object.entries(currentGCData.gcNodes)) {\n\t\t\tconst previousRoutes = previousGCData.gcNodes[nodeId] ?? [];\n\t\t\tconst explicitRoutes = explicitReferences.get(nodeId) ?? [];\n\n\t\t\t/**\n\t\t\t * 1. For routes in the current GC data, routes that were not present in previous GC data and did not have\n\t\t\t * explicit references should be added to missing explicit routes list.\n\t\t\t * 2. Only include data store and blob routes since GC only works for these two.\n\t\t\t * Note: Due to a bug with de-duped blobs, only adding data store routes for now.\n\t\t\t * 3. Ignore DDS routes to their parent datastores since those were added implicitly. So, there won't be\n\t\t\t * explicit routes to them.\n\t\t\t */\n\t\t\tconst missingExplicitRoutes: string[] = [];\n\t\t\tfor (const route of currentOutboundRoutes) {\n\t\t\t\tconst nodeType = this.getNodeType(route);\n\t\t\t\tif (\n\t\t\t\t\t(nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob) &&\n\t\t\t\t\t!nodeId.startsWith(route) &&\n\t\t\t\t\t!previousRoutes.includes(route) &&\n\t\t\t\t\t!explicitRoutes.includes(route)\n\t\t\t\t) {\n\t\t\t\t\tmissingExplicitRoutes.push(route);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (missingExplicitRoutes.length > 0) {\n\t\t\t\t// Send as Generic not Error since there are known corner cases where this will fire.\n\t\t\t\t// E.g. If an old client re-references a node via an attach op (that doesn't include GC Data)\n\t\t\t\tlogger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"gcUnknownOutboundReferences\",\n\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\tid: nodeId,\n\t\t\t\t\t\troutes: JSON.stringify(missingExplicitRoutes),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log events that are pending in pendingEventsQueue. This is called after GC runs in the summarizer client\n\t * so that the state of an unreferenced node is updated.\n\t */\n\tpublic async logPendingEvents(logger: ITelemetryLoggerExt) {\n\t\t// Events sent come only from the summarizer client. In between summaries, events are pushed to a queue and at\n\t\t// summary time they are then logged.\n\t\t// Events generated:\n\t\t// InactiveObject_Loaded, InactiveObject_Changed, InactiveObject_Revived\n\t\t// SweepReadyObject_Loaded, SweepReadyObject_Changed, SweepReadyObject_Revived\n\t\tfor (const eventProps of this.pendingEventsQueue) {\n\t\t\t// const { usageType, state, id, fromId, ...propsToLog } = eventProps;\n\t\t\tconst { usageType, state, id, fromId, headers, gcConfigs, ...detailedProps } =\n\t\t\t\teventProps;\n\t\t\t/**\n\t\t\t * Revived event is logged only if the node is active. If the node is not active, the reference to it was\n\t\t\t * from another unreferenced node and this scenario is not interesting to log.\n\t\t\t * Loaded and Changed events are logged only if the node is not active. If the node is active, it was\n\t\t\t * revived and a Revived event will be logged for it.\n\t\t\t */\n\t\t\tconst nodeStateTracker = this.getNodeStateTracker(eventProps.id.value);\n\t\t\tconst active =\n\t\t\t\tnodeStateTracker === undefined ||\n\t\t\t\tnodeStateTracker.state === UnreferencedState.Active;\n\t\t\tif ((usageType === \"Revived\") === active) {\n\t\t\t\tconst pkg = await this.getNodePackagePath(eventProps.id.value);\n\t\t\t\tconst fromPkg = eventProps.fromId\n\t\t\t\t\t? await this.getNodePackagePath(eventProps.fromId.value)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${usageType}`,\n\t\t\t\t\tid,\n\t\t\t\t\tfromId,\n\t\t\t\t\theaders: { ...headers },\n\t\t\t\t\tdetails: detailedProps,\n\t\t\t\t\tgcConfigs,\n\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\tpkg: pkg?.join(\"/\"),\n\t\t\t\t\t\tfromPkg: fromPkg?.join(\"/\"),\n\t\t\t\t\t}),\n\t\t\t\t};\n\n\t\t\t\t// These are logged as generic events and not errors because there can be false positives. The Tombstone\n\t\t\t\t// and Delete errors are separately logged and are reliable.\n\t\t\t\tlogger.sendTelemetryEvent(event);\n\t\t\t}\n\t\t}\n\t\tthis.pendingEventsQueue = [];\n\t}\n}\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEventExt & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = tagCodeArtifacts({ pkg: packagePath?.join(\"/\") })?.pkg;\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadOverrideKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"gcTelemetry.js","sourceRoot":"","sources":["../../src/gc/gcTelemetry.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 { IGarbageCollectionData } from \"@fluidframework/runtime-definitions\";\nimport {\n\tgenerateStack,\n\tITelemetryLoggerExt,\n\tMonitoringContext,\n\ttagCodeArtifacts,\n\ttype ITelemetryGenericEventExt,\n} from \"@fluidframework/telemetry-utils\";\nimport type { Tagged } from \"@fluidframework/core-interfaces\";\nimport { RuntimeHeaderData } from \"../containerRuntime.js\";\nimport { ICreateContainerMetadata } from \"../summary/index.js\";\nimport {\n\tGCNodeType,\n\tUnreferencedState,\n\tIGarbageCollectorConfigs,\n\tdisableTombstoneKey,\n\tthrowOnTombstoneUsageKey,\n\tthrowOnTombstoneLoadOverrideKey,\n\trunSweepKey,\n\tGCFeatureMatrix,\n} from \"./gcDefinitions.js\";\nimport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker.js\";\n\ntype NodeUsageType = \"Changed\" | \"Loaded\" | \"Revived\";\n\n/** Properties that are common to IUnreferencedEventProps and INodeUsageProps */\ninterface ICommonProps {\n\tusageType: NodeUsageType;\n\tcompletedGCRuns: number;\n\tisTombstoned: boolean;\n\tlastSummaryTime?: number;\n\theaders?: RuntimeHeaderData;\n}\n\n/** The event that is logged when unreferenced node is used after a certain time. */\ninterface IUnreferencedEventProps extends ICreateContainerMetadata, ICommonProps {\n\t/** The id that GC uses to track the node. May or may not match id */\n\ttrackedId: string;\n\tstate: UnreferencedState;\n\t/** The full path (in GC Path format) to the node in question */\n\tid: Tagged<string>;\n\tfromId?: Tagged<string>;\n\ttype: GCNodeType;\n\tunrefTime: number;\n\tage: number;\n\t// Expanding GC feature matrix. Without doing this, the configs cannot be logged in telemetry directly.\n\tgcConfigs: Omit<IGarbageCollectorConfigs, \"persistedGcFeatureMatrix\"> & {\n\t\t[K in keyof GCFeatureMatrix]: GCFeatureMatrix[K];\n\t};\n\ttimeout?: number;\n}\n\n/** Properties passed to nodeUsed function when a node is used. */\ninterface INodeUsageProps extends ICommonProps {\n\t/** The full path (in GC Path format) to the node in question */\n\tid: string;\n\t/** Latest timestamp received from the server, as a baseline for computing GC state/age */\n\tcurrentReferenceTimestampMs: number | undefined;\n\t/** The package path of the node. This may not be available if the node hasn't been loaded yet */\n\tpackagePath: readonly string[] | undefined;\n\t/** In case of Revived - what node added the reference? */\n\tfromId?: string;\n\t/** In case of Revived - was it revived due to autorecovery? */\n\tautorecovery?: true;\n\t/** URL (including query string) if this usage came from a request */\n\trequestUrl?: string;\n\t/** Original request headers if this usage came from a request or handle.get */\n\trequestHeaders?: string;\n}\n\n/**\n * Encapsulates the logic that tracks the various telemetry logged by the Garbage Collector.\n *\n * These events are not logged as errors, just generic events, since there can be false positives:\n *\n * 1. inactiveObject telemetry - When an inactive node is used - A node that has been unreferenced for inactiveTimeoutMs.\n * 2. tombstoneReadyObject telemetry - When a tombstone-ready node is used - A node that has been unreferenced for tombstoneTimeoutMs.\n * 3. sweepReadyObject telemetry - When a sweep-ready node is used - A node that has been unreferenced for tombstoneTimeoutMs + sweepGracePeriodMs.\n *\n * These events are logged as errors since they are based on the core GC logic:\n *\n * 1. Tombstone telemetry - When a tombstoned node is used - A node that has been marked as tombstone.\n * 2. Unknown outbound reference telemetry - When a node is referenced but GC was not notified of it when the new reference appeared.\n *\n * Note: The telemetry for a Deleted node being used is logged elsewhere in this package.\n */\nexport class GCTelemetryTracker {\n\t// Keeps track of unreferenced events that are logged for a node. This is used to limit the log generation to one\n\t// per event per node.\n\tprivate readonly loggedUnreferencedEvents: Set<string> = new Set();\n\t// Queue for unreferenced events that should be logged the next time GC runs.\n\tprivate pendingEventsQueue: IUnreferencedEventProps[] = [];\n\n\tconstructor(\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly configs: IGarbageCollectorConfigs,\n\t\tprivate readonly isSummarizerClient: boolean,\n\t\tprivate readonly createContainerMetadata: ICreateContainerMetadata,\n\t\tprivate readonly getNodeType: (nodeId: string) => GCNodeType,\n\t\tprivate readonly getNodeStateTracker: (\n\t\t\tnodeId: string,\n\t\t) => UnreferencedStateTracker | undefined,\n\t\tprivate readonly getNodePackagePath: (\n\t\t\tnodePath: string,\n\t\t) => Promise<readonly string[] | undefined>,\n\t) {}\n\n\t/**\n\t * Returns whether an event should be logged for a node that isn't active anymore. This does not apply to\n\t * tombstoned nodes for which an event is always logged. Some scenarios where we won't log:\n\t * 1. When a DDS is changed. The corresponding data store's event will be logged instead.\n\t * 2. An event is logged only once per container instance per event per node.\n\t */\n\tprivate shouldLogNonActiveEvent(\n\t\tnodeType: GCNodeType,\n\t\tusageType: NodeUsageType,\n\t\tnodeStateTracker: UnreferencedStateTracker,\n\t\tuniqueEventId: string,\n\t) {\n\t\tif (nodeStateTracker.state === UnreferencedState.Active) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (nodeType === GCNodeType.Other) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// For sub data store (DDS) nodes, if they are changed, its data store will also be changed,\n\t\t// so skip logging to make the telemetry less noisy.\n\t\tif (nodeType === GCNodeType.SubDataStore && usageType === \"Changed\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Non-tombstone events are logged once per event per node. A unique id is generated by joining\n\t\t// node state (inactive / sweep ready), node's id and usage (loaded / changed / revived).\n\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Called when a node is used. If the node is inactive or tombstoned, log telemetry indicating object is used\n\t * when it should not have been.\n\t * @param trackedId - The id that GC uses to track the node. For SubDataStore nodes, this should be the DataStore ID.\n\t * @param INodeUsageProps - All kind of details about this event to be logged\n\t */\n\tpublic nodeUsed(\n\t\ttrackedId: string,\n\t\t{\n\t\t\tusageType,\n\t\t\tcurrentReferenceTimestampMs,\n\t\t\tpackagePath,\n\t\t\tid: untaggedId,\n\t\t\tfromId: untaggedFromId,\n\t\t\tisTombstoned,\n\t\t\t...otherNodeUsageProps\n\t\t}: INodeUsageProps,\n\t) {\n\t\t// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip\n\t\t// logging as nothing interesting would have happened worth logging.\n\t\tif (currentReferenceTimestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Note: For SubDataStore Load usage, trackedId will be the DataStore's id, not the full path in question.\n\t\t// This is necessary because the SubDataStore path may be unrecognized by GC (if suited for a custom request handler)\n\t\tconst nodeStateTracker = this.getNodeStateTracker(trackedId);\n\t\tconst nodeType = this.getNodeType(untaggedId);\n\n\t\tconst timeout = (() => {\n\t\t\tswitch (nodeStateTracker?.state) {\n\t\t\t\tcase UnreferencedState.Inactive:\n\t\t\t\t\treturn this.configs.inactiveTimeoutMs;\n\t\t\t\tcase UnreferencedState.TombstoneReady:\n\t\t\t\t\treturn this.configs.tombstoneTimeoutMs;\n\t\t\t\tcase UnreferencedState.SweepReady:\n\t\t\t\t\treturn (\n\t\t\t\t\t\tthis.configs.tombstoneTimeoutMs &&\n\t\t\t\t\t\tthis.configs.tombstoneTimeoutMs + this.configs.sweepGracePeriodMs\n\t\t\t\t\t);\n\t\t\t\tdefault:\n\t\t\t\t\treturn undefined;\n\t\t\t}\n\t\t})();\n\t\tconst { persistedGcFeatureMatrix, ...configs } = this.configs;\n\t\tconst unrefEventProps = {\n\t\t\ttrackedId,\n\t\t\ttype: nodeType,\n\t\t\tunrefTime: nodeStateTracker?.unreferencedTimestampMs ?? -1,\n\t\t\tage:\n\t\t\t\tnodeStateTracker !== undefined\n\t\t\t\t\t? currentReferenceTimestampMs - nodeStateTracker.unreferencedTimestampMs\n\t\t\t\t\t: -1,\n\t\t\ttimeout,\n\t\t\tisTombstoned,\n\t\t\t...tagCodeArtifacts({ id: untaggedId, fromId: untaggedFromId }),\n\t\t\t...otherNodeUsageProps,\n\t\t\t...this.createContainerMetadata,\n\t\t\tgcConfigs: { ...configs, ...persistedGcFeatureMatrix },\n\t\t} satisfies Omit<IUnreferencedEventProps, \"state\" | \"usageType\"> &\n\t\t\ttypeof otherNodeUsageProps;\n\n\t\t// If the node that is used is tombstoned, log a tombstone telemetry.\n\t\tif (isTombstoned) {\n\t\t\tthis.logTombstoneUsageTelemetry(unrefEventProps, nodeType, usageType, packagePath);\n\t\t}\n\n\t\t// After logging tombstone telemetry, if the node's unreferenced state is not tracked, there is nothing\n\t\t// else to log.\n\t\tif (nodeStateTracker === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst state = nodeStateTracker.state;\n\t\tconst uniqueEventId = `${state}-${untaggedId}-${usageType}`;\n\n\t\tif (!this.shouldLogNonActiveEvent(nodeType, usageType, nodeStateTracker, uniqueEventId)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Add the unique event id so that we don't generate a log for this event again in this session.\n\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\n\t\t// For summarizer client, queue the event so it is logged the next time GC runs if the event is still valid.\n\t\t// For non-summarizer client, log the event now since GC won't run on it. This may result in false positives\n\t\t// but it's a good signal nonetheless and we can consume it with a grain of salt.\n\t\t// Inactive errors are usages of Objects that are unreferenced for at least a period of 7 days.\n\t\t// SweepReady errors are usages of Objects that will be deleted by GC Sweep!\n\t\tif (this.isSummarizerClient) {\n\t\t\tthis.pendingEventsQueue.push({\n\t\t\t\t...unrefEventProps, // Note: Contains some properties from INodeUsageProps as well\n\t\t\t\tusageType,\n\t\t\t\tstate,\n\t\t\t});\n\t\t} else {\n\t\t\t// For non-summarizer clients, only log \"Loaded\" type events since these objects may not be loaded in the\n\t\t\t// summarizer clients if they are based off of user actions (such as scrolling to content for these objects)\n\t\t\t// Events generated:\n\t\t\t// InactiveObject_Loaded, SweepReadyObject_Loaded\n\t\t\tif (usageType === \"Loaded\") {\n\t\t\t\tconst { id, fromId, headers, gcConfigs, ...detailedProps } = unrefEventProps;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${usageType}`,\n\t\t\t\t\t...tagCodeArtifacts({ pkg: packagePath?.join(\"/\") }),\n\t\t\t\t\tstack: generateStack(),\n\t\t\t\t\tid,\n\t\t\t\t\tfromId,\n\t\t\t\t\theaders: { ...headers },\n\t\t\t\t\tdetails: detailedProps,\n\t\t\t\t\tgcConfigs,\n\t\t\t\t};\n\n\t\t\t\t// These are logged as generic events and not errors because there can be false positives. The Tombstone\n\t\t\t\t// and Delete errors are separately logged and are reliable.\n\t\t\t\tthis.mc.logger.sendTelemetryEvent(event);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Logs telemetry when a tombstoned object is changed, revived or loaded.\n\t */\n\tprivate logTombstoneUsageTelemetry(\n\t\tunrefEventProps: Omit<IUnreferencedEventProps, \"state\" | \"usageType\">,\n\t\tnodeType: GCNodeType,\n\t\tusageType: NodeUsageType,\n\t\tpackagePath?: readonly string[],\n\t) {\n\t\t// This will log the following events:\n\t\t// GC_Tombstone_DataStore_Requested, GC_Tombstone_DataStore_Changed, GC_Tombstone_DataStore_Revived\n\t\t// GC_Tombstone_SubDataStore_Requested, GC_Tombstone_SubDataStore_Changed, GC_Tombstone_SubDataStore_Revived\n\t\t// GC_Tombstone_Blob_Requested, GC_Tombstone_Blob_Changed, GC_Tombstone_Blob_Revived\n\t\tconst { id, fromId, headers, gcConfigs, ...detailedProps } = unrefEventProps;\n\t\tconst eventUsageName = usageType === \"Loaded\" ? \"Requested\" : usageType;\n\t\tconst event = {\n\t\t\teventName: `GC_Tombstone_${nodeType}_${eventUsageName}`,\n\t\t\t...tagCodeArtifacts({ pkg: packagePath?.join(\"/\") }),\n\t\t\tstack: generateStack(),\n\t\t\tid,\n\t\t\tfromId,\n\t\t\theaders: { ...headers },\n\t\t\tdetails: detailedProps, // Also includes some properties from INodeUsageProps type\n\t\t\tgcConfigs,\n\t\t\ttombstoneFlags: {\n\t\t\t\tDisableTombstone: this.mc.config.getBoolean(disableTombstoneKey),\n\t\t\t\tThrowOnTombstoneUsage: this.mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\t\t\tThrowOnTombstoneLoad: this.mc.config.getBoolean(throwOnTombstoneLoadOverrideKey),\n\t\t\t},\n\t\t\tsweepFlags: {\n\t\t\t\tEnableSweepFlag: this.mc.config.getBoolean(runSweepKey),\n\t\t\t},\n\t\t};\n\n\t\tif (\n\t\t\t(usageType === \"Loaded\" &&\n\t\t\t\tthis.configs.throwOnTombstoneLoad &&\n\t\t\t\t!headers?.allowTombstone) ||\n\t\t\t(usageType === \"Changed\" && this.configs.throwOnTombstoneUsage)\n\t\t) {\n\t\t\tthis.mc.logger.sendErrorEvent(event);\n\t\t} else {\n\t\t\tthis.mc.logger.sendTelemetryEvent(event);\n\t\t}\n\t}\n\n\t/**\n\t * Log all new references or outbound routes in the current graph that haven't been explicitly notified to GC.\n\t * The principle is that every new reference or outbound route must be notified to GC via the\n\t * addedOutboundReference method. It it hasn't, its a bug and we want to identify these scenarios.\n\t *\n\t * In more simple terms:\n\t * Missing Explicit References = Current References - Previous References - Explicitly Added References;\n\t *\n\t * @param currentGCData - The GC data (reference graph) from the current GC run.\n\t * @param previousGCData - The GC data (reference graph) from the previous GC run.\n\t * @param explicitReferences - New references added explicity between the previous and the current run.\n\t */\n\tpublic logIfMissingExplicitReferences(\n\t\tcurrentGCData: IGarbageCollectionData,\n\t\tpreviousGCData: IGarbageCollectionData,\n\t\texplicitReferences: Map<string, string[]>,\n\t\tlogger: ITelemetryLoggerExt,\n\t) {\n\t\tfor (const [nodeId, currentOutboundRoutes] of Object.entries(currentGCData.gcNodes)) {\n\t\t\tconst previousRoutes = previousGCData.gcNodes[nodeId] ?? [];\n\t\t\tconst explicitRoutes = explicitReferences.get(nodeId) ?? [];\n\n\t\t\t/**\n\t\t\t * 1. For routes in the current GC data, routes that were not present in previous GC data and did not have\n\t\t\t * explicit references should be added to missing explicit routes list.\n\t\t\t * 2. Only include data store and blob routes since GC only works for these two.\n\t\t\t * Note: Due to a bug with de-duped blobs, only adding data store routes for now.\n\t\t\t * 3. Ignore DDS routes to their parent datastores since those were added implicitly. So, there won't be\n\t\t\t * explicit routes to them.\n\t\t\t */\n\t\t\tconst missingExplicitRoutes: string[] = [];\n\t\t\tfor (const route of currentOutboundRoutes) {\n\t\t\t\tconst nodeType = this.getNodeType(route);\n\t\t\t\tif (\n\t\t\t\t\t(nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob) &&\n\t\t\t\t\t!nodeId.startsWith(route) &&\n\t\t\t\t\t!previousRoutes.includes(route) &&\n\t\t\t\t\t!explicitRoutes.includes(route)\n\t\t\t\t) {\n\t\t\t\t\tmissingExplicitRoutes.push(route);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (missingExplicitRoutes.length > 0) {\n\t\t\t\t// Send as Generic not Error since there are known corner cases where this will fire.\n\t\t\t\t// E.g. If an old client re-references a node via an attach op (that doesn't include GC Data)\n\t\t\t\tlogger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"gcUnknownOutboundReferences\",\n\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\tid: nodeId,\n\t\t\t\t\t\troutes: JSON.stringify(missingExplicitRoutes),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log events that are pending in pendingEventsQueue. This is called after GC runs in the summarizer client\n\t * so that the state of an unreferenced node is updated.\n\t */\n\tpublic async logPendingEvents(logger: ITelemetryLoggerExt) {\n\t\t// Events sent come only from the summarizer client. In between summaries, events are pushed to a queue and at\n\t\t// summary time they are then logged.\n\t\t// Events generated:\n\t\t// InactiveObject_Loaded, InactiveObject_Changed, InactiveObject_Revived\n\t\t// SweepReadyObject_Loaded, SweepReadyObject_Changed, SweepReadyObject_Revived\n\t\tfor (const eventProps of this.pendingEventsQueue) {\n\t\t\tconst { usageType, state, id, fromId, headers, gcConfigs, ...detailedProps } =\n\t\t\t\teventProps;\n\t\t\t/**\n\t\t\t * Revived event is logged only if the node is active. If the node is not active, the reference to it was\n\t\t\t * from another unreferenced node and this scenario is not interesting to log.\n\t\t\t * Loaded and Changed events are logged only if the node is not active. If the node is active, it was\n\t\t\t * revived and a Revived event will be logged for it.\n\t\t\t */\n\t\t\tconst nodeStateTracker = this.getNodeStateTracker(detailedProps.trackedId); // Note: This is never SubDataStore path\n\t\t\tconst active =\n\t\t\t\tnodeStateTracker === undefined ||\n\t\t\t\tnodeStateTracker.state === UnreferencedState.Active;\n\t\t\tif ((usageType === \"Revived\") === active) {\n\t\t\t\tconst pkg = await this.getNodePackagePath(eventProps.id.value);\n\t\t\t\tconst fromPkg = eventProps.fromId\n\t\t\t\t\t? await this.getNodePackagePath(eventProps.fromId.value)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${usageType}`,\n\t\t\t\t\tid,\n\t\t\t\t\tfromId,\n\t\t\t\t\theaders: { ...headers },\n\t\t\t\t\tdetails: detailedProps,\n\t\t\t\t\tgcConfigs,\n\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\tpkg: pkg?.join(\"/\"),\n\t\t\t\t\t\tfromPkg: fromPkg?.join(\"/\"),\n\t\t\t\t\t}),\n\t\t\t\t};\n\n\t\t\t\t// These are logged as generic events and not errors because there can be false positives. The Tombstone\n\t\t\t\t// and Delete errors are separately logged and are reliable.\n\t\t\t\tlogger.sendTelemetryEvent(event);\n\t\t\t}\n\t\t}\n\t\tthis.pendingEventsQueue = [];\n\t}\n}\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEventExt & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = tagCodeArtifacts({ pkg: packagePath?.join(\"/\") })?.pkg;\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadOverrideKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n"]}
|
package/lib/gc/index.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
export { GarbageCollector } from "./garbageCollection.js";
|
|
6
|
-
export { nextGCVersion, defaultInactiveTimeoutMs, defaultSweepGracePeriodMs, defaultSessionExpiryDurationMs, GCNodeType, gcTestModeKey, gcDisableDataStoreSweepOptionName, gcDisableThrowOnTombstoneLoadOptionName, gcGenerationOptionName, GCFeatureMatrix, GCVersion, gcVersionUpgradeToV4Key, IGarbageCollectionRuntime, IGarbageCollector, IGarbageCollectorConfigs, IGarbageCollectorCreateParams, IGCMetadata, IGCMetadata_Deprecated, IGCResult, IGCRuntimeOptions, IMarkPhaseStats, ISweepPhaseStats, IGCStats, oneDayMs, runGCKey, runSessionExpiryKey, runSweepKey, stableGCVersion, disableAutoRecoveryKey, disableDatastoreSweepKey, detectOutboundRoutesViaDDSKey, UnreferencedState, throwOnTombstoneLoadOverrideKey, GarbageCollectionMessage, GarbageCollectionMessageType, ISweepMessage, } from "./gcDefinitions.js";
|
|
7
|
-
export { cloneGCData, concatGarbageCollectionStates,
|
|
6
|
+
export { nextGCVersion, defaultInactiveTimeoutMs, defaultSweepGracePeriodMs, defaultSessionExpiryDurationMs, GCNodeType, gcTestModeKey, gcDisableDataStoreSweepOptionName, gcDisableThrowOnTombstoneLoadOptionName, gcGenerationOptionName, GCFeatureMatrix, GCVersion, gcVersionUpgradeToV4Key, IGarbageCollectionRuntime, IGarbageCollector, IGarbageCollectorConfigs, IGarbageCollectorCreateParams, IGCMetadata, IGCMetadata_Deprecated, IGCNodeUpdatedProps, IGCResult, IGCRuntimeOptions, IMarkPhaseStats, ISweepPhaseStats, IGCStats, oneDayMs, runGCKey, runSessionExpiryKey, runSweepKey, stableGCVersion, disableAutoRecoveryKey, disableDatastoreSweepKey, detectOutboundRoutesViaDDSKey, UnreferencedState, throwOnTombstoneLoadOverrideKey, GarbageCollectionMessage, GarbageCollectionMessageType, ISweepMessage, } from "./gcDefinitions.js";
|
|
7
|
+
export { cloneGCData, concatGarbageCollectionStates, unpackChildNodesGCDetails, urlToGCNodePath, } from "./gcHelpers.js";
|
|
8
8
|
export { runGarbageCollection } from "./gcReferenceGraphAlgorithm.js";
|
|
9
9
|
export { IGarbageCollectionNodeData, IGarbageCollectionSnapshotData, IGarbageCollectionState, IGarbageCollectionSummaryDetailsLegacy, } from "./gcSummaryDefinitions.js";
|
|
10
10
|
export { gcStateBlobKey, GCSummaryStateTracker, IGCSummaryTrackingData, } from "./gcSummaryStateTracker.js";
|
package/lib/gc/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACN,aAAa,EACb,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,UAAU,EACV,aAAa,EACb,iCAAiC,EACjC,uCAAuC,EACvC,sBAAsB,EACtB,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,WAAW,EACX,sBAAsB,EACtB,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,wBAAwB,EACxB,6BAA6B,EAC7B,iBAAiB,EACjB,+BAA+B,EAC/B,wBAAwB,EACxB,4BAA4B,EAC5B,aAAa,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,WAAW,EACX,6BAA6B,EAC7B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACN,aAAa,EACb,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,UAAU,EACV,aAAa,EACb,iCAAiC,EACjC,uCAAuC,EACvC,sBAAsB,EACtB,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,wBAAwB,EACxB,6BAA6B,EAC7B,iBAAiB,EACjB,+BAA+B,EAC/B,wBAAwB,EACxB,4BAA4B,EAC5B,aAAa,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,WAAW,EACX,6BAA6B,EAC7B,yBAAyB,EACzB,eAAe,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EACN,0BAA0B,EAC1B,8BAA8B,EAC9B,uBAAuB,EACvB,sCAAsC,GACtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACN,cAAc,EACd,qBAAqB,EACrB,sBAAsB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC"}
|
package/lib/gc/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { GarbageCollector } from "./garbageCollection.js";
|
|
6
6
|
export { nextGCVersion, defaultInactiveTimeoutMs, defaultSweepGracePeriodMs, defaultSessionExpiryDurationMs, GCNodeType, gcTestModeKey, gcDisableDataStoreSweepOptionName, gcDisableThrowOnTombstoneLoadOptionName, gcGenerationOptionName, gcVersionUpgradeToV4Key, oneDayMs, runGCKey, runSessionExpiryKey, runSweepKey, stableGCVersion, disableAutoRecoveryKey, disableDatastoreSweepKey, detectOutboundRoutesViaDDSKey, UnreferencedState, throwOnTombstoneLoadOverrideKey, GarbageCollectionMessageType, } from "./gcDefinitions.js";
|
|
7
|
-
export { cloneGCData, concatGarbageCollectionStates,
|
|
7
|
+
export { cloneGCData, concatGarbageCollectionStates, unpackChildNodesGCDetails, urlToGCNodePath, } from "./gcHelpers.js";
|
|
8
8
|
export { runGarbageCollection } from "./gcReferenceGraphAlgorithm.js";
|
|
9
9
|
export { gcStateBlobKey, GCSummaryStateTracker, } from "./gcSummaryStateTracker.js";
|
|
10
10
|
export { GCTelemetryTracker, sendGCUnexpectedUsageEvent } from "./gcTelemetry.js";
|
package/lib/gc/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACN,aAAa,EACb,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,UAAU,EACV,aAAa,EACb,iCAAiC,EACjC,uCAAuC,EACvC,sBAAsB,EAGtB,uBAAuB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACN,aAAa,EACb,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,UAAU,EACV,aAAa,EACb,iCAAiC,EACjC,uCAAuC,EACvC,sBAAsB,EAGtB,uBAAuB,EAavB,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,sBAAsB,EACtB,wBAAwB,EACxB,6BAA6B,EAC7B,iBAAiB,EACjB,+BAA+B,EAE/B,4BAA4B,GAE5B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,WAAW,EACX,6BAA6B,EAC7B,yBAAyB,EACzB,eAAe,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAOtE,OAAO,EACN,cAAc,EACd,qBAAqB,GAErB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { GarbageCollector } from \"./garbageCollection.js\";\nexport {\n\tnextGCVersion,\n\tdefaultInactiveTimeoutMs,\n\tdefaultSweepGracePeriodMs,\n\tdefaultSessionExpiryDurationMs,\n\tGCNodeType,\n\tgcTestModeKey,\n\tgcDisableDataStoreSweepOptionName,\n\tgcDisableThrowOnTombstoneLoadOptionName,\n\tgcGenerationOptionName,\n\tGCFeatureMatrix,\n\tGCVersion,\n\tgcVersionUpgradeToV4Key,\n\tIGarbageCollectionRuntime,\n\tIGarbageCollector,\n\tIGarbageCollectorConfigs,\n\tIGarbageCollectorCreateParams,\n\tIGCMetadata,\n\tIGCMetadata_Deprecated,\n\tIGCNodeUpdatedProps,\n\tIGCResult,\n\tIGCRuntimeOptions,\n\tIMarkPhaseStats,\n\tISweepPhaseStats,\n\tIGCStats,\n\toneDayMs,\n\trunGCKey,\n\trunSessionExpiryKey,\n\trunSweepKey,\n\tstableGCVersion,\n\tdisableAutoRecoveryKey,\n\tdisableDatastoreSweepKey,\n\tdetectOutboundRoutesViaDDSKey,\n\tUnreferencedState,\n\tthrowOnTombstoneLoadOverrideKey,\n\tGarbageCollectionMessage,\n\tGarbageCollectionMessageType,\n\tISweepMessage,\n} from \"./gcDefinitions.js\";\nexport {\n\tcloneGCData,\n\tconcatGarbageCollectionStates,\n\tunpackChildNodesGCDetails,\n\turlToGCNodePath,\n} from \"./gcHelpers.js\";\nexport { runGarbageCollection } from \"./gcReferenceGraphAlgorithm.js\";\nexport {\n\tIGarbageCollectionNodeData,\n\tIGarbageCollectionSnapshotData,\n\tIGarbageCollectionState,\n\tIGarbageCollectionSummaryDetailsLegacy,\n} from \"./gcSummaryDefinitions.js\";\nexport {\n\tgcStateBlobKey,\n\tGCSummaryStateTracker,\n\tIGCSummaryTrackingData,\n} from \"./gcSummaryStateTracker.js\";\nexport { GCTelemetryTracker, sendGCUnexpectedUsageEvent } from \"./gcTelemetry.js\";\nexport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker.js\";\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
export { ISummaryRuntimeOptions, ISummaryBaseConfiguration, ISummaryConfigurationHeuristics, ISummaryConfigurationDisableSummarizer, ISummaryConfigurationDisableHeuristics, IContainerRuntimeOptions, isRuntimeMessage, RuntimeMessage, agentSchedulerId, ContainerRuntime, TombstoneResponseHeaderKey, InactiveResponseHeaderKey, ISummaryConfiguration, DefaultSummaryConfiguration, ICompressionRuntimeOptions, CompressionAlgorithms, } from "./containerRuntime.js";
|
|
5
|
+
export { ISummaryRuntimeOptions, ISummaryBaseConfiguration, ISummaryConfigurationHeuristics, ISummaryConfigurationDisableSummarizer, ISummaryConfigurationDisableHeuristics, IContainerRuntimeOptions, isRuntimeMessage, RuntimeMessage, agentSchedulerId, ContainerRuntime, DeletedResponseHeaderKey, TombstoneResponseHeaderKey, InactiveResponseHeaderKey, ISummaryConfiguration, DefaultSummaryConfiguration, ICompressionRuntimeOptions, CompressionAlgorithms, RuntimeHeaderData, } from "./containerRuntime.js";
|
|
6
6
|
export { ContainerMessageType, ContainerRuntimeMessage, IContainerRuntimeMessageCompatDetails, CompatModeBehavior, RecentlyAddedContainerRuntimeMessageDetails, UnknownContainerRuntimeMessage, } from "./messageTypes.js";
|
|
7
7
|
export { IBlobManagerLoadInfo } from "./blobManager.js";
|
|
8
8
|
export { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
9
9
|
export { detectOutboundReferences, RuntimeHeaders, ChannelCollectionFactory, AllowTombstoneRequestHeaderKey, AllowInactiveRequestHeaderKey, } from "./channelCollection.js";
|
|
10
|
-
export { GCNodeType, IGCMetadata, GCFeatureMatrix, GCVersion, IGCRuntimeOptions, IMarkPhaseStats, ISweepPhaseStats, IGCStats, } from "./gc/index.js";
|
|
10
|
+
export { GCNodeType, IGCMetadata, GCFeatureMatrix, GCVersion, IGCRuntimeOptions, IMarkPhaseStats, ISweepPhaseStats, IGCNodeUpdatedProps, IGCStats, } from "./gc/index.js";
|
|
11
11
|
export { IAckedSummary, ISummarizer, ISummarizeResults, ISummaryCancellationToken, neverCancelledSummaryToken, Summarizer, SummarizerStopReason, SummaryCollection, EnqueueSummarizeResult, IAckSummaryResult, IBaseSummarizeResult, IBroadcastSummaryResult, ICancellationToken, IConnectableRuntime, IContainerRuntimeMetadata, ICreateContainerMetadata, IEnqueueSummarizeOptions, IGenerateSummaryTreeResult, IGeneratedSummaryStats, INackSummaryResult, IOnDemandSummarizeOptions, IRefreshSummaryAckOptions, ISubmitSummaryOpResult, ISubmitSummaryOptions, ISerializedElection, ISummarizeOptions, ISummarizerEvents, ISummarizerInternalsProvider, ISummarizerRuntime, ISummarizingWarning, IUploadSummaryResult, SubmitSummaryResult, SummarizeResultPart, IClientSummaryWatcher, ISummary, ISummaryCollectionOpEvents, ISummaryAckMessage, ISummaryMetadataMessage, ISummaryNackMessage, ISummaryOpMessage, OpActionEventListener, OpActionEventName, ICancellableSummarizerController, SubmitSummaryFailureData, SummaryStage, IRetriableFailureResult, ISummarizeEventProps, IdCompressorMode, } from "./summary/index.js";
|
|
12
12
|
export { IChunkedOp, unpackRuntimeMessage } from "./opLifecycle/index.js";
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,sBAAsB,EACtB,yBAAyB,EACzB,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,wBAAwB,EACxB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,sBAAsB,EACtB,yBAAyB,EACzB,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,wBAAwB,EACxB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,EACrB,iBAAiB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,oBAAoB,EACpB,uBAAuB,EACvB,qCAAqC,EACrC,kBAAkB,EAClB,2CAA2C,EAC3C,8BAA8B,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACN,wBAAwB,EACxB,cAAc,EACd,wBAAwB,EACxB,8BAA8B,EAC9B,6BAA6B,GAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,UAAU,EACV,WAAW,EACX,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,QAAQ,GACR,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,aAAa,EACb,WAAW,EACX,iBAAiB,EACjB,yBAAyB,EACzB,0BAA0B,EAC1B,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,EACzB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,4BAA4B,EAC5B,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,gCAAgC,EAChC,wBAAwB,EACxB,YAAY,EACZ,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
export { isRuntimeMessage, RuntimeMessage, agentSchedulerId, ContainerRuntime, TombstoneResponseHeaderKey, InactiveResponseHeaderKey, DefaultSummaryConfiguration, CompressionAlgorithms, } from "./containerRuntime.js";
|
|
5
|
+
export { isRuntimeMessage, RuntimeMessage, agentSchedulerId, ContainerRuntime, DeletedResponseHeaderKey, TombstoneResponseHeaderKey, InactiveResponseHeaderKey, DefaultSummaryConfiguration, CompressionAlgorithms, } from "./containerRuntime.js";
|
|
6
6
|
export { ContainerMessageType, } from "./messageTypes.js";
|
|
7
7
|
export { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
8
8
|
export { detectOutboundReferences, RuntimeHeaders, ChannelCollectionFactory, AllowTombstoneRequestHeaderKey, AllowInactiveRequestHeaderKey, } from "./channelCollection.js";
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAON,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,0BAA0B,EAC1B,yBAAyB,EAEzB,2BAA2B,EAE3B,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAON,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,wBAAwB,EACxB,0BAA0B,EAC1B,yBAAyB,EAEzB,2BAA2B,EAE3B,qBAAqB,GAErB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACN,oBAAoB,GAMpB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EACN,wBAAwB,EACxB,cAAc,EACd,wBAAwB,EACxB,8BAA8B,EAC9B,6BAA6B,GAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,UAAU,GASV,MAAM,eAAe,CAAC;AACvB,OAAO,EAKN,0BAA0B,EAC1B,UAAU,EAEV,iBAAiB,GAyCjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAc,oBAAoB,EAAE,MAAM,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tISummaryRuntimeOptions,\n\tISummaryBaseConfiguration,\n\tISummaryConfigurationHeuristics,\n\tISummaryConfigurationDisableSummarizer,\n\tISummaryConfigurationDisableHeuristics,\n\tIContainerRuntimeOptions,\n\tisRuntimeMessage,\n\tRuntimeMessage,\n\tagentSchedulerId,\n\tContainerRuntime,\n\tDeletedResponseHeaderKey,\n\tTombstoneResponseHeaderKey,\n\tInactiveResponseHeaderKey,\n\tISummaryConfiguration,\n\tDefaultSummaryConfiguration,\n\tICompressionRuntimeOptions,\n\tCompressionAlgorithms,\n\tRuntimeHeaderData,\n} from \"./containerRuntime.js\";\nexport {\n\tContainerMessageType,\n\tContainerRuntimeMessage,\n\tIContainerRuntimeMessageCompatDetails,\n\tCompatModeBehavior,\n\tRecentlyAddedContainerRuntimeMessageDetails,\n\tUnknownContainerRuntimeMessage,\n} from \"./messageTypes.js\";\nexport { IBlobManagerLoadInfo } from \"./blobManager.js\";\nexport { FluidDataStoreRegistry } from \"./dataStoreRegistry.js\";\nexport {\n\tdetectOutboundReferences,\n\tRuntimeHeaders,\n\tChannelCollectionFactory,\n\tAllowTombstoneRequestHeaderKey,\n\tAllowInactiveRequestHeaderKey,\n} from \"./channelCollection.js\";\nexport {\n\tGCNodeType,\n\tIGCMetadata,\n\tGCFeatureMatrix,\n\tGCVersion,\n\tIGCRuntimeOptions,\n\tIMarkPhaseStats,\n\tISweepPhaseStats,\n\tIGCNodeUpdatedProps,\n\tIGCStats,\n} from \"./gc/index.js\";\nexport {\n\tIAckedSummary,\n\tISummarizer,\n\tISummarizeResults,\n\tISummaryCancellationToken,\n\tneverCancelledSummaryToken,\n\tSummarizer,\n\tSummarizerStopReason,\n\tSummaryCollection,\n\tEnqueueSummarizeResult,\n\tIAckSummaryResult,\n\tIBaseSummarizeResult,\n\tIBroadcastSummaryResult,\n\tICancellationToken,\n\tIConnectableRuntime,\n\tIContainerRuntimeMetadata,\n\tICreateContainerMetadata,\n\tIEnqueueSummarizeOptions,\n\tIGenerateSummaryTreeResult,\n\tIGeneratedSummaryStats,\n\tINackSummaryResult,\n\tIOnDemandSummarizeOptions,\n\tIRefreshSummaryAckOptions,\n\tISubmitSummaryOpResult,\n\tISubmitSummaryOptions,\n\tISerializedElection,\n\tISummarizeOptions,\n\tISummarizerEvents,\n\tISummarizerInternalsProvider,\n\tISummarizerRuntime,\n\tISummarizingWarning,\n\tIUploadSummaryResult,\n\tSubmitSummaryResult,\n\tSummarizeResultPart,\n\tIClientSummaryWatcher,\n\tISummary,\n\tISummaryCollectionOpEvents,\n\tISummaryAckMessage,\n\tISummaryMetadataMessage,\n\tISummaryNackMessage,\n\tISummaryOpMessage,\n\tOpActionEventListener,\n\tOpActionEventName,\n\tICancellableSummarizerController,\n\tSubmitSummaryFailureData,\n\tSummaryStage,\n\tIRetriableFailureResult,\n\tISummarizeEventProps,\n\tIdCompressorMode,\n} from \"./summary/index.js\";\nexport { IChunkedOp, unpackRuntimeMessage } from \"./opLifecycle/index.js\";\n"]}
|
package/lib/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/container-runtime";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-rc.2.0.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-rc.2.0.4";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
package/lib/packageVersion.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-rc.2.0.
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-rc.2.0.4\";\n"]}
|
|
@@ -43,6 +43,15 @@ describe("Garbage Collection Tests", () => {
|
|
|
43
43
|
}
|
|
44
44
|
return sweepReadyRoutes;
|
|
45
45
|
}
|
|
46
|
+
/** More concise signature for calling IGarbageCollector.nodeUpdated */
|
|
47
|
+
function nodeUpdated(garbageCollector, path, reason, timestampMs, packagePath) {
|
|
48
|
+
garbageCollector.nodeUpdated({
|
|
49
|
+
node: { type: "DataStore", path },
|
|
50
|
+
reason,
|
|
51
|
+
timestampMs,
|
|
52
|
+
packagePath,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
46
55
|
function createGarbageCollector(params = {}) {
|
|
47
56
|
const { createParams = {}, gcBlobsMap = new Map(), gcMetadata = {}, closeFn = () => { }, isSummarizerClient = true, getGCData = async () => defaultGCData, } = params;
|
|
48
57
|
const getNodeType = (nodePath) => {
|
|
@@ -278,7 +287,7 @@ describe("Garbage Collection Tests", () => {
|
|
|
278
287
|
assert.equal(gc.unreferencedNodesState.get(nodes[0])?.state, UnreferencedState.TombstoneReady, "node 0 should be TombstoneReady");
|
|
279
288
|
assert.deepEqual(gc.tombstones, [nodes[0]], "node 0 should be in the Tombstones list");
|
|
280
289
|
// Simulate usage to trigger TombstoneLoaded op.
|
|
281
|
-
|
|
290
|
+
nodeUpdated(gc, nodes[0], "Loaded");
|
|
282
291
|
const [gcTombstoneLoadedMessage] = spies.gc.submitMessage.args[0];
|
|
283
292
|
assert.deepEqual(gcTombstoneLoadedMessage, {
|
|
284
293
|
type: ContainerMessageType.GC,
|
|
@@ -313,8 +322,8 @@ describe("Garbage Collection Tests", () => {
|
|
|
313
322
|
// Mock node loaded and changed activity for all the nodes in the graph.
|
|
314
323
|
async function mockNodeChangesAndRunGC(garbageCollector) {
|
|
315
324
|
nodes.forEach((nodeId) => {
|
|
316
|
-
|
|
317
|
-
|
|
325
|
+
nodeUpdated(garbageCollector, nodeId, "Loaded", Date.now(), testPkgPath);
|
|
326
|
+
nodeUpdated(garbageCollector, nodeId, "Changed", Date.now(), testPkgPath);
|
|
318
327
|
});
|
|
319
328
|
await garbageCollector.collectGarbage({});
|
|
320
329
|
}
|
|
@@ -430,8 +439,8 @@ describe("Garbage Collection Tests", () => {
|
|
|
430
439
|
validateNoEvents();
|
|
431
440
|
// Expire the timeout and validate that only revived event is generated for node 2.
|
|
432
441
|
clock.tick(1);
|
|
433
|
-
|
|
434
|
-
|
|
442
|
+
nodeUpdated(garbageCollector, nodes[2], "Changed", Date.now(), testPkgPath);
|
|
443
|
+
nodeUpdated(garbageCollector, nodes[2], "Loaded", Date.now(), testPkgPath);
|
|
435
444
|
garbageCollector.addedOutboundReference(nodes[1], nodes[2]);
|
|
436
445
|
await garbageCollector.collectGarbage({});
|
|
437
446
|
for (const event of mockLogger.events) {
|
|
@@ -510,8 +519,8 @@ describe("Garbage Collection Tests", () => {
|
|
|
510
519
|
// Run GC to trigger loading the GC details from the base summary. Will also generate Delete logs
|
|
511
520
|
await garbageCollector.collectGarbage({});
|
|
512
521
|
// Validate that all events are logged as expected.
|
|
513
|
-
|
|
514
|
-
|
|
522
|
+
nodeUpdated(garbageCollector, nodes[3], "Loaded", Date.now(), testPkgPath);
|
|
523
|
+
nodeUpdated(garbageCollector, nodes[3], "Changed", Date.now(), testPkgPath);
|
|
515
524
|
await garbageCollector.collectGarbage({});
|
|
516
525
|
mockLogger.assertMatch([
|
|
517
526
|
{
|
|
@@ -573,8 +582,8 @@ describe("Garbage Collection Tests", () => {
|
|
|
573
582
|
// Initialize the base state which happens during runtime initialization.
|
|
574
583
|
await garbageCollector.initializeBaseState();
|
|
575
584
|
// Simulate sending op and loading the node in unreferenced state.
|
|
576
|
-
|
|
577
|
-
|
|
585
|
+
nodeUpdated(garbageCollector, nodes[3], "Loaded", Date.now(), testPkgPath);
|
|
586
|
+
nodeUpdated(garbageCollector, nodes[3], "Changed", Date.now(), testPkgPath);
|
|
578
587
|
// Log pending events explicitly. This is needed because summarizer clients don't log these events
|
|
579
588
|
// until the next GC run which calls this function.
|
|
580
589
|
await garbageCollector.telemetryTracker.logPendingEvents(garbageCollector.mc.logger);
|
|
@@ -639,8 +648,8 @@ describe("Garbage Collection Tests", () => {
|
|
|
639
648
|
defaultGCData.gcNodes[nodes[2]] = [];
|
|
640
649
|
await garbageCollector.collectGarbage({});
|
|
641
650
|
// Validate that no events are generated since none of the timeouts have passed
|
|
642
|
-
|
|
643
|
-
|
|
651
|
+
nodeUpdated(garbageCollector, nodes[3], "Loaded", Date.now(), testPkgPath);
|
|
652
|
+
nodeUpdated(garbageCollector, nodes[3], "Changed", Date.now(), testPkgPath);
|
|
644
653
|
await garbageCollector.collectGarbage({});
|
|
645
654
|
mockLogger.assertMatchNone([
|
|
646
655
|
{
|
|
@@ -714,9 +723,9 @@ describe("Garbage Collection Tests", () => {
|
|
|
714
723
|
defaultGCData.gcNodes[nodes[2]] = [];
|
|
715
724
|
await garbageCollector.collectGarbage({});
|
|
716
725
|
// Validate that all events are logged as expected.
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
726
|
+
nodeUpdated(garbageCollector, nodes[3], "Loaded", Date.now(), testPkgPath);
|
|
727
|
+
nodeUpdated(garbageCollector, nodes[1], "Changed", Date.now(), testPkgPath);
|
|
728
|
+
nodeUpdated(garbageCollector, nodes[2], "Changed", Date.now(), testPkgPath);
|
|
720
729
|
await garbageCollector.collectGarbage({});
|
|
721
730
|
mockLogger.assertMatch([
|
|
722
731
|
{
|