@fluidframework/container-runtime 2.80.0 → 2.81.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 (47) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/container-runtime.test-files.tar +0 -0
  3. package/dist/dataStoreContext.d.ts.map +1 -1
  4. package/dist/dataStoreContext.js +1 -0
  5. package/dist/dataStoreContext.js.map +1 -1
  6. package/dist/deltaScheduler.d.ts.map +1 -1
  7. package/dist/deltaScheduler.js +1 -0
  8. package/dist/deltaScheduler.js.map +1 -1
  9. package/dist/gc/gcHelpers.d.ts.map +1 -1
  10. package/dist/gc/gcHelpers.js +1 -0
  11. package/dist/gc/gcHelpers.js.map +1 -1
  12. package/dist/packageVersion.d.ts +1 -1
  13. package/dist/packageVersion.js +1 -1
  14. package/dist/packageVersion.js.map +1 -1
  15. package/dist/runtimeLayerCompatState.d.ts +2 -2
  16. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  17. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +1 -0
  18. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  19. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js +8 -8
  20. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  21. package/eslint.config.mts +4 -4
  22. package/lib/dataStoreContext.d.ts.map +1 -1
  23. package/lib/dataStoreContext.js +1 -0
  24. package/lib/dataStoreContext.js.map +1 -1
  25. package/lib/deltaScheduler.d.ts.map +1 -1
  26. package/lib/deltaScheduler.js +1 -0
  27. package/lib/deltaScheduler.js.map +1 -1
  28. package/lib/gc/gcHelpers.d.ts.map +1 -1
  29. package/lib/gc/gcHelpers.js +1 -0
  30. package/lib/gc/gcHelpers.js.map +1 -1
  31. package/lib/packageVersion.d.ts +1 -1
  32. package/lib/packageVersion.js +1 -1
  33. package/lib/packageVersion.js.map +1 -1
  34. package/lib/runtimeLayerCompatState.d.ts +2 -2
  35. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  36. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +1 -0
  37. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  38. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js +8 -8
  39. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  40. package/package.json +22 -22
  41. package/src/dataStoreContext.ts +1 -0
  42. package/src/deltaScheduler.ts +1 -0
  43. package/src/gc/gcHelpers.ts +1 -0
  44. package/src/packageVersion.ts +1 -1
  45. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +1 -0
  46. package/src/summary/summaryDelayLoadedModule/summaryGenerator.ts +8 -8
  47. package/.eslintrc.cjs +0 -30
@@ -1 +1 @@
1
- {"version":3,"file":"gcHelpers.js","sourceRoot":"","sources":["../../src/gc/gcHelpers.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 { assert } from \"@fluidframework/core-utils/internal\";\nimport type { ISnapshotTree } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype IGarbageCollectionDetailsBase,\n\tgcBlobPrefix,\n\tgcDeletedBlobKey,\n\tgcTombstoneBlobKey,\n\ttype IGarbageCollectionData,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport type { IConfigProvider } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype GCFeatureMatrix,\n\ttype GCVersion,\n\ttype IGCMetadata,\n\tgcVersionUpgradeToV4Key,\n\tnextGCVersion,\n\tstableGCVersion,\n} from \"./gcDefinitions.js\";\nimport type {\n\tIGarbageCollectionNodeData,\n\tIGarbageCollectionSnapshotData,\n\tIGarbageCollectionState,\n} from \"./gcSummaryDefinitions.js\";\n\nexport function getGCVersion(metadata?: IGCMetadata): GCVersion {\n\tif (!metadata) {\n\t\t// Force to 0/disallowed in prior versions\n\t\treturn 0;\n\t}\n\treturn metadata.gcFeature ?? 0;\n}\n\n/**\n * Indicates what GC version is in effect for new GC data being written in this session\n */\nexport function getGCVersionInEffect(configProvider: IConfigProvider): number {\n\t// If version upgrade is not enabled, fall back to the stable GC version.\n\treturn configProvider.getBoolean(gcVersionUpgradeToV4Key) === true\n\t\t? nextGCVersion\n\t\t: stableGCVersion;\n}\n\n/**\n * Indicates whether Sweep is allowed for this document based on the persisted GC Feature Matrix and current gcGeneration.\n * This applies to the entire Sweep Phase the same - both Tombstone Enforcement (i.e. should loading a Tombstone fail?) and Deletion.\n *\n * In order to protect old documents that were created at a time when known bugs exist that violate GC's invariants\n * such that enforcing GC Sweep would cause legitimate data loss, the container author may increment the generation value for Sweep\n * such that containers created with a different value will not be subjected to GC Sweep.\n *\n * If no generation is provided, Sweep will be enabled for all documents.\n *\n * For backwards compatibility, the current generation value is also compared against the persisted gcTombstoneGeneration if present.\n *\n * @param featureMatrix - The GC Feature Matrix, containing the persisted generation value\n * @param currentGeneration - The current app-provided gcGeneration value\n * @returns true if GC Sweep should be allowed for this document\n */\nexport function shouldAllowGcSweep(\n\tfeatureMatrix: GCFeatureMatrix,\n\tcurrentGeneration: number | undefined,\n): boolean {\n\t// If no Generation value is provided for this session, default to true\n\tif (currentGeneration === undefined) {\n\t\treturn true;\n\t}\n\n\t// tombstoneGeneration is the predecessor and needs to be supported for back-compat reasons\n\tconst targetGeneration = featureMatrix.tombstoneGeneration ?? featureMatrix.gcGeneration;\n\n\treturn currentGeneration === targetGeneration;\n}\n\n/**\n * Sorts the given GC state as per the id of the GC nodes. It also sorts the outbound routes array of each node.\n */\nexport function generateSortedGCState(\n\tgcState: IGarbageCollectionState,\n): IGarbageCollectionState {\n\tconst sortableArray: [string, IGarbageCollectionNodeData][] = Object.entries(\n\t\tgcState.gcNodes,\n\t);\n\tsortableArray.sort(([a], [b]) => a.localeCompare(b));\n\tconst sortedGCState: IGarbageCollectionState = { gcNodes: {} };\n\tfor (const [nodeId, nodeData] of sortableArray) {\n\t\tnodeData.outboundRoutes.sort();\n\t\tsortedGCState.gcNodes[nodeId] = nodeData;\n\t}\n\treturn sortedGCState;\n}\n\n/**\n * Concatenates the given GC states and returns the concatenated GC state.\n */\nexport function concatGarbageCollectionStates(\n\tgcState1: IGarbageCollectionState,\n\tgcState2: IGarbageCollectionState,\n): IGarbageCollectionState {\n\tconst combinedGCNodes: { [id: string]: IGarbageCollectionNodeData } = {};\n\tfor (const [nodeId, nodeData] of Object.entries(gcState1.gcNodes)) {\n\t\tcombinedGCNodes[nodeId] = {\n\t\t\toutboundRoutes: [...nodeData.outboundRoutes],\n\t\t\tunreferencedTimestampMs: nodeData.unreferencedTimestampMs,\n\t\t};\n\t}\n\n\tfor (const [nodeId, nodeData] of Object.entries(gcState2.gcNodes)) {\n\t\tlet combineNodeData = combinedGCNodes[nodeId];\n\t\tif (combineNodeData === undefined) {\n\t\t\tcombineNodeData = {\n\t\t\t\toutboundRoutes: [...nodeData.outboundRoutes],\n\t\t\t\tunreferencedTimestampMs: nodeData.unreferencedTimestampMs,\n\t\t\t};\n\t\t} else {\n\t\t\t// Validate that same node doesn't have different unreferenced timestamp.\n\t\t\tif (\n\t\t\t\tnodeData.unreferencedTimestampMs !== undefined &&\n\t\t\t\tcombineNodeData.unreferencedTimestampMs !== undefined\n\t\t\t) {\n\t\t\t\tassert(\n\t\t\t\t\tnodeData.unreferencedTimestampMs === combineNodeData.unreferencedTimestampMs,\n\t\t\t\t\t0x5d7 /* Two entries for the same GC node with different unreferenced timestamp */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcombineNodeData = {\n\t\t\t\toutboundRoutes: [\n\t\t\t\t\t...new Set([...nodeData.outboundRoutes, ...combineNodeData.outboundRoutes]),\n\t\t\t\t],\n\t\t\t\tunreferencedTimestampMs:\n\t\t\t\t\tnodeData.unreferencedTimestampMs ?? combineNodeData.unreferencedTimestampMs,\n\t\t\t};\n\t\t}\n\t\tcombinedGCNodes[nodeId] = combineNodeData;\n\t}\n\treturn { gcNodes: combinedGCNodes };\n}\n\n/**\n * Helper function that clones the GC data.\n * @param gcData - The GC data to clone.\n * @returns a clone of the given GC data.\n */\nexport function cloneGCData(gcData: IGarbageCollectionData): IGarbageCollectionData {\n\tconst clonedGCNodes: { [id: string]: string[] } = {};\n\tfor (const [id, outboundRoutes] of Object.entries(gcData.gcNodes)) {\n\t\tclonedGCNodes[id] = [...outboundRoutes];\n\t}\n\treturn {\n\t\tgcNodes: clonedGCNodes,\n\t};\n}\n\n/**\n * Concatenates the given GC data and returns the concatenated GC data.\n */\nexport function concatGarbageCollectionData(\n\tgcData1: IGarbageCollectionData,\n\tgcData2: IGarbageCollectionData,\n): IGarbageCollectionData {\n\tconst combinedGCData: IGarbageCollectionData = cloneGCData(gcData1);\n\tfor (const [id, routes] of Object.entries(gcData2.gcNodes)) {\n\t\tif (combinedGCData.gcNodes[id] === undefined) {\n\t\t\tcombinedGCData.gcNodes[id] = [...routes];\n\t\t} else {\n\t\t\tconst combinedRoutes = [...routes, ...combinedGCData.gcNodes[id]];\n\t\t\tcombinedGCData.gcNodes[id] = [...new Set(combinedRoutes)];\n\t\t}\n\t}\n\treturn combinedGCData;\n}\n\n/**\n * Gets the base garbage collection state from the given snapshot tree. It contains GC state, deleted nodes and\n * tombstones. The GC state may be written into multiple blobs. Merge the GC state from all such blobs into one.\n */\nexport async function getGCDataFromSnapshot(\n\tgcSnapshotTree: ISnapshotTree,\n\treadAndParseBlob: <T>(id: string) => Promise<T>,\n): Promise<IGarbageCollectionSnapshotData> {\n\tlet rootGCState: IGarbageCollectionState = { gcNodes: {} };\n\tlet tombstones: string[] | undefined;\n\tlet deletedNodes: string[] | undefined;\n\tfor (const key of Object.keys(gcSnapshotTree.blobs)) {\n\t\t// Update deleted nodes blob.\n\t\tif (key === gcDeletedBlobKey) {\n\t\t\tdeletedNodes = await readAndParseBlob<string[]>(gcSnapshotTree.blobs[key]);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Update tombstone blob.\n\t\tif (key === gcTombstoneBlobKey) {\n\t\t\ttombstones = await readAndParseBlob<string[]>(gcSnapshotTree.blobs[key]);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Skip blobs that do not start with the GC prefix.\n\t\tif (!key.startsWith(gcBlobPrefix)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst blobId = gcSnapshotTree.blobs[key];\n\t\tif (blobId === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst gcState = await readAndParseBlob<IGarbageCollectionState>(blobId);\n\t\tassert(gcState !== undefined, 0x5d8 /* GC blob missing from snapshot */);\n\t\t// Merge the GC state of this blob into the root GC state.\n\t\trootGCState = concatGarbageCollectionStates(rootGCState, gcState);\n\t}\n\treturn { gcState: rootGCState, tombstones, deletedNodes };\n}\n\n/**\n * Helper function that unpacks the GC details of the children from a given node's GC details.\n * @param gcDetails - The GC details of a node.\n * @returns A map of GC details of each children of the the given node.\n */\nexport function unpackChildNodesGCDetails(\n\tgcDetails: IGarbageCollectionDetailsBase,\n): Map<string, IGarbageCollectionDetailsBase> {\n\tconst childGCDetailsMap: Map<string, IGarbageCollectionDetailsBase> = new Map();\n\n\t// If GC data is not available, bail out.\n\tif (gcDetails.gcData === undefined) {\n\t\treturn childGCDetailsMap;\n\t}\n\n\tconst gcNodes = gcDetails.gcData.gcNodes;\n\tfor (const [id, outboundRoutes] of Object.entries(gcNodes)) {\n\t\t// Skip self-node since only children GC data is to be generated.\n\t\tif (id === \"/\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst childId = id.split(\"/\")[1];\n\t\tassert(\n\t\t\tchildId !== undefined,\n\t\t\t0x9fe /* node id should be an absolute route with child id part */,\n\t\t);\n\t\tlet childGCNodeId = id.slice(childId.length + 1);\n\t\t// GC node id always begins with \"/\". Handle the special case where a child's id in the parent's GC nodes is\n\t\t// of format `/root`. In this case, the childId is root and childGCNodeId is \"\". Make childGCNodeId = \"/\".\n\t\tif (childGCNodeId === \"\") {\n\t\t\tchildGCNodeId = \"/\";\n\t\t}\n\n\t\tlet childGCDetails = childGCDetailsMap.get(childId);\n\t\tif (childGCDetails === undefined) {\n\t\t\tchildGCDetails = { gcData: { gcNodes: {} }, usedRoutes: [] };\n\t\t}\n\t\t// gcData should not undefined as its always at least initialized as empty above.\n\t\tassert(\n\t\t\tchildGCDetails.gcData !== undefined,\n\t\t\t0x5da /* Child GC data should have been initialized */,\n\t\t);\n\t\tchildGCDetails.gcData.gcNodes[childGCNodeId] = [...new Set(outboundRoutes)];\n\t\tchildGCDetailsMap.set(childId, childGCDetails);\n\t}\n\n\tif (gcDetails.usedRoutes === undefined) {\n\t\treturn childGCDetailsMap;\n\t}\n\n\t// Remove the node's self used route, if any, and generate the children used routes.\n\tconst usedRoutes = gcDetails.usedRoutes.filter((route) => route !== \"\" && route !== \"/\");\n\tfor (const route of usedRoutes) {\n\t\tconst childId = route.split(\"/\")[1];\n\t\tassert(\n\t\t\tchildId !== undefined,\n\t\t\t0x9ff /* used route should be an absolute route with child id part */,\n\t\t);\n\t\tconst childUsedRoute = route.slice(childId.length + 1);\n\n\t\tconst childGCDetails = childGCDetailsMap.get(childId);\n\t\tassert(\n\t\t\tchildGCDetails?.usedRoutes !== undefined,\n\t\t\t0x5dc /* This should have be initialized when generate GC nodes above */,\n\t\t);\n\n\t\tchildGCDetails.usedRoutes.push(childUsedRoute);\n\t\tchildGCDetailsMap.set(childId, childGCDetails);\n\t}\n\treturn childGCDetailsMap;\n}\n\n/**\n * Trims the leading and trailing slashes from the given string.\n * @param str - A string that may contain leading and / or trailing slashes.\n * @returns A new string without leading and trailing slashes.\n */\nfunction trimLeadingAndTrailingSlashes(str: string): string {\n\treturn str.replace(/^\\/+|\\/+$/g, \"\");\n}\n\n/**\n * Reformats a request URL to match expected format for a GC node path\n */\nexport function urlToGCNodePath(url: string): string {\n\treturn `/${trimLeadingAndTrailingSlashes(url.split(\"?\")[0])}`;\n}\n\n/**\n * Pulls out the first path segment and formats it as a GC Node path\n * e.g. \"/dataStoreId/ddsId\" yields \"/dataStoreId\"\n */\nexport function dataStoreNodePathOnly(subDataStorePath: string): string {\n\treturn `/${subDataStorePath.split(\"/\")[1]}`;\n}\n\n/**\n * Utility to implement compat behaviors given an unknown message type\n * The parameters are typed to support compile-time enforcement of handling all known types/behaviors\n *\n * @param _unknownGCMessageType - Typed as never to ensure all known types have been\n * handled before calling this function (e.g. in a switch statement).\n * @param compatBehavior - Typed redundantly with CompatModeBehavior to ensure handling is added when updating that type\n */\nexport function compatBehaviorAllowsGCMessageType(\n\t_unknownGCMessageType: never,\n\tcompatBehavior: \"Ignore\" | \"FailToProcess\" | undefined,\n): boolean {\n\t// undefined defaults to same behavior as \"FailToProcess\"\n\treturn compatBehavior === \"Ignore\";\n}\n"]}
1
+ {"version":3,"file":"gcHelpers.js","sourceRoot":"","sources":["../../src/gc/gcHelpers.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 { assert } from \"@fluidframework/core-utils/internal\";\nimport type { ISnapshotTree } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype IGarbageCollectionDetailsBase,\n\tgcBlobPrefix,\n\tgcDeletedBlobKey,\n\tgcTombstoneBlobKey,\n\ttype IGarbageCollectionData,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport type { IConfigProvider } from \"@fluidframework/telemetry-utils/internal\";\n\nimport {\n\ttype GCFeatureMatrix,\n\ttype GCVersion,\n\ttype IGCMetadata,\n\tgcVersionUpgradeToV4Key,\n\tnextGCVersion,\n\tstableGCVersion,\n} from \"./gcDefinitions.js\";\nimport type {\n\tIGarbageCollectionNodeData,\n\tIGarbageCollectionSnapshotData,\n\tIGarbageCollectionState,\n} from \"./gcSummaryDefinitions.js\";\n\nexport function getGCVersion(metadata?: IGCMetadata): GCVersion {\n\tif (!metadata) {\n\t\t// Force to 0/disallowed in prior versions\n\t\treturn 0;\n\t}\n\treturn metadata.gcFeature ?? 0;\n}\n\n/**\n * Indicates what GC version is in effect for new GC data being written in this session\n */\nexport function getGCVersionInEffect(configProvider: IConfigProvider): number {\n\t// If version upgrade is not enabled, fall back to the stable GC version.\n\treturn configProvider.getBoolean(gcVersionUpgradeToV4Key) === true\n\t\t? nextGCVersion\n\t\t: stableGCVersion;\n}\n\n/**\n * Indicates whether Sweep is allowed for this document based on the persisted GC Feature Matrix and current gcGeneration.\n * This applies to the entire Sweep Phase the same - both Tombstone Enforcement (i.e. should loading a Tombstone fail?) and Deletion.\n *\n * In order to protect old documents that were created at a time when known bugs exist that violate GC's invariants\n * such that enforcing GC Sweep would cause legitimate data loss, the container author may increment the generation value for Sweep\n * such that containers created with a different value will not be subjected to GC Sweep.\n *\n * If no generation is provided, Sweep will be enabled for all documents.\n *\n * For backwards compatibility, the current generation value is also compared against the persisted gcTombstoneGeneration if present.\n *\n * @param featureMatrix - The GC Feature Matrix, containing the persisted generation value\n * @param currentGeneration - The current app-provided gcGeneration value\n * @returns true if GC Sweep should be allowed for this document\n */\nexport function shouldAllowGcSweep(\n\tfeatureMatrix: GCFeatureMatrix,\n\tcurrentGeneration: number | undefined,\n): boolean {\n\t// If no Generation value is provided for this session, default to true\n\tif (currentGeneration === undefined) {\n\t\treturn true;\n\t}\n\n\t// tombstoneGeneration is the predecessor and needs to be supported for back-compat reasons\n\tconst targetGeneration = featureMatrix.tombstoneGeneration ?? featureMatrix.gcGeneration;\n\n\treturn currentGeneration === targetGeneration;\n}\n\n/**\n * Sorts the given GC state as per the id of the GC nodes. It also sorts the outbound routes array of each node.\n */\nexport function generateSortedGCState(\n\tgcState: IGarbageCollectionState,\n): IGarbageCollectionState {\n\tconst sortableArray: [string, IGarbageCollectionNodeData][] = Object.entries(\n\t\tgcState.gcNodes,\n\t);\n\tsortableArray.sort(([a], [b]) => a.localeCompare(b));\n\tconst sortedGCState: IGarbageCollectionState = { gcNodes: {} };\n\tfor (const [nodeId, nodeData] of sortableArray) {\n\t\tnodeData.outboundRoutes.sort();\n\t\tsortedGCState.gcNodes[nodeId] = nodeData;\n\t}\n\treturn sortedGCState;\n}\n\n/**\n * Concatenates the given GC states and returns the concatenated GC state.\n */\nexport function concatGarbageCollectionStates(\n\tgcState1: IGarbageCollectionState,\n\tgcState2: IGarbageCollectionState,\n): IGarbageCollectionState {\n\tconst combinedGCNodes: { [id: string]: IGarbageCollectionNodeData } = {};\n\tfor (const [nodeId, nodeData] of Object.entries(gcState1.gcNodes)) {\n\t\tcombinedGCNodes[nodeId] = {\n\t\t\toutboundRoutes: [...nodeData.outboundRoutes],\n\t\t\tunreferencedTimestampMs: nodeData.unreferencedTimestampMs,\n\t\t};\n\t}\n\n\tfor (const [nodeId, nodeData] of Object.entries(gcState2.gcNodes)) {\n\t\tlet combineNodeData = combinedGCNodes[nodeId];\n\t\tif (combineNodeData === undefined) {\n\t\t\tcombineNodeData = {\n\t\t\t\toutboundRoutes: [...nodeData.outboundRoutes],\n\t\t\t\tunreferencedTimestampMs: nodeData.unreferencedTimestampMs,\n\t\t\t};\n\t\t} else {\n\t\t\t// Validate that same node doesn't have different unreferenced timestamp.\n\t\t\tif (\n\t\t\t\tnodeData.unreferencedTimestampMs !== undefined &&\n\t\t\t\tcombineNodeData.unreferencedTimestampMs !== undefined\n\t\t\t) {\n\t\t\t\tassert(\n\t\t\t\t\tnodeData.unreferencedTimestampMs === combineNodeData.unreferencedTimestampMs,\n\t\t\t\t\t0x5d7 /* Two entries for the same GC node with different unreferenced timestamp */,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcombineNodeData = {\n\t\t\t\toutboundRoutes: [\n\t\t\t\t\t...new Set([...nodeData.outboundRoutes, ...combineNodeData.outboundRoutes]),\n\t\t\t\t],\n\t\t\t\tunreferencedTimestampMs:\n\t\t\t\t\tnodeData.unreferencedTimestampMs ?? combineNodeData.unreferencedTimestampMs,\n\t\t\t};\n\t\t}\n\t\tcombinedGCNodes[nodeId] = combineNodeData;\n\t}\n\treturn { gcNodes: combinedGCNodes };\n}\n\n/**\n * Helper function that clones the GC data.\n * @param gcData - The GC data to clone.\n * @returns a clone of the given GC data.\n */\nexport function cloneGCData(gcData: IGarbageCollectionData): IGarbageCollectionData {\n\tconst clonedGCNodes: { [id: string]: string[] } = {};\n\tfor (const [id, outboundRoutes] of Object.entries(gcData.gcNodes)) {\n\t\tclonedGCNodes[id] = [...outboundRoutes];\n\t}\n\treturn {\n\t\tgcNodes: clonedGCNodes,\n\t};\n}\n\n/**\n * Concatenates the given GC data and returns the concatenated GC data.\n */\nexport function concatGarbageCollectionData(\n\tgcData1: IGarbageCollectionData,\n\tgcData2: IGarbageCollectionData,\n): IGarbageCollectionData {\n\tconst combinedGCData: IGarbageCollectionData = cloneGCData(gcData1);\n\tfor (const [id, routes] of Object.entries(gcData2.gcNodes)) {\n\t\tif (combinedGCData.gcNodes[id] === undefined) {\n\t\t\tcombinedGCData.gcNodes[id] = [...routes];\n\t\t} else {\n\t\t\tconst combinedRoutes = [...routes, ...combinedGCData.gcNodes[id]];\n\t\t\tcombinedGCData.gcNodes[id] = [...new Set(combinedRoutes)];\n\t\t}\n\t}\n\treturn combinedGCData;\n}\n\n/**\n * Gets the base garbage collection state from the given snapshot tree. It contains GC state, deleted nodes and\n * tombstones. The GC state may be written into multiple blobs. Merge the GC state from all such blobs into one.\n */\nexport async function getGCDataFromSnapshot(\n\tgcSnapshotTree: ISnapshotTree,\n\treadAndParseBlob: <T>(id: string) => Promise<T>,\n): Promise<IGarbageCollectionSnapshotData> {\n\tlet rootGCState: IGarbageCollectionState = { gcNodes: {} };\n\tlet tombstones: string[] | undefined;\n\tlet deletedNodes: string[] | undefined;\n\tfor (const key of Object.keys(gcSnapshotTree.blobs)) {\n\t\t// Update deleted nodes blob.\n\t\tif (key === gcDeletedBlobKey) {\n\t\t\tdeletedNodes = await readAndParseBlob<string[]>(gcSnapshotTree.blobs[key]);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Update tombstone blob.\n\t\tif (key === gcTombstoneBlobKey) {\n\t\t\ttombstones = await readAndParseBlob<string[]>(gcSnapshotTree.blobs[key]);\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Skip blobs that do not start with the GC prefix.\n\t\tif (!key.startsWith(gcBlobPrefix)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst blobId = gcSnapshotTree.blobs[key];\n\t\tif (blobId === undefined) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst gcState = await readAndParseBlob<IGarbageCollectionState>(blobId);\n\t\tassert(gcState !== undefined, 0x5d8 /* GC blob missing from snapshot */);\n\t\t// Merge the GC state of this blob into the root GC state.\n\t\trootGCState = concatGarbageCollectionStates(rootGCState, gcState);\n\t}\n\treturn { gcState: rootGCState, tombstones, deletedNodes };\n}\n\n/**\n * Helper function that unpacks the GC details of the children from a given node's GC details.\n * @param gcDetails - The GC details of a node.\n * @returns A map of GC details of each children of the the given node.\n */\nexport function unpackChildNodesGCDetails(\n\tgcDetails: IGarbageCollectionDetailsBase,\n): Map<string, IGarbageCollectionDetailsBase> {\n\tconst childGCDetailsMap: Map<string, IGarbageCollectionDetailsBase> = new Map();\n\n\t// If GC data is not available, bail out.\n\tif (gcDetails.gcData === undefined) {\n\t\treturn childGCDetailsMap;\n\t}\n\n\tconst gcNodes = gcDetails.gcData.gcNodes;\n\tfor (const [id, outboundRoutes] of Object.entries(gcNodes)) {\n\t\t// Skip self-node since only children GC data is to be generated.\n\t\tif (id === \"/\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst childId = id.split(\"/\")[1];\n\t\tassert(\n\t\t\tchildId !== undefined,\n\t\t\t0x9fe /* node id should be an absolute route with child id part */,\n\t\t);\n\t\tlet childGCNodeId = id.slice(childId.length + 1);\n\t\t// GC node id always begins with \"/\". Handle the special case where a child's id in the parent's GC nodes is\n\t\t// of format `/root`. In this case, the childId is root and childGCNodeId is \"\". Make childGCNodeId = \"/\".\n\t\tif (childGCNodeId === \"\") {\n\t\t\tchildGCNodeId = \"/\";\n\t\t}\n\n\t\tlet childGCDetails = childGCDetailsMap.get(childId);\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\tif (childGCDetails === undefined) {\n\t\t\tchildGCDetails = { gcData: { gcNodes: {} }, usedRoutes: [] };\n\t\t}\n\t\t// gcData should not undefined as its always at least initialized as empty above.\n\t\tassert(\n\t\t\tchildGCDetails.gcData !== undefined,\n\t\t\t0x5da /* Child GC data should have been initialized */,\n\t\t);\n\t\tchildGCDetails.gcData.gcNodes[childGCNodeId] = [...new Set(outboundRoutes)];\n\t\tchildGCDetailsMap.set(childId, childGCDetails);\n\t}\n\n\tif (gcDetails.usedRoutes === undefined) {\n\t\treturn childGCDetailsMap;\n\t}\n\n\t// Remove the node's self used route, if any, and generate the children used routes.\n\tconst usedRoutes = gcDetails.usedRoutes.filter((route) => route !== \"\" && route !== \"/\");\n\tfor (const route of usedRoutes) {\n\t\tconst childId = route.split(\"/\")[1];\n\t\tassert(\n\t\t\tchildId !== undefined,\n\t\t\t0x9ff /* used route should be an absolute route with child id part */,\n\t\t);\n\t\tconst childUsedRoute = route.slice(childId.length + 1);\n\n\t\tconst childGCDetails = childGCDetailsMap.get(childId);\n\t\tassert(\n\t\t\tchildGCDetails?.usedRoutes !== undefined,\n\t\t\t0x5dc /* This should have be initialized when generate GC nodes above */,\n\t\t);\n\n\t\tchildGCDetails.usedRoutes.push(childUsedRoute);\n\t\tchildGCDetailsMap.set(childId, childGCDetails);\n\t}\n\treturn childGCDetailsMap;\n}\n\n/**\n * Trims the leading and trailing slashes from the given string.\n * @param str - A string that may contain leading and / or trailing slashes.\n * @returns A new string without leading and trailing slashes.\n */\nfunction trimLeadingAndTrailingSlashes(str: string): string {\n\treturn str.replace(/^\\/+|\\/+$/g, \"\");\n}\n\n/**\n * Reformats a request URL to match expected format for a GC node path\n */\nexport function urlToGCNodePath(url: string): string {\n\treturn `/${trimLeadingAndTrailingSlashes(url.split(\"?\")[0])}`;\n}\n\n/**\n * Pulls out the first path segment and formats it as a GC Node path\n * e.g. \"/dataStoreId/ddsId\" yields \"/dataStoreId\"\n */\nexport function dataStoreNodePathOnly(subDataStorePath: string): string {\n\treturn `/${subDataStorePath.split(\"/\")[1]}`;\n}\n\n/**\n * Utility to implement compat behaviors given an unknown message type\n * The parameters are typed to support compile-time enforcement of handling all known types/behaviors\n *\n * @param _unknownGCMessageType - Typed as never to ensure all known types have been\n * handled before calling this function (e.g. in a switch statement).\n * @param compatBehavior - Typed redundantly with CompatModeBehavior to ensure handling is added when updating that type\n */\nexport function compatBehaviorAllowsGCMessageType(\n\t_unknownGCMessageType: never,\n\tcompatBehavior: \"Ignore\" | \"FailToProcess\" | undefined,\n): boolean {\n\t// undefined defaults to same behavior as \"FailToProcess\"\n\treturn compatBehavior === \"Ignore\";\n}\n"]}
@@ -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.80.0";
8
+ export declare const pkgVersion = "2.81.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/container-runtime";
8
- export const pkgVersion = "2.80.0";
8
+ export const pkgVersion = "2.81.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -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,QAAQ,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.80.0\";\n"]}
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,QAAQ,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.81.0\";\n"]}
@@ -17,11 +17,11 @@ export declare const runtimeCoreCompatDetails: {
17
17
  /**
18
18
  * The package version of the Runtime layer.
19
19
  */
20
- readonly pkgVersion: "2.80.0";
20
+ readonly pkgVersion: "2.81.0";
21
21
  /**
22
22
  * The current generation of the Runtime layer.
23
23
  */
24
- readonly generation: 3;
24
+ readonly generation: 4;
25
25
  };
26
26
  /**
27
27
  * Runtime's compatibility details that is exposed to the Loader layer.
@@ -1 +1 @@
1
- {"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../../src/summary/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"summarizerNodeWithGc.d.ts","sourceRoot":"","sources":["../../../src/summary/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"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"}
@@ -279,6 +279,7 @@ export class SummarizerNodeWithGC extends SummarizerNode {
279
279
  // If the child route used routes are not defined, initialize it now and it can be used for all child nodes
280
280
  // created until this summarization process is completed. This is an optimization to unpack the used routes
281
281
  // only when needed.
282
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
282
283
  if (this.wipChildNodesUsedRoutes === undefined) {
283
284
  this.wipChildNodesUsedRoutes = unpackChildNodesUsedRoutes(this.usedRoutes);
284
285
  }
@@ -1 +1 @@
1
- {"version":3,"file":"summarizerNodeWithGc.js","sourceRoot":"","sources":["../../../src/summary/summarizerNode/summarizerNodeWithGc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAS1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACpF,OAAO,EACN,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,0CAA0C,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAkBrD;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,oBAAqB,SAAQ,cAAc;IA+BvD;;;OAGG;IACH,YACC,MAA4B,EAC5B,mBAAwC,EACxC,MAAmC,EACnC,gBAAwB,EACxB,oBAA4B;IAC5B;;OAEG;IACH,kCAA2C,EAC3C,gBAAuC,EACtB,WAAmE,EACpF,kBAAiE;IACjE;;OAEG;IACH,WAAoB;QAEpB,KAAK,CACJ,MAAM,EACN,mBAAmB,EACnB,MAAM,EACN,gBAAgB,EAChB,oBAAoB,EACpB,kCAAkC,EAClC,gBAAgB,EAChB,WAAW,CACX,CAAC;QAhBe,gBAAW,GAAX,WAAW,CAAwD;QAjCrF,4FAA4F;QACpF,wBAAmB,GAAY,KAAK,CAAC;QAS7C,mHAAmH;QACnH,iHAAiH;QACjH,iHAAiH;QACzG,eAAU,GAAa,CAAC,EAAE,CAAC,CAAC;QAsCnC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,KAAK,IAAI,CAAC;QAE7C,IAAI,CAAC,cAAc,GAAG,IAAI,WAAW,CAAC,KAAK,IAAI,EAAE;YAChD,OAAO,CAAC,MAAM,kBAAkB,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,wBAAwB,GAAG,IAAI,WAAW,CAAC,KAAK,IAAI,EAAE;YAC1D,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC/B,OAAO,yBAAyB,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACxF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,iBAAiB;QAC9B,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC9B,OAAO;QACR,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC;QAEhD,yGAAyG;QACzG,6CAA6C;QAC7C,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC9B,OAAO;QACR,CAAC;QACD,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAEhC,8GAA8G;QAC9G,oGAAoG;QACpG,iEAAiE;QACjE,IAAI,aAAa,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,aAAa,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAC5C,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;YACvD,IAAI,CAAC,mBAAmB,GAAG,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;QACjE,CAAC;IACF,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,SAAS,CAAC,SAAkB,KAAK;QAC7C,MAAM,CACL,CAAC,IAAI,CAAC,UAAU,EAChB,KAAK,CAAC,iEAAiE,CACvE,CAAC;QACF,MAAM,CACL,IAAI,CAAC,WAAW,KAAK,SAAS,EAC9B,KAAK,CAAC,uDAAuD,CAC7D,CAAC;QAEF,8GAA8G;QAC9G,6GAA6G;QAC7G,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAE/B,gHAAgH;QAChH,yGAAyG;QACzG,0GAA0G;QAC1G,6BAA6B;QAC7B,IACC,IAAI,CAAC,cAAc;YACnB,CAAC,MAAM;YACP,CAAC,IAAI,CAAC,cAAc,EAAE;YACtB,IAAI,CAAC,MAAM,KAAK,SAAS,EACxB,CAAC;YACF,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;OAEG;IACI,YAAY,CAClB,uBAA+B,EAC/B,aAAmC,EACnC,sBAA8B;QAE9B,sFAAsF;QACtF,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACtB,MAAM,CACL,IAAI,CAAC,uBAAuB,KAAK,SAAS,EAC1C,KAAK,CAAC,iFAAiF,CACvF,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,YAAY,CAAC,uBAAuB,EAAE,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAC3F,CAAC;IAED;;;;;;;OAOG;IACO,mBAAmB,CAAC,mBAA4B;QACzD,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO;gBACN,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,iBAAiB;gBACzB,EAAE,EAAE;oBACH,GAAG,EAAE,gBAAgB,CAAC,YAAY;oBAClC,KAAK,EAAE,IAAI,CAAC,eAAe;iBAC3B;gBACD,wFAAwF;gBACxF,iBAAiB,EAAE,CAAC;aACpB,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;IACvD,CAAC;IAEO,WAAW;QAClB,kEAAkE;QAClE,8FAA8F;QAC9F,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,uBAAuB,KAAK,SAAS,EAAE,CAAC;YACnE,OAAO,KAAK,CAAC;QACd,CAAC;QACD;;;;;;;;;;WAUG;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;;OAMG;IACO,mBAAmB,CAAC,cAAsB,EAAE,mBAA4B;QACjF,IAAI,uBAA2C,CAAC;QAChD,gDAAgD;QAChD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACtB,uBAAuB,GAAG,IAAI,CAAC,uBAAuB,CAAC;QACxD,CAAC;QAED,KAAK,CAAC,mBAAmB,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;QAE/D,iEAAiE;QACjE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACtB,MAAM,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YACrE,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;gBACtC,MAAM,wBAAwB,GAAG;oBAChC,oBAAoB,EAAE,uBAAuB;oBAC7C,GAAG,kBAAkB;iBACrB,CAAC;gBACF,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC;YACrE,CAAC;QACF,CAAC;IACF,CAAC;IAED;;OAEG;IACI,YAAY;QAClB,IAAI,CAAC,uBAAuB,GAAG,SAAS,CAAC;QACzC,IAAI,CAAC,uBAAuB,GAAG,SAAS,CAAC;QACzC,KAAK,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED;;;OAGG;IACO,+BAA+B,CACxC,cAAsB,EACtB,uBAA+B;QAE/B,6FAA6F;QAC7F,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACtB,MAAM,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YACrE,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;gBACtC,6EAA6E;gBAC7E,MAAM,iBAAiB,GAAG,kBAA8C,CAAC;gBACzE,IAAI,iBAAiB,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;oBAC1D,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,gCAAgC,EAAE;wBAChE,cAAc;wBACd,uBAAuB;wBACvB,GAAG,gBAAgB,CAAC;4BACnB,EAAE,EAAE,IAAI,CAAC,eAAe;yBACxB,CAAC;qBACF,CAAC,CAAC;oBACH,IAAI,CAAC,MAAM,CAAC,cAAc,CACzB;wBACC,SAAS,EAAE,KAAK,CAAC,OAAO;qBACxB,EACD,KAAK,CACL,CAAC;oBACF,MAAM,KAAK,CAAC;gBACb,CAAC;gBACD,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,KAAK,CACpC,iBAAiB,CAAC,oBAAoB,CAC1B,CAAC;YACf,CAAC;QACF,CAAC;QAED,OAAO,KAAK,CAAC,+BAA+B,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;IACvF,CAAC;IAED;;OAEG;IACI,WAAW;IACjB;;OAEG;IACH,mBAAwC;IACxC;;OAEG;IACH,EAAU;IACV;;;;OAIG;IACH,WAA2C,EAC3C,SAAsC,EAAE,EACxC,WAAmE;QAEnE,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACzF;;;;;WAKG;QACH,MAAM,uBAAuB,GAAG,KAAK,IAA4C,EAAE;YAClF,MAAM,uBAAuB,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC;YACpE,OAAO,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAC9C,CAAC,CAAC;QAEF,MAAM,aAAa,GAAwB,IAAI,CAAC,wBAAwB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC1F,MAAM,KAAK,GAAG,IAAI,oBAAoB,CACrC,IAAI,CAAC,MAAM,EACX,mBAAmB,EACnB;YACC,GAAG,MAAM;YACT,gGAAgG;YAChG,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU;SAChD,EACD,aAAa,CAAC,eAAe,EAC7B,aAAa,CAAC,oBAAoB,EAClC,aAAa,CAAC,kCAAkC,EAChD,IAAI,CAAC,gBAAgB,EACrB,WAAW,EACX,uBAAuB,EACvB,aAAa,CAAC,eAAe,CAC7B,CAAC;QAEF,yGAAyG;QACzG,uEAAuE;QACvE,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACO,qBAAqB,CAAC,KAA2B,EAAE,EAAU;QACtE,KAAK,CAAC,qBAAqB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEvC,6GAA6G;QAC7G,0GAA0G;QAC1G,2GAA2G;QAC3G,uDAAuD;QACvD,IAAI,IAAI,CAAC,uBAAuB,KAAK,SAAS,EAAE,CAAC;YAChD,2GAA2G;YAC3G,2GAA2G;YAC3G,oBAAoB;YACpB,IAAI,IAAI,CAAC,uBAAuB,KAAK,SAAS,EAAE,CAAC;gBAChD,IAAI,CAAC,uBAAuB,GAAG,0BAA0B,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC5E,CAAC;YACD,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;QAED,qFAAqF;QACrF,KAAK,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC;YACrE,MAAM,oBAAoB,GAAG,cAA0C,CAAC;YACxE,IAAI,oBAAoB,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;gBAC7D,MAAM,mBAAmB,GAAG,0BAA0B,CACrD,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,oBAAoB,CAAa,CACjE,CAAC;gBACF,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAChE,MAAM,uBAAuB,GAAG;oBAC/B,GAAG,oBAAoB;oBACvB,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC;iBACzD,CAAC;gBACF,KAAK,CAAC,iBAAiB,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;YACvD,CAAC;QACF,CAAC;IACF,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,EAAU;QAC5B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,QAAQ,CAAC,EAAU;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAyB,CAAC;IACtD,CAAC;IAEM,YAAY;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACtE,CAAC;IAEM,gBAAgB,CAAC,UAAoB;QAC3C,4GAA4G;QAC5G,yBAAyB;QACzB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QAEpC,6GAA6G;QAC7G,+BAA+B;QAC/B,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,mBAAmB,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChE,CAAC;IACF,CAAC;IAED;;OAEG;IACO,UAAU;QACnB,OAAO,IAAI,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC5D,CAAC;IAED;;OAEG;IACK,cAAc;QACrB,OAAO,KAAK,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACK,mBAAmB;QAC1B,uEAAuE;QACvE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,CACN,IAAI,CAAC,mBAAmB,KAAK,SAAS;YACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAC5E,CAAC;IACH,CAAC;CACD;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC7C,MAA4B,EAC5B,mBAAwC,EACxC,oBAA4B,EAC5B,uBAA2C,EAC3C,SAAsC,EAAE,EACxC,WAAmE,EACnE,kBAAiE,EACrC,EAAE,CAC9B,IAAI,oBAAoB,CACvB,MAAM,EACN,mBAAmB,EACnB,MAAM,EACN,EAAE,CAAC,qBAAqB,EACxB,oBAAoB,EACpB,uBAAuB,EACvB,SAAS,CAAC,sBAAsB,EAChC,WAAW,EACX,kBAAkB,EAClB,EAAE,CAAC,iBAAiB,CACpB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, LazyPromise } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIGarbageCollectionData,\n\tCreateChildSummarizerNodeParam,\n\tIGarbageCollectionDetailsBase,\n\tISummarizerNodeConfigWithGC,\n\tISummarizerNodeWithGC,\n\tSummarizeInternalFn,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { unpackChildNodesUsedRoutes } from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tLoggingError,\n\tTelemetryDataTag,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { cloneGCData, unpackChildNodesGCDetails } from \"../../gc/index.js\";\n\nimport { SummarizerNode } from \"./summarizerNode.js\";\nimport type {\n\tICreateChildDetails,\n\tIStartSummaryResult,\n\tISummarizerNodeRootContract,\n\tPendingSummaryInfo,\n\tValidateSummaryResult,\n} from \"./summarizerNodeUtils.js\";\n\nexport interface IRootSummarizerNodeWithGC\n\textends ISummarizerNodeWithGC,\n\t\tISummarizerNodeRootContract {}\n\n// Extend PendingSummaryInfo to add used routes tracking it.\ninterface PendingSummaryInfoWithGC extends PendingSummaryInfo {\n\tserializedUsedRoutes: string | undefined;\n}\n\n/**\n * Extends the functionality of SummarizerNode to manage this node's garbage collection data:\n *\n * - Adds a new API `getGCData` to return GC data of this node.\n *\n * - Caches the result of `getGCData` to be used if nothing changes between summaries.\n *\n * - Manages the used routes of this node. These are used to identify if this node is referenced in the document\n * and to determine if the node's used state changed since last summary.\n *\n *- Adds trackState param to summarize. If trackState is false, it bypasses the SummarizerNode and calls\n * directly into summarizeInternal method.\n */\nexport class SummarizerNodeWithGC extends SummarizerNode implements IRootSummarizerNodeWithGC {\n\t// Tracks the work-in-progress used routes during summary.\n\tprivate wipSerializedUsedRoutes: string | undefined;\n\n\t// Tracks the work-in-progress used routes of child nodes during summary.\n\tprivate wipChildNodesUsedRoutes: Map<string, string[]> | undefined;\n\n\t// This is the last known used routes of this node as seen by the server as part of a summary.\n\tprivate referenceUsedRoutes: string[] | undefined;\n\n\t// The base GC details of this node used to initialize the GC state.\n\tprivate readonly baseGCDetailsP: Promise<IGarbageCollectionDetailsBase>;\n\n\t// Keeps track of whether we have loaded the base details to ensure that we only do it once.\n\tprivate baseGCDetailsLoaded: boolean = false;\n\n\t// The base GC details for the child nodes. This is passed to child nodes when creating them.\n\tprivate readonly childNodesBaseGCDetailsP: Promise<\n\t\tMap<string, IGarbageCollectionDetailsBase>\n\t>;\n\n\tprivate gcData: IGarbageCollectionData | undefined;\n\n\t// Set used routes to have self route by default. This makes the node referenced by default. This is done to ensure\n\t// that this node is not marked as collected when running GC has been disabled. Once, the option to disable GC is\n\t// removed (from runGC flag in IContainerRuntimeOptions), this should be changed to be have no routes by default.\n\tprivate usedRoutes: string[] = [\"\"];\n\n\t// True if GC is disabled for this node. If so, do not track GC specific state for a summary.\n\tprivate readonly gcDisabled: boolean;\n\n\t/**\n\t * Do not call constructor directly.\n\t * Use createRootSummarizerNodeWithGC to create root node, or createChild to create child nodes.\n\t */\n\tpublic constructor(\n\t\tlogger: ITelemetryBaseLogger,\n\t\tsummarizeInternalFn: SummarizeInternalFn,\n\t\tconfig: ISummarizerNodeConfigWithGC,\n\t\t_summaryHandleId: string,\n\t\tchangeSequenceNumber: number,\n\t\t/**\n\t\t * Summary reference sequence number, i.e. last sequence number seen when it was created\n\t\t */\n\t\tlastSummaryReferenceSequenceNumber?: number,\n\t\twipSummaryLogger?: ITelemetryBaseLogger,\n\t\tprivate readonly getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n\t\tgetBaseGCDetailsFn?: () => Promise<IGarbageCollectionDetailsBase>,\n\t\t/**\n\t\t * A unique id of this node to be logged when sending telemetry.\n\t\t */\n\t\ttelemetryId?: string,\n\t) {\n\t\tsuper(\n\t\t\tlogger,\n\t\t\tsummarizeInternalFn,\n\t\t\tconfig,\n\t\t\t_summaryHandleId,\n\t\t\tchangeSequenceNumber,\n\t\t\tlastSummaryReferenceSequenceNumber,\n\t\t\twipSummaryLogger,\n\t\t\ttelemetryId,\n\t\t);\n\n\t\tthis.gcDisabled = config.gcDisabled === true;\n\n\t\tthis.baseGCDetailsP = new LazyPromise(async () => {\n\t\t\treturn (await getBaseGCDetailsFn?.()) ?? { usedRoutes: [] };\n\t\t});\n\n\t\tthis.childNodesBaseGCDetailsP = new LazyPromise(async () => {\n\t\t\tawait this.loadBaseGCDetails();\n\t\t\treturn unpackChildNodesGCDetails({ gcData: this.gcData, usedRoutes: this.usedRoutes });\n\t\t});\n\t}\n\n\t/**\n\t * Loads state from this node's initial GC summary details. This contains the following data from the last summary\n\t * seen by the server for this client:\n\t * - usedRoutes: This is used to figure out if the used state of this node changed since last summary.\n\t * - gcData: The garbage collection data of this node that is required for running GC.\n\t */\n\tprivate async loadBaseGCDetails(): Promise<void> {\n\t\tif (this.baseGCDetailsLoaded) {\n\t\t\treturn;\n\t\t}\n\t\tconst baseGCDetails = await this.baseGCDetailsP;\n\n\t\t// Possible race - If there were parallel calls to loadBaseGCDetails, we want to make sure that we update\n\t\t// the state from the base details only once.\n\t\tif (this.baseGCDetailsLoaded) {\n\t\t\treturn;\n\t\t}\n\t\tthis.baseGCDetailsLoaded = true;\n\n\t\t// Update GC data, used routes and reference used routes. The used routes are sorted because they are compared\n\t\t// across GC runs to check if they changed. Sorting ensures that the elements are in the same order.\n\t\t// If the GC details has GC data, initialize our GC data from it.\n\t\tif (baseGCDetails.gcData !== undefined) {\n\t\t\tthis.gcData = cloneGCData(baseGCDetails.gcData);\n\t\t}\n\t\tif (baseGCDetails.usedRoutes !== undefined) {\n\t\t\tthis.usedRoutes = [...baseGCDetails.usedRoutes].sort();\n\t\t\tthis.referenceUsedRoutes = [...baseGCDetails.usedRoutes].sort();\n\t\t}\n\t}\n\n\t/**\n\t * Returns the GC data of this node. If nothing has changed since last summary, it tries to reuse the data from\n\t * the previous summary. Else, it gets new GC data from the underlying Fluid object.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tassert(\n\t\t\t!this.gcDisabled,\n\t\t\t0x1b2 /* \"Getting GC data should not be called when GC is disabled!\" */,\n\t\t);\n\t\tassert(\n\t\t\tthis.getGCDataFn !== undefined,\n\t\t\t0x1b3 /* \"GC data cannot be retrieved without getGCDataFn\" */,\n\t\t);\n\n\t\t// Load GC details from the initial summary, if not already loaded. If this is the first time this function is\n\t\t// called and the node's data has not changed since last summary, the GC data in initial details is returned.\n\t\tawait this.loadBaseGCDetails();\n\n\t\t// If there is no new data since last summary and we have GC data from the previous run, return it. The previous\n\t\t// GC data may not be available if loaded from a snapshot with either GC disabled or before GC was added.\n\t\t// Note - canReuseHandle is checked to be consistent with summarize - generate GC data for nodes for which\n\t\t// summary must be generated.\n\t\tif (\n\t\t\tthis.canReuseHandle &&\n\t\t\t!fullGC &&\n\t\t\t!this.hasDataChanged() &&\n\t\t\tthis.gcData !== undefined\n\t\t) {\n\t\t\treturn cloneGCData(this.gcData);\n\t\t}\n\n\t\tconst gcData = await this.getGCDataFn(fullGC);\n\t\tthis.gcData = cloneGCData(gcData);\n\t\treturn gcData;\n\t}\n\n\t/**\n\t * Called during the start of a summary. Updates the work-in-progress used routes.\n\t */\n\tpublic startSummary(\n\t\treferenceSequenceNumber: number,\n\t\tsummaryLogger: ITelemetryBaseLogger,\n\t\tlatestSummaryRefSeqNum: number,\n\t): IStartSummaryResult {\n\t\t// If GC is disabled, skip setting wip used routes since we should not track GC state.\n\t\tif (!this.gcDisabled) {\n\t\t\tassert(\n\t\t\t\tthis.wipSerializedUsedRoutes === undefined,\n\t\t\t\t0x1b4 /* \"We should not already be tracking used routes when to track a new summary\" */,\n\t\t\t);\n\t\t}\n\t\treturn super.startSummary(referenceSequenceNumber, summaryLogger, latestSummaryRefSeqNum);\n\t}\n\n\t/**\n\t * Validates that the in-progress summary is correct for all nodes, i.e., GC should have run for non-skipped nodes.\n\t * @param parentSkipRecursion - true if the parent of this node skipped recursing the child nodes when running GC.\n\t * In that case, the children will not have work-in-progress state.\n\t *\n\t * @returns ValidateSummaryResult which contains a boolean success indicating whether the validation was successful.\n\t * In case of failure, additional information is returned indicating type of failure and where it was.\n\t */\n\tprotected validateSummaryCore(parentSkipRecursion: boolean): ValidateSummaryResult {\n\t\tif (this.wasGCMissed()) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\treason: \"NodeDidNotRunGC\",\n\t\t\t\tid: {\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\tvalue: this.telemetryNodeId,\n\t\t\t\t},\n\t\t\t\t// These errors are usually transient and should go away when summarize / GC is retried.\n\t\t\t\tretryAfterSeconds: 1,\n\t\t\t};\n\t\t}\n\t\treturn super.validateSummaryCore(parentSkipRecursion);\n\t}\n\n\tprivate wasGCMissed(): boolean {\n\t\t// If GC is disabled, it should not have run so it was not missed.\n\t\t// Otherwise, GC should have been called on this node and wipSerializedUsedRoutes must be set.\n\t\tif (this.gcDisabled || this.wipSerializedUsedRoutes !== undefined) {\n\t\t\treturn false;\n\t\t}\n\t\t/**\n\t\t * The absence of wip used routes indicates that GC was not run on this node. This can happen if:\n\t\t * 1. A child node was created after GC was already run on the parent. For example, a data store\n\t\t * is realized (loaded) after GC was run on it creating summarizer nodes for its DDSes. In this\n\t\t * case, the parent will pass on used routes to the child nodes and it will have wip used routes.\n\t\t * 2. A new node was created but GC was never run on it. This can mean that the GC data generated\n\t\t * during summarize is incomplete.\n\t\t *\n\t\t * This happens due to scenarios such as data store created during summarize. Such errors should go away when\n\t\t * summarize is attempted again.\n\t\t */\n\t\treturn true;\n\t}\n\n\t/**\n\t * Called after summary has been uploaded to the server. Add the work-in-progress state to the pending\n\t * summary queue. We track this until we get an ack from the server for this summary.\n\t * @param proposalHandle - The handle of the summary that was uploaded to the server.\n\t * @param parentSkipRecursion - true if the parent of this node skipped recursing the child nodes when summarizing.\n\t * In that case, the children will not have work-in-progress state.\n\t */\n\tprotected completeSummaryCore(proposalHandle: string, parentSkipRecursion: boolean): void {\n\t\tlet wipSerializedUsedRoutes: string | undefined;\n\t\t// If GC is disabled, don't set wip used routes.\n\t\tif (!this.gcDisabled) {\n\t\t\twipSerializedUsedRoutes = this.wipSerializedUsedRoutes;\n\t\t}\n\n\t\tsuper.completeSummaryCore(proposalHandle, parentSkipRecursion);\n\n\t\t// If GC is disabled, skip setting pending summary with GC state.\n\t\tif (!this.gcDisabled) {\n\t\t\tconst pendingSummaryInfo = this.pendingSummaries.get(proposalHandle);\n\t\t\tif (pendingSummaryInfo !== undefined) {\n\t\t\t\tconst pendingSummaryInfoWithGC = {\n\t\t\t\t\tserializedUsedRoutes: wipSerializedUsedRoutes,\n\t\t\t\t\t...pendingSummaryInfo,\n\t\t\t\t};\n\t\t\t\tthis.pendingSummaries.set(proposalHandle, pendingSummaryInfoWithGC);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Clears the work-in-progress state.\n\t */\n\tpublic clearSummary(): void {\n\t\tthis.wipSerializedUsedRoutes = undefined;\n\t\tthis.wipChildNodesUsedRoutes = undefined;\n\t\tsuper.clearSummary();\n\t}\n\n\t/**\n\t * Called when we get an ack from the server for a summary we sent. Update the reference state of this node\n\t * from the state in the pending summary queue.\n\t */\n\tprotected refreshLatestSummaryFromPending(\n\t\tproposalHandle: string,\n\t\treferenceSequenceNumber: number,\n\t): void {\n\t\t// If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n\t\tif (!this.gcDisabled) {\n\t\t\tconst pendingSummaryInfo = this.pendingSummaries.get(proposalHandle);\n\t\t\tif (pendingSummaryInfo !== undefined) {\n\t\t\t\t// If a pending summary exists, it must have used routes since GC is enabled.\n\t\t\t\tconst summaryNodeWithGC = pendingSummaryInfo as PendingSummaryInfoWithGC;\n\t\t\t\tif (summaryNodeWithGC.serializedUsedRoutes === undefined) {\n\t\t\t\t\tconst error = new LoggingError(\"MissingGCStateInPendingSummary\", {\n\t\t\t\t\t\tproposalHandle,\n\t\t\t\t\t\treferenceSequenceNumber,\n\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\tid: this.telemetryNodeId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: error.message,\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tthis.referenceUsedRoutes = JSON.parse(\n\t\t\t\t\tsummaryNodeWithGC.serializedUsedRoutes,\n\t\t\t\t) as string[];\n\t\t\t}\n\t\t}\n\n\t\treturn super.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n\t}\n\n\t/**\n\t * Override the createChild method to return an instance of SummarizerNodeWithGC.\n\t */\n\tpublic createChild(\n\t\t/**\n\t\t * Summarize function\n\t\t */\n\t\tsummarizeInternalFn: SummarizeInternalFn,\n\t\t/**\n\t\t * Initial id or path part of this node\n\t\t */\n\t\tid: string,\n\t\t/**\n\t\t * Information needed to create the node.\n\t\t * If it is from a base summary, it will assert that a summary has been seen.\n\t\t * Attach information if it is created from an attach op.\n\t\t */\n\t\tcreateParam: CreateChildSummarizerNodeParam,\n\t\tconfig: ISummarizerNodeConfigWithGC = {},\n\t\tgetGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n\t): ISummarizerNodeWithGC {\n\t\tassert(!this.children.has(id), 0x1b6 /* \"Create SummarizerNode child already exists\" */);\n\t\t/**\n\t\t * Update the child node's base GC details from this node's current GC details instead of updating from the base\n\t\t * GC details of this node. This will handle scenarios where the GC details was updated during refresh from\n\t\t * snapshot and the child node wasn't created then. If a child is created after that, its GC details should be\n\t\t * the one from the downloaded snapshot and not the base GC details.\n\t\t */\n\t\tconst getChildBaseGCDetailsFn = async (): Promise<IGarbageCollectionDetailsBase> => {\n\t\t\tconst childNodesBaseGCDetails = await this.childNodesBaseGCDetailsP;\n\t\t\treturn childNodesBaseGCDetails.get(id) ?? {};\n\t\t};\n\n\t\tconst createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n\t\tconst child = new SummarizerNodeWithGC(\n\t\t\tthis.logger,\n\t\t\tsummarizeInternalFn,\n\t\t\t{\n\t\t\t\t...config,\n\t\t\t\t// Propagate our gcDisabled state to the child if its not explicity specified in child's config.\n\t\t\t\tgcDisabled: config.gcDisabled ?? this.gcDisabled,\n\t\t\t},\n\t\t\tcreateDetails.summaryHandleId,\n\t\t\tcreateDetails.changeSequenceNumber,\n\t\t\tcreateDetails.lastSummaryReferenceSequenceNumber,\n\t\t\tthis.wipSummaryLogger,\n\t\t\tgetGCDataFn,\n\t\t\tgetChildBaseGCDetailsFn,\n\t\t\tcreateDetails.telemetryNodeId,\n\t\t);\n\n\t\t// There may be additional state that has to be updated in this child. For example, if a summary is being\n\t\t// tracked, the child's summary tracking state needs to be updated too.\n\t\tthis.maybeUpdateChildState(child, id);\n\n\t\tthis.children.set(id, child);\n\t\treturn child;\n\t}\n\n\t/**\n\t * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's\n\t * summary tracking state needs to be updated too.\n\t * Also, in case a child node gets realized in between Summary Op and Summary Ack, let's initialize the child's\n\t * pending summary as well. Finally, if the pendingSummaries entries have serializedRoutes, replicate them to the\n\t * pendingSummaries from the child nodes.\n\t * @param child - The child node whose state is to be updated.\n\t * @param id - Initial id or path part of this node\n\t */\n\tprotected maybeUpdateChildState(child: SummarizerNodeWithGC, id: string): void {\n\t\tsuper.maybeUpdateChildState(child, id);\n\n\t\t// If GC has run on this node and summarization isn't complete, this.wipSerializedUsedRoutes will be defined.\n\t\t// In that case, update the used routes of the child node. This can happen in scenarios where a data store\n\t\t// doesn't have any ops but its reference state changed. So, it gets realized during summarize after GC ran\n\t\t// so GC would not have run on this node which is fine.\n\t\tif (this.wipSerializedUsedRoutes !== undefined) {\n\t\t\t// If the child route used routes are not defined, initialize it now and it can be used for all child nodes\n\t\t\t// created until this summarization process is completed. This is an optimization to unpack the used routes\n\t\t\t// only when needed.\n\t\t\tif (this.wipChildNodesUsedRoutes === undefined) {\n\t\t\t\tthis.wipChildNodesUsedRoutes = unpackChildNodesUsedRoutes(this.usedRoutes);\n\t\t\t}\n\t\t\tchild.updateUsedRoutes(this.wipChildNodesUsedRoutes.get(id) ?? [\"\"]);\n\t\t}\n\n\t\t// In case we have pending summaries on the parent, let's initialize it on the child.\n\t\tfor (const [key, pendingSummary] of this.pendingSummaries.entries()) {\n\t\t\tconst pendingSummaryWithGC = pendingSummary as PendingSummaryInfoWithGC;\n\t\t\tif (pendingSummaryWithGC.serializedUsedRoutes !== undefined) {\n\t\t\t\tconst childNodeUsedRoutes = unpackChildNodesUsedRoutes(\n\t\t\t\t\tJSON.parse(pendingSummaryWithGC.serializedUsedRoutes) as string[],\n\t\t\t\t);\n\t\t\t\tconst newSerializedRoutes = childNodeUsedRoutes.get(id) ?? [\"\"];\n\t\t\t\tconst childPendingSummaryInfo = {\n\t\t\t\t\t...pendingSummaryWithGC,\n\t\t\t\t\tserializedUsedRoutes: JSON.stringify(newSerializedRoutes),\n\t\t\t\t};\n\t\t\t\tchild.addPendingSummary(key, childPendingSummaryInfo);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Deletes the child node with the given id.\n\t */\n\tpublic deleteChild(id: string): void {\n\t\tthis.children.delete(id);\n\t}\n\n\t/**\n\t * Override the getChild method to return an instance of SummarizerNodeWithGC.\n\t */\n\tpublic getChild(id: string): ISummarizerNodeWithGC | undefined {\n\t\treturn this.children.get(id) as SummarizerNodeWithGC;\n\t}\n\n\tpublic isReferenced(): boolean {\n\t\treturn this.usedRoutes.includes(\"\") || this.usedRoutes.includes(\"/\");\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]): void {\n\t\t// Sort the given routes before updating. This will ensure that the routes compared in hasUsedStateChanged()\n\t\t// are in the same order.\n\t\tthis.usedRoutes = usedRoutes.sort();\n\n\t\t// If GC is not disabled and a summary is in progress, update the work-in-progress used routes so that it can\n\t\t// be tracked for this summary.\n\t\tif (!this.gcDisabled && this.isSummaryInProgress()) {\n\t\t\tthis.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n\t\t}\n\t}\n\n\t/**\n\t * Override the hasChanged method. If this node data or its used state changed, the node is considered changed.\n\t */\n\tprotected hasChanged(): boolean {\n\t\treturn this.hasDataChanged() || this.hasUsedStateChanged();\n\t}\n\n\t/**\n\t * This tells whether the data in this node has changed or not.\n\t */\n\tprivate hasDataChanged(): boolean {\n\t\treturn super.hasChanged();\n\t}\n\n\t/**\n\t * This tells whether the used state of this node has changed since last successful summary. If the used routes\n\t * of this node changed, its used state is considered changed. Basically, if this node or any of its child nodes\n\t * was previously used and became unused (or vice versa), its used state has changed.\n\t */\n\tprivate hasUsedStateChanged(): boolean {\n\t\t// If GC is disabled, it should not affect summary state, return false.\n\t\tif (this.gcDisabled) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn (\n\t\t\tthis.referenceUsedRoutes === undefined ||\n\t\t\tJSON.stringify(this.usedRoutes) !== JSON.stringify(this.referenceUsedRoutes)\n\t\t);\n\t}\n}\n\n/**\n * Creates a root summarizer node with GC functionality built-in.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n * @param getGCDataFn - Function to get the GC data of this node\n * @param baseGCDetailsP - Function to get the initial GC details of this node\n */\nexport const createRootSummarizerNodeWithGC = (\n\tlogger: ITelemetryBaseLogger,\n\tsummarizeInternalFn: SummarizeInternalFn,\n\tchangeSequenceNumber: number,\n\treferenceSequenceNumber: number | undefined,\n\tconfig: ISummarizerNodeConfigWithGC = {},\n\tgetGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n\tgetBaseGCDetailsFn?: () => Promise<IGarbageCollectionDetailsBase>,\n): IRootSummarizerNodeWithGC =>\n\tnew SummarizerNodeWithGC(\n\t\tlogger,\n\t\tsummarizeInternalFn,\n\t\tconfig,\n\t\t\"\" /* summaryHandleId */,\n\t\tchangeSequenceNumber,\n\t\treferenceSequenceNumber,\n\t\tundefined /* wipSummaryLogger */,\n\t\tgetGCDataFn,\n\t\tgetBaseGCDetailsFn,\n\t\t\"\" /* telemetryId */,\n\t);\n"]}
1
+ {"version":3,"file":"summarizerNodeWithGc.js","sourceRoot":"","sources":["../../../src/summary/summarizerNode/summarizerNodeWithGc.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 type { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { assert, LazyPromise } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIGarbageCollectionData,\n\tCreateChildSummarizerNodeParam,\n\tIGarbageCollectionDetailsBase,\n\tISummarizerNodeConfigWithGC,\n\tISummarizerNodeWithGC,\n\tSummarizeInternalFn,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { unpackChildNodesUsedRoutes } from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tLoggingError,\n\tTelemetryDataTag,\n\ttagCodeArtifacts,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { cloneGCData, unpackChildNodesGCDetails } from \"../../gc/index.js\";\n\nimport { SummarizerNode } from \"./summarizerNode.js\";\nimport type {\n\tICreateChildDetails,\n\tIStartSummaryResult,\n\tISummarizerNodeRootContract,\n\tPendingSummaryInfo,\n\tValidateSummaryResult,\n} from \"./summarizerNodeUtils.js\";\n\nexport interface IRootSummarizerNodeWithGC\n\textends ISummarizerNodeWithGC,\n\t\tISummarizerNodeRootContract {}\n\n// Extend PendingSummaryInfo to add used routes tracking it.\ninterface PendingSummaryInfoWithGC extends PendingSummaryInfo {\n\tserializedUsedRoutes: string | undefined;\n}\n\n/**\n * Extends the functionality of SummarizerNode to manage this node's garbage collection data:\n *\n * - Adds a new API `getGCData` to return GC data of this node.\n *\n * - Caches the result of `getGCData` to be used if nothing changes between summaries.\n *\n * - Manages the used routes of this node. These are used to identify if this node is referenced in the document\n * and to determine if the node's used state changed since last summary.\n *\n *- Adds trackState param to summarize. If trackState is false, it bypasses the SummarizerNode and calls\n * directly into summarizeInternal method.\n */\nexport class SummarizerNodeWithGC extends SummarizerNode implements IRootSummarizerNodeWithGC {\n\t// Tracks the work-in-progress used routes during summary.\n\tprivate wipSerializedUsedRoutes: string | undefined;\n\n\t// Tracks the work-in-progress used routes of child nodes during summary.\n\tprivate wipChildNodesUsedRoutes: Map<string, string[]> | undefined;\n\n\t// This is the last known used routes of this node as seen by the server as part of a summary.\n\tprivate referenceUsedRoutes: string[] | undefined;\n\n\t// The base GC details of this node used to initialize the GC state.\n\tprivate readonly baseGCDetailsP: Promise<IGarbageCollectionDetailsBase>;\n\n\t// Keeps track of whether we have loaded the base details to ensure that we only do it once.\n\tprivate baseGCDetailsLoaded: boolean = false;\n\n\t// The base GC details for the child nodes. This is passed to child nodes when creating them.\n\tprivate readonly childNodesBaseGCDetailsP: Promise<\n\t\tMap<string, IGarbageCollectionDetailsBase>\n\t>;\n\n\tprivate gcData: IGarbageCollectionData | undefined;\n\n\t// Set used routes to have self route by default. This makes the node referenced by default. This is done to ensure\n\t// that this node is not marked as collected when running GC has been disabled. Once, the option to disable GC is\n\t// removed (from runGC flag in IContainerRuntimeOptions), this should be changed to be have no routes by default.\n\tprivate usedRoutes: string[] = [\"\"];\n\n\t// True if GC is disabled for this node. If so, do not track GC specific state for a summary.\n\tprivate readonly gcDisabled: boolean;\n\n\t/**\n\t * Do not call constructor directly.\n\t * Use createRootSummarizerNodeWithGC to create root node, or createChild to create child nodes.\n\t */\n\tpublic constructor(\n\t\tlogger: ITelemetryBaseLogger,\n\t\tsummarizeInternalFn: SummarizeInternalFn,\n\t\tconfig: ISummarizerNodeConfigWithGC,\n\t\t_summaryHandleId: string,\n\t\tchangeSequenceNumber: number,\n\t\t/**\n\t\t * Summary reference sequence number, i.e. last sequence number seen when it was created\n\t\t */\n\t\tlastSummaryReferenceSequenceNumber?: number,\n\t\twipSummaryLogger?: ITelemetryBaseLogger,\n\t\tprivate readonly getGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n\t\tgetBaseGCDetailsFn?: () => Promise<IGarbageCollectionDetailsBase>,\n\t\t/**\n\t\t * A unique id of this node to be logged when sending telemetry.\n\t\t */\n\t\ttelemetryId?: string,\n\t) {\n\t\tsuper(\n\t\t\tlogger,\n\t\t\tsummarizeInternalFn,\n\t\t\tconfig,\n\t\t\t_summaryHandleId,\n\t\t\tchangeSequenceNumber,\n\t\t\tlastSummaryReferenceSequenceNumber,\n\t\t\twipSummaryLogger,\n\t\t\ttelemetryId,\n\t\t);\n\n\t\tthis.gcDisabled = config.gcDisabled === true;\n\n\t\tthis.baseGCDetailsP = new LazyPromise(async () => {\n\t\t\treturn (await getBaseGCDetailsFn?.()) ?? { usedRoutes: [] };\n\t\t});\n\n\t\tthis.childNodesBaseGCDetailsP = new LazyPromise(async () => {\n\t\t\tawait this.loadBaseGCDetails();\n\t\t\treturn unpackChildNodesGCDetails({ gcData: this.gcData, usedRoutes: this.usedRoutes });\n\t\t});\n\t}\n\n\t/**\n\t * Loads state from this node's initial GC summary details. This contains the following data from the last summary\n\t * seen by the server for this client:\n\t * - usedRoutes: This is used to figure out if the used state of this node changed since last summary.\n\t * - gcData: The garbage collection data of this node that is required for running GC.\n\t */\n\tprivate async loadBaseGCDetails(): Promise<void> {\n\t\tif (this.baseGCDetailsLoaded) {\n\t\t\treturn;\n\t\t}\n\t\tconst baseGCDetails = await this.baseGCDetailsP;\n\n\t\t// Possible race - If there were parallel calls to loadBaseGCDetails, we want to make sure that we update\n\t\t// the state from the base details only once.\n\t\tif (this.baseGCDetailsLoaded) {\n\t\t\treturn;\n\t\t}\n\t\tthis.baseGCDetailsLoaded = true;\n\n\t\t// Update GC data, used routes and reference used routes. The used routes are sorted because they are compared\n\t\t// across GC runs to check if they changed. Sorting ensures that the elements are in the same order.\n\t\t// If the GC details has GC data, initialize our GC data from it.\n\t\tif (baseGCDetails.gcData !== undefined) {\n\t\t\tthis.gcData = cloneGCData(baseGCDetails.gcData);\n\t\t}\n\t\tif (baseGCDetails.usedRoutes !== undefined) {\n\t\t\tthis.usedRoutes = [...baseGCDetails.usedRoutes].sort();\n\t\t\tthis.referenceUsedRoutes = [...baseGCDetails.usedRoutes].sort();\n\t\t}\n\t}\n\n\t/**\n\t * Returns the GC data of this node. If nothing has changed since last summary, it tries to reuse the data from\n\t * the previous summary. Else, it gets new GC data from the underlying Fluid object.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tassert(\n\t\t\t!this.gcDisabled,\n\t\t\t0x1b2 /* \"Getting GC data should not be called when GC is disabled!\" */,\n\t\t);\n\t\tassert(\n\t\t\tthis.getGCDataFn !== undefined,\n\t\t\t0x1b3 /* \"GC data cannot be retrieved without getGCDataFn\" */,\n\t\t);\n\n\t\t// Load GC details from the initial summary, if not already loaded. If this is the first time this function is\n\t\t// called and the node's data has not changed since last summary, the GC data in initial details is returned.\n\t\tawait this.loadBaseGCDetails();\n\n\t\t// If there is no new data since last summary and we have GC data from the previous run, return it. The previous\n\t\t// GC data may not be available if loaded from a snapshot with either GC disabled or before GC was added.\n\t\t// Note - canReuseHandle is checked to be consistent with summarize - generate GC data for nodes for which\n\t\t// summary must be generated.\n\t\tif (\n\t\t\tthis.canReuseHandle &&\n\t\t\t!fullGC &&\n\t\t\t!this.hasDataChanged() &&\n\t\t\tthis.gcData !== undefined\n\t\t) {\n\t\t\treturn cloneGCData(this.gcData);\n\t\t}\n\n\t\tconst gcData = await this.getGCDataFn(fullGC);\n\t\tthis.gcData = cloneGCData(gcData);\n\t\treturn gcData;\n\t}\n\n\t/**\n\t * Called during the start of a summary. Updates the work-in-progress used routes.\n\t */\n\tpublic startSummary(\n\t\treferenceSequenceNumber: number,\n\t\tsummaryLogger: ITelemetryBaseLogger,\n\t\tlatestSummaryRefSeqNum: number,\n\t): IStartSummaryResult {\n\t\t// If GC is disabled, skip setting wip used routes since we should not track GC state.\n\t\tif (!this.gcDisabled) {\n\t\t\tassert(\n\t\t\t\tthis.wipSerializedUsedRoutes === undefined,\n\t\t\t\t0x1b4 /* \"We should not already be tracking used routes when to track a new summary\" */,\n\t\t\t);\n\t\t}\n\t\treturn super.startSummary(referenceSequenceNumber, summaryLogger, latestSummaryRefSeqNum);\n\t}\n\n\t/**\n\t * Validates that the in-progress summary is correct for all nodes, i.e., GC should have run for non-skipped nodes.\n\t * @param parentSkipRecursion - true if the parent of this node skipped recursing the child nodes when running GC.\n\t * In that case, the children will not have work-in-progress state.\n\t *\n\t * @returns ValidateSummaryResult which contains a boolean success indicating whether the validation was successful.\n\t * In case of failure, additional information is returned indicating type of failure and where it was.\n\t */\n\tprotected validateSummaryCore(parentSkipRecursion: boolean): ValidateSummaryResult {\n\t\tif (this.wasGCMissed()) {\n\t\t\treturn {\n\t\t\t\tsuccess: false,\n\t\t\t\treason: \"NodeDidNotRunGC\",\n\t\t\t\tid: {\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\tvalue: this.telemetryNodeId,\n\t\t\t\t},\n\t\t\t\t// These errors are usually transient and should go away when summarize / GC is retried.\n\t\t\t\tretryAfterSeconds: 1,\n\t\t\t};\n\t\t}\n\t\treturn super.validateSummaryCore(parentSkipRecursion);\n\t}\n\n\tprivate wasGCMissed(): boolean {\n\t\t// If GC is disabled, it should not have run so it was not missed.\n\t\t// Otherwise, GC should have been called on this node and wipSerializedUsedRoutes must be set.\n\t\tif (this.gcDisabled || this.wipSerializedUsedRoutes !== undefined) {\n\t\t\treturn false;\n\t\t}\n\t\t/**\n\t\t * The absence of wip used routes indicates that GC was not run on this node. This can happen if:\n\t\t * 1. A child node was created after GC was already run on the parent. For example, a data store\n\t\t * is realized (loaded) after GC was run on it creating summarizer nodes for its DDSes. In this\n\t\t * case, the parent will pass on used routes to the child nodes and it will have wip used routes.\n\t\t * 2. A new node was created but GC was never run on it. This can mean that the GC data generated\n\t\t * during summarize is incomplete.\n\t\t *\n\t\t * This happens due to scenarios such as data store created during summarize. Such errors should go away when\n\t\t * summarize is attempted again.\n\t\t */\n\t\treturn true;\n\t}\n\n\t/**\n\t * Called after summary has been uploaded to the server. Add the work-in-progress state to the pending\n\t * summary queue. We track this until we get an ack from the server for this summary.\n\t * @param proposalHandle - The handle of the summary that was uploaded to the server.\n\t * @param parentSkipRecursion - true if the parent of this node skipped recursing the child nodes when summarizing.\n\t * In that case, the children will not have work-in-progress state.\n\t */\n\tprotected completeSummaryCore(proposalHandle: string, parentSkipRecursion: boolean): void {\n\t\tlet wipSerializedUsedRoutes: string | undefined;\n\t\t// If GC is disabled, don't set wip used routes.\n\t\tif (!this.gcDisabled) {\n\t\t\twipSerializedUsedRoutes = this.wipSerializedUsedRoutes;\n\t\t}\n\n\t\tsuper.completeSummaryCore(proposalHandle, parentSkipRecursion);\n\n\t\t// If GC is disabled, skip setting pending summary with GC state.\n\t\tif (!this.gcDisabled) {\n\t\t\tconst pendingSummaryInfo = this.pendingSummaries.get(proposalHandle);\n\t\t\tif (pendingSummaryInfo !== undefined) {\n\t\t\t\tconst pendingSummaryInfoWithGC = {\n\t\t\t\t\tserializedUsedRoutes: wipSerializedUsedRoutes,\n\t\t\t\t\t...pendingSummaryInfo,\n\t\t\t\t};\n\t\t\t\tthis.pendingSummaries.set(proposalHandle, pendingSummaryInfoWithGC);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Clears the work-in-progress state.\n\t */\n\tpublic clearSummary(): void {\n\t\tthis.wipSerializedUsedRoutes = undefined;\n\t\tthis.wipChildNodesUsedRoutes = undefined;\n\t\tsuper.clearSummary();\n\t}\n\n\t/**\n\t * Called when we get an ack from the server for a summary we sent. Update the reference state of this node\n\t * from the state in the pending summary queue.\n\t */\n\tprotected refreshLatestSummaryFromPending(\n\t\tproposalHandle: string,\n\t\treferenceSequenceNumber: number,\n\t): void {\n\t\t// If GC is disabled, skip setting referenced used routes since we are not tracking GC state.\n\t\tif (!this.gcDisabled) {\n\t\t\tconst pendingSummaryInfo = this.pendingSummaries.get(proposalHandle);\n\t\t\tif (pendingSummaryInfo !== undefined) {\n\t\t\t\t// If a pending summary exists, it must have used routes since GC is enabled.\n\t\t\t\tconst summaryNodeWithGC = pendingSummaryInfo as PendingSummaryInfoWithGC;\n\t\t\t\tif (summaryNodeWithGC.serializedUsedRoutes === undefined) {\n\t\t\t\t\tconst error = new LoggingError(\"MissingGCStateInPendingSummary\", {\n\t\t\t\t\t\tproposalHandle,\n\t\t\t\t\t\treferenceSequenceNumber,\n\t\t\t\t\t\t...tagCodeArtifacts({\n\t\t\t\t\t\t\tid: this.telemetryNodeId,\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\teventName: error.message,\n\t\t\t\t\t\t},\n\t\t\t\t\t\terror,\n\t\t\t\t\t);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tthis.referenceUsedRoutes = JSON.parse(\n\t\t\t\t\tsummaryNodeWithGC.serializedUsedRoutes,\n\t\t\t\t) as string[];\n\t\t\t}\n\t\t}\n\n\t\treturn super.refreshLatestSummaryFromPending(proposalHandle, referenceSequenceNumber);\n\t}\n\n\t/**\n\t * Override the createChild method to return an instance of SummarizerNodeWithGC.\n\t */\n\tpublic createChild(\n\t\t/**\n\t\t * Summarize function\n\t\t */\n\t\tsummarizeInternalFn: SummarizeInternalFn,\n\t\t/**\n\t\t * Initial id or path part of this node\n\t\t */\n\t\tid: string,\n\t\t/**\n\t\t * Information needed to create the node.\n\t\t * If it is from a base summary, it will assert that a summary has been seen.\n\t\t * Attach information if it is created from an attach op.\n\t\t */\n\t\tcreateParam: CreateChildSummarizerNodeParam,\n\t\tconfig: ISummarizerNodeConfigWithGC = {},\n\t\tgetGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n\t): ISummarizerNodeWithGC {\n\t\tassert(!this.children.has(id), 0x1b6 /* \"Create SummarizerNode child already exists\" */);\n\t\t/**\n\t\t * Update the child node's base GC details from this node's current GC details instead of updating from the base\n\t\t * GC details of this node. This will handle scenarios where the GC details was updated during refresh from\n\t\t * snapshot and the child node wasn't created then. If a child is created after that, its GC details should be\n\t\t * the one from the downloaded snapshot and not the base GC details.\n\t\t */\n\t\tconst getChildBaseGCDetailsFn = async (): Promise<IGarbageCollectionDetailsBase> => {\n\t\t\tconst childNodesBaseGCDetails = await this.childNodesBaseGCDetailsP;\n\t\t\treturn childNodesBaseGCDetails.get(id) ?? {};\n\t\t};\n\n\t\tconst createDetails: ICreateChildDetails = this.getCreateDetailsForChild(id, createParam);\n\t\tconst child = new SummarizerNodeWithGC(\n\t\t\tthis.logger,\n\t\t\tsummarizeInternalFn,\n\t\t\t{\n\t\t\t\t...config,\n\t\t\t\t// Propagate our gcDisabled state to the child if its not explicity specified in child's config.\n\t\t\t\tgcDisabled: config.gcDisabled ?? this.gcDisabled,\n\t\t\t},\n\t\t\tcreateDetails.summaryHandleId,\n\t\t\tcreateDetails.changeSequenceNumber,\n\t\t\tcreateDetails.lastSummaryReferenceSequenceNumber,\n\t\t\tthis.wipSummaryLogger,\n\t\t\tgetGCDataFn,\n\t\t\tgetChildBaseGCDetailsFn,\n\t\t\tcreateDetails.telemetryNodeId,\n\t\t);\n\n\t\t// There may be additional state that has to be updated in this child. For example, if a summary is being\n\t\t// tracked, the child's summary tracking state needs to be updated too.\n\t\tthis.maybeUpdateChildState(child, id);\n\n\t\tthis.children.set(id, child);\n\t\treturn child;\n\t}\n\n\t/**\n\t * Updates the state of the child if required. For example, if a summary is currently being tracked, the child's\n\t * summary tracking state needs to be updated too.\n\t * Also, in case a child node gets realized in between Summary Op and Summary Ack, let's initialize the child's\n\t * pending summary as well. Finally, if the pendingSummaries entries have serializedRoutes, replicate them to the\n\t * pendingSummaries from the child nodes.\n\t * @param child - The child node whose state is to be updated.\n\t * @param id - Initial id or path part of this node\n\t */\n\tprotected maybeUpdateChildState(child: SummarizerNodeWithGC, id: string): void {\n\t\tsuper.maybeUpdateChildState(child, id);\n\n\t\t// If GC has run on this node and summarization isn't complete, this.wipSerializedUsedRoutes will be defined.\n\t\t// In that case, update the used routes of the child node. This can happen in scenarios where a data store\n\t\t// doesn't have any ops but its reference state changed. So, it gets realized during summarize after GC ran\n\t\t// so GC would not have run on this node which is fine.\n\t\tif (this.wipSerializedUsedRoutes !== undefined) {\n\t\t\t// If the child route used routes are not defined, initialize it now and it can be used for all child nodes\n\t\t\t// created until this summarization process is completed. This is an optimization to unpack the used routes\n\t\t\t// only when needed.\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\t\tif (this.wipChildNodesUsedRoutes === undefined) {\n\t\t\t\tthis.wipChildNodesUsedRoutes = unpackChildNodesUsedRoutes(this.usedRoutes);\n\t\t\t}\n\t\t\tchild.updateUsedRoutes(this.wipChildNodesUsedRoutes.get(id) ?? [\"\"]);\n\t\t}\n\n\t\t// In case we have pending summaries on the parent, let's initialize it on the child.\n\t\tfor (const [key, pendingSummary] of this.pendingSummaries.entries()) {\n\t\t\tconst pendingSummaryWithGC = pendingSummary as PendingSummaryInfoWithGC;\n\t\t\tif (pendingSummaryWithGC.serializedUsedRoutes !== undefined) {\n\t\t\t\tconst childNodeUsedRoutes = unpackChildNodesUsedRoutes(\n\t\t\t\t\tJSON.parse(pendingSummaryWithGC.serializedUsedRoutes) as string[],\n\t\t\t\t);\n\t\t\t\tconst newSerializedRoutes = childNodeUsedRoutes.get(id) ?? [\"\"];\n\t\t\t\tconst childPendingSummaryInfo = {\n\t\t\t\t\t...pendingSummaryWithGC,\n\t\t\t\t\tserializedUsedRoutes: JSON.stringify(newSerializedRoutes),\n\t\t\t\t};\n\t\t\t\tchild.addPendingSummary(key, childPendingSummaryInfo);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Deletes the child node with the given id.\n\t */\n\tpublic deleteChild(id: string): void {\n\t\tthis.children.delete(id);\n\t}\n\n\t/**\n\t * Override the getChild method to return an instance of SummarizerNodeWithGC.\n\t */\n\tpublic getChild(id: string): ISummarizerNodeWithGC | undefined {\n\t\treturn this.children.get(id) as SummarizerNodeWithGC;\n\t}\n\n\tpublic isReferenced(): boolean {\n\t\treturn this.usedRoutes.includes(\"\") || this.usedRoutes.includes(\"/\");\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]): void {\n\t\t// Sort the given routes before updating. This will ensure that the routes compared in hasUsedStateChanged()\n\t\t// are in the same order.\n\t\tthis.usedRoutes = usedRoutes.sort();\n\n\t\t// If GC is not disabled and a summary is in progress, update the work-in-progress used routes so that it can\n\t\t// be tracked for this summary.\n\t\tif (!this.gcDisabled && this.isSummaryInProgress()) {\n\t\t\tthis.wipSerializedUsedRoutes = JSON.stringify(this.usedRoutes);\n\t\t}\n\t}\n\n\t/**\n\t * Override the hasChanged method. If this node data or its used state changed, the node is considered changed.\n\t */\n\tprotected hasChanged(): boolean {\n\t\treturn this.hasDataChanged() || this.hasUsedStateChanged();\n\t}\n\n\t/**\n\t * This tells whether the data in this node has changed or not.\n\t */\n\tprivate hasDataChanged(): boolean {\n\t\treturn super.hasChanged();\n\t}\n\n\t/**\n\t * This tells whether the used state of this node has changed since last successful summary. If the used routes\n\t * of this node changed, its used state is considered changed. Basically, if this node or any of its child nodes\n\t * was previously used and became unused (or vice versa), its used state has changed.\n\t */\n\tprivate hasUsedStateChanged(): boolean {\n\t\t// If GC is disabled, it should not affect summary state, return false.\n\t\tif (this.gcDisabled) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn (\n\t\t\tthis.referenceUsedRoutes === undefined ||\n\t\t\tJSON.stringify(this.usedRoutes) !== JSON.stringify(this.referenceUsedRoutes)\n\t\t);\n\t}\n}\n\n/**\n * Creates a root summarizer node with GC functionality built-in.\n * @param logger - Logger to use within SummarizerNode\n * @param summarizeInternalFn - Function to generate summary\n * @param changeSequenceNumber - Sequence number of latest change to new node/subtree\n * @param referenceSequenceNumber - Reference sequence number of last acked summary,\n * or undefined if not loaded from summary\n * @param config - Configure behavior of summarizer node\n * @param getGCDataFn - Function to get the GC data of this node\n * @param baseGCDetailsP - Function to get the initial GC details of this node\n */\nexport const createRootSummarizerNodeWithGC = (\n\tlogger: ITelemetryBaseLogger,\n\tsummarizeInternalFn: SummarizeInternalFn,\n\tchangeSequenceNumber: number,\n\treferenceSequenceNumber: number | undefined,\n\tconfig: ISummarizerNodeConfigWithGC = {},\n\tgetGCDataFn?: (fullGC?: boolean) => Promise<IGarbageCollectionData>,\n\tgetBaseGCDetailsFn?: () => Promise<IGarbageCollectionDetailsBase>,\n): IRootSummarizerNodeWithGC =>\n\tnew SummarizerNodeWithGC(\n\t\tlogger,\n\t\tsummarizeInternalFn,\n\t\tconfig,\n\t\t\"\" /* summaryHandleId */,\n\t\tchangeSequenceNumber,\n\t\treferenceSequenceNumber,\n\t\tundefined /* wipSummaryLogger */,\n\t\tgetGCDataFn,\n\t\tgetBaseGCDetailsFn,\n\t\t\"\" /* telemetryId */,\n\t);\n"]}
@@ -69,7 +69,7 @@ export class SummaryGenerator extends TypedEventEmitter {
69
69
  * For submit failures, submitFailureResult should be provided. For nack failures, nackSummaryResult should
70
70
  * be provided. For op broadcast failures, only errors / properties should be provided.
71
71
  */
72
- const fail = (errorCode, error, properties, submitFailureResult, nackSummaryResult) => {
72
+ const summaryFail = (errorCode, error, properties, submitFailureResult, nackSummaryResult) => {
73
73
  // Report any failure as an error unless it was due to cancellation (like "disconnected" error)
74
74
  // If failure happened on upload, we may not yet realized that socket disconnected, so check
75
75
  // offlineError too.
@@ -108,7 +108,7 @@ export class SummaryGenerator extends TypedEventEmitter {
108
108
  if (summaryData.stage !== "submit") {
109
109
  const errorCode = "submitSummaryFailure";
110
110
  const retriableError = summaryData.error ?? new RetriableSummaryError(getFailMessage(errorCode));
111
- return fail(errorCode, retriableError, summarizeTelemetryProps, {
111
+ return summaryFail(errorCode, retriableError, summarizeTelemetryProps, {
112
112
  stage: summaryData.stage,
113
113
  });
114
114
  }
@@ -140,7 +140,7 @@ export class SummaryGenerator extends TypedEventEmitter {
140
140
  resultsBuilder.summarySubmitted.resolve({ success: true, data: summaryData });
141
141
  }
142
142
  catch (error) {
143
- return fail("submitSummaryFailure", wrapError(error, (message) => new RetriableSummaryError(message, getRetryDelaySecondsFromError(error))), undefined /* properties */, {
143
+ return summaryFail("submitSummaryFailure", wrapError(error, (message) => new RetriableSummaryError(message, getRetryDelaySecondsFromError(error))), undefined /* properties */, {
144
144
  stage: "unknown",
145
145
  });
146
146
  }
@@ -158,13 +158,13 @@ export class SummaryGenerator extends TypedEventEmitter {
158
158
  const waitBroadcastResult = await raceTimer(summary.waitBroadcast(), pendingTimeoutP, cancellationToken);
159
159
  if (waitBroadcastResult.result === "cancelled") {
160
160
  const errorCode = "disconnect";
161
- return fail(errorCode, new RetriableSummaryError(getFailMessage(errorCode)));
161
+ return summaryFail(errorCode, new RetriableSummaryError(getFailMessage(errorCode)));
162
162
  }
163
163
  if (waitBroadcastResult.result !== "done") {
164
164
  // The summary op may not have been received within the timeout due to a transient error. So,
165
165
  // fail with a retriable error to re-attempt the summary if possible.
166
166
  const errorCode = "summaryOpWaitTimeout";
167
- return fail(errorCode, new RetriableSummaryError(getFailMessage(errorCode), 0 /* retryAfterSeconds */));
167
+ return summaryFail(errorCode, new RetriableSummaryError(getFailMessage(errorCode), 0 /* retryAfterSeconds */));
168
168
  }
169
169
  const summarizeOp = waitBroadcastResult.value;
170
170
  const broadcastDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;
@@ -184,13 +184,13 @@ export class SummaryGenerator extends TypedEventEmitter {
184
184
  const waitAckNackResult = await raceTimer(summary.waitAckNack(), pendingTimeoutP, cancellationToken);
185
185
  if (waitAckNackResult.result === "cancelled") {
186
186
  const errorCode = "disconnect";
187
- return fail(errorCode, new RetriableSummaryError(getFailMessage(errorCode)));
187
+ return summaryFail(errorCode, new RetriableSummaryError(getFailMessage(errorCode)));
188
188
  }
189
189
  if (waitAckNackResult.result !== "done") {
190
190
  const errorCode = "summaryAckWaitTimeout";
191
191
  // The summary ack may not have been received within the timeout due to a transient error. So,
192
192
  // fail with a retriable error to re-attempt the summary if possible.
193
- return fail(errorCode, new RetriableSummaryError(getFailMessage(errorCode), 0 /* retryAfterSeconds */));
193
+ return summaryFail(errorCode, new RetriableSummaryError(getFailMessage(errorCode), 0 /* retryAfterSeconds */));
194
194
  }
195
195
  const ackNackOp = waitAckNackResult.value;
196
196
  this.pendingAckTimer.clear();
@@ -241,7 +241,7 @@ export class SummaryGenerator extends TypedEventEmitter {
241
241
  });
242
242
  assert(getRetryDelaySecondsFromError(error) === retryAfterSeconds, 0x25f /* "retryAfterSeconds" */);
243
243
  // This will only set resultsBuilder.receivedSummaryAckOrNack, as other promises are already set.
244
- return fail(errorCode, error, { ...summarizeTelemetryProps, nackRetryAfter: retryAfterSeconds }, undefined /* submitFailureResult */, { summaryNackOp: ackNackOp, ackNackDuration });
244
+ return summaryFail(errorCode, error, { ...summarizeTelemetryProps, nackRetryAfter: retryAfterSeconds }, undefined /* submitFailureResult */, { summaryNackOp: ackNackOp, ackNackDuration });
245
245
  }
246
246
  }
247
247
  finally {
@@ -1 +1 @@
1
- {"version":3,"file":"summaryGenerator.js","sourceRoot":"","sources":["../../../src/summary/summaryDelayLoadedModule/summaryGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,MAAM,EAAsB,KAAK,EAAE,MAAM,qCAAqC,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AAC5F,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EACN,YAAY,EAEZ,gBAAgB,EAChB,SAAS,GACT,MAAM,0CAA0C,CAAC;AAWlD,OAAO,EACN,qBAAqB,EACrB,cAAc,EACd,SAAS,GAET,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,yDAAyD;AACzD,MAAM,uBAAuB,GAAG,KAAK,CAAC,CAAC,SAAS;AAChD,MAAM,wBAAwB,GAAG,CAAC,CAAC,CAAC,4BAA4B;AAEhE;;GAEG;AACH,MAAM,OAAO,gBAAiB,SAAQ,iBAAoC;IAGzE,YACkB,eAA8B,EAC9B,aAAsC,EACtC,qBAEgB,EAChB,yBAAqC,EACrC,4BAEC,EACD,cAA2D,EAC3D,MAA2B;QAE5C,KAAK,EAAE,CAAC;QAZS,oBAAe,GAAf,eAAe,CAAe;QAC9B,kBAAa,GAAb,aAAa,CAAyB;QACtC,0BAAqB,GAArB,qBAAqB,CAEL;QAChB,8BAAyB,GAAzB,yBAAyB,CAAY;QACrC,iCAA4B,GAA5B,4BAA4B,CAE3B;QACD,mBAAc,GAAd,cAAc,CAA6C;QAC3D,WAAM,GAAN,MAAM,CAAqB;QAG5C,IAAI,CAAC,cAAc,GAAG,IAAI,KAAK,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAC7D,IAAI,CAAC,qBAAqB,CAAC,uBAAuB,EAAE,CAAC,CAAC,CACtD,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,SAAS,CACf,cAAqC,EACrC,cAAc,GAAG,IAAI,sBAAsB,EAAE;QAE7C,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,KAAK,CACvD,CAAC,KAA6B,EAAE,EAAE;YACjC,MAAM,OAAO,GAAG,0BAA0B,CAAC;YAC3C,cAAc,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;YAC3E,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC,CACD,CAAC;QAEF,OAAO,cAAc,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,aAAa,CAC1B,oBAA2C,EAC3C,cAAsC;QAEtC,MAAM,EACL,aAAa,EACb,iBAAiB,EACjB,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,EACzC,GAAG,gBAAgB,EACnB,GAAG,oBAAoB,CAAC;QAEzB,gBAAgB,CAAC,uBAAuB,CAAC,eAAe,CAAC,CAAC;QAC1D,MAAM,aAAa,GAAG,EAAE,GAAG,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;QACpE,IAAI,CAAC,sBAAsB,GAAG,gBAAgB,CAAC;QAE/C,8DAA8D;QAC9D,wEAAwE;QACxE,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW,CAAC;QACrF,MAAM,oBAAoB,GACzB,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,WAAW,CAAC;QACnE,IAAI,uBAAuB,GAA8B;YACxD,GAAG,gBAAgB;YACnB,QAAQ,EAAE,gBAAgB,CAAC,QAAQ,IAAI,KAAK;YAC5C,oBAAoB;YACpB,oBAAoB;YACpB,6BAA6B,EAAE,IAAI,CAAC,aAAa,CAAC,gBAAgB;YAClE,0BAA0B,EAAE,IAAI,CAAC,aAAa,CAAC,aAAa;SAC5D,CAAC;QAEF,MAAM,cAAc,GAAG,gBAAgB,CAAC,KAAK,CAC5C,aAAa,EACb;YACC,SAAS,EAAE,WAAW;YACtB,GAAG,uBAAuB;SAC1B,EACD,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAC7C,CAAC;QAEF,IAAI,WAA4C,CAAC;QAEjD;;;;WAIG;QACH,MAAM,IAAI,GAAG,CACZ,SAA6B,EAC7B,KAA6B,EAC7B,UAAsC,EACtC,mBAA8C,EAC9C,iBAAsC,EAC/B,EAAE;YACT,+FAA+F;YAC/F,4FAA4F;YAC5F,oBAAoB;YACpB,MAAM,QAAQ,GACb,iBAAiB,CAAC,SAAS;gBAC3B,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,EAAE,SAAS,KAAK,gBAAgB,CAAC,YAAY,CAAC;gBAC1E,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,OAAO,CAAC;YAEZ,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;YACzC,cAAc,CAAC,MAAM,CACpB;gBACC,GAAG,UAAU;gBACb,MAAM;gBACN,QAAQ;gBACR,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;aAC1C,EACD,KAAK,CACL,CAAC,CAAC,2DAA2D;YAE9D,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;QAC5E,CAAC,CAAC;QAEF,oCAAoC;QACpC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC;YACJ,gBAAgB,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;YAC5D,iGAAiG;YACjG,MAAM,oBAAoB,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,iBAAiB,CAAC;YAE9E,WAAW,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;YAC9D,gBAAgB,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;YAE5D,+EAA+E;YAC/E,MAAM,uBAAuB,GAAG,WAAW,CAAC,uBAAuB,CAAC;YACpE,uBAAuB,GAAG;gBACzB,GAAG,uBAAuB;gBAC1B,uBAAuB;gBACvB,qBAAqB,EAAE,WAAW,CAAC,qBAAqB;gBACxD,mBAAmB,EAAE,uBAAuB,GAAG,oBAAoB;gBACnE,mBAAmB,EAClB,uBAAuB,GAAG,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,iBAAiB;gBACrF,KAAK,EAAE,WAAW,CAAC,KAAK;aACxB,CAAC;YACF,uBAAuB,GAAG,IAAI,CAAC,8BAA8B,CAC5D,WAAW,EACX,uBAAuB,CACvB,CAAC;YAEF,IAAI,WAAW,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACpC,MAAM,SAAS,GAAuB,sBAAsB,CAAC;gBAC7D,MAAM,cAAc,GACnB,WAAW,CAAC,KAAK,IAAI,IAAI,qBAAqB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;gBAC3E,OAAO,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,uBAAuB,EAAE;oBAC/D,KAAK,EAAE,WAAW,CAAC,KAAK;iBACxB,CAAC,CAAC;YACJ,CAAC;YAED;;;;;;;;;eASG;YACH,IAAI,oBAAoB,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAC5C,gBAAgB,CAAC,uBAAuB,CAAC,cAAc,CAAC,CAAC;gBACzD,MAAM,EAAE,wBAAwB,EAAE,4BAA4B,GAAG,CAAC,EAAE,GACnE,WAAW,CAAC,YAAY,CAAC;gBAC1B,IACC,wBAAwB;oBACxB,4BAA4B,GAAG,IAAI,CAAC,aAAa,CAAC,mBAAmB,EACpE,CAAC;oBACF,aAAa,CAAC,cAAc,CAAC;wBAC5B,SAAS,EAAE,6BAA6B;wBACxC,wBAAwB;wBACxB,4BAA4B;wBAC5B,mBAAmB,EAAE,IAAI,CAAC,aAAa,CAAC,mBAAmB;qBAC3D,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;YAED,0FAA0F;YAC1F,cAAc,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,GAAG,uBAAuB,EAAE,CAAC,CAAC;YACvE,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QAC/E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,IAAI,CACV,sBAAsB,EACtB,SAAS,CACR,KAAK,EACL,CAAC,OAAO,EAAE,EAAE,CACX,IAAI,qBAAqB,CAAC,OAAO,EAAE,6BAA6B,CAAC,KAAK,CAAC,CAAC,CACzE,EACD,SAAS,CAAC,gBAAgB,EAC1B;gBACC,KAAK,EAAE,SAAS;aAChB,CACD,CAAC;QACH,CAAC;gBAAS,CAAC;YACV,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC/B,IAAI,CAAC,aAAa,CAAC,aAAa,EAAE,CAAC;YACpC,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;QAED,gBAAgB,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;QAE9D,IAAI,CAAC;YACJ,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;YAEnF,qBAAqB;YACrB,MAAM,mBAAmB,GAAG,MAAM,SAAS,CAC1C,OAAO,CAAC,aAAa,EAAE,EACvB,eAAe,EACf,iBAAiB,CACjB,CAAC;YACF,IAAI,mBAAmB,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAChD,MAAM,SAAS,GAAuB,YAAY,CAAC;gBACnD,OAAO,IAAI,CAAC,SAAS,EAAE,IAAI,qBAAqB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC9E,CAAC;YACD,IAAI,mBAAmB,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC3C,6FAA6F;gBAC7F,qEAAqE;gBACrE,MAAM,SAAS,GAAuB,sBAAsB,CAAC;gBAC7D,OAAO,IAAI,CACV,SAAS,EACT,IAAI,qBAAqB,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,uBAAuB,CAAC,CAC/E,CAAC;YACH,CAAC;YACD,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC;YAE9C,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW,CAAC;YAClF,cAAc,CAAC,oBAAoB,CAAC,OAAO,CAAC;gBAC3C,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,EAAE,WAAW,EAAE,iBAAiB,EAAE;aACxC,CAAC,CAAC;YAEH,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,qBAAqB,GAAG,WAAW,CAAC,cAAc,CAAC;YAClF,aAAa,CAAC,kBAAkB,CAAC;gBAChC,SAAS,EAAE,cAAc;gBACzB,QAAQ,EAAE,iBAAiB;gBAC3B,uBAAuB,EAAE,WAAW,CAAC,uBAAuB;gBAC5D,qBAAqB,EAAE,WAAW,CAAC,cAAc;gBACjD,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC,MAAM;aACnC,CAAC,CAAC;YAEH,oBAAoB;YACpB,MAAM,iBAAiB,GAAG,MAAM,SAAS,CACxC,OAAO,CAAC,WAAW,EAAE,EACrB,eAAe,EACf,iBAAiB,CACjB,CAAC;YACF,IAAI,iBAAiB,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAC9C,MAAM,SAAS,GAAuB,YAAY,CAAC;gBACnD,OAAO,IAAI,CAAC,SAAS,EAAE,IAAI,qBAAqB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC9E,CAAC;YACD,IAAI,iBAAiB,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBACzC,MAAM,SAAS,GAAuB,uBAAuB,CAAC;gBAC9D,8FAA8F;gBAC9F,qEAAqE;gBACrE,OAAO,IAAI,CACV,SAAS,EACT,IAAI,qBAAqB,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,uBAAuB,CAAC,CAC/E,CAAC;YACH,CAAC;YACD,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC;YAC1C,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAE7B,6BAA6B;YAC7B,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,WAAW,CAAC;YAEhF,wBAAwB;YACxB,uBAAuB,GAAG;gBACzB,eAAe,EAAE,eAAe;gBAChC,qBAAqB,EAAE,SAAS,CAAC,cAAc;gBAC/C,qBAAqB,EAAE,SAAS,CAAC,QAAQ,CAAC,eAAe,CAAC,qBAAqB;gBAC/E,GAAG,uBAAuB;aAC1B,CAAC;YACF,IAAI,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,UAAU,EAAE,CAAC;gBAC/C,gBAAgB,CAAC,uBAAuB,CAAC,aAAa,CAAC,CAAC;gBACxD,IAAI,CAAC,aAAa,CAAC,2BAA2B,EAAE,CAAC;gBACjD,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBACjC,cAAc,CAAC,GAAG,CAAC;oBAClB,GAAG,uBAAuB;oBAC1B,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM;iBACjC,CAAC,CAAC;gBACH,sGAAsG;gBACtG,6DAA6D;gBAC7D,MAAM,IAAI,CAAC,4BAA4B,CAAC;oBACvC,cAAc,EAAE,WAAW,CAAC,QAAQ,CAAC,MAAM;oBAC3C,SAAS,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM;oBACpC,aAAa,EAAE,WAAW,CAAC,uBAAuB;oBAClD,aAAa;iBACb,CAAC,CAAC;gBACH,cAAc,CAAC,wBAAwB,CAAC,OAAO,CAAC;oBAC/C,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE;wBACL,YAAY,EAAE,SAAS;wBACvB,eAAe;qBACf;iBACD,CAAC,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACP,gDAAgD;gBAChD,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBAC7E,gBAAgB,CAAC,uBAAuB,CAAC,cAAc,CAAC,CAAC;gBACzD,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC;gBACvC,MAAM,YAAY,GAAG,WAAW,EAAE,OAAO,CAAC;gBAC1C,MAAM,iBAAiB,GAAG,WAAW,EAAE,UAAU,CAAC;gBAElD,MAAM,SAAS,GAAuB,aAAa,CAAC;gBAEpD,6CAA6C;gBAC7C,MAAM,KAAK,GAAG,IAAI,qBAAqB,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,iBAAiB,EAAE;oBACrF,YAAY;iBACZ,CAAC,CAAC;gBAEH,MAAM,CACL,6BAA6B,CAAC,KAAK,CAAC,KAAK,iBAAiB,EAC1D,KAAK,CAAC,yBAAyB,CAC/B,CAAC;gBACF,iGAAiG;gBACjG,OAAO,IAAI,CACV,SAAS,EACT,KAAK,EACL,EAAE,GAAG,uBAAuB,EAAE,cAAc,EAAE,iBAAiB,EAAE,EACjE,SAAS,CAAC,yBAAyB,EACnC,EAAE,aAAa,EAAE,SAAS,EAAE,eAAe,EAAE,CAC7C,CAAC;YACH,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,sBAAsB,GAAG,SAAS,CAAC;QACzC,CAAC;IACF,CAAC;IAEO,8BAA8B,CACrC,WAAgC,EAChC,YAAuC;QAEvC,QAAQ,WAAW,CAAC,KAAK,EAAE,CAAC;YAC3B,KAAK,MAAM,CAAC,CAAC,CAAC;gBACb,OAAO,YAAY,CAAC;YACrB,CAAC;YAED,KAAK,UAAU,CAAC,CAAC,CAAC;gBACjB,OAAO;oBACN,GAAG,YAAY;oBACf,GAAG,WAAW,CAAC,YAAY;oBAC3B,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;iBAC9C,CAAC;YACH,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,OAAO;oBACN,GAAG,YAAY;oBACf,GAAG,WAAW,CAAC,YAAY;oBAC3B,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;oBAC9C,MAAM,EAAE,WAAW,CAAC,MAAM;oBAC1B,cAAc,EAAE,WAAW,CAAC,cAAc;iBAC1C,CAAC;YACH,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,OAAO;oBACN,GAAG,YAAY;oBACf,GAAG,WAAW,CAAC,YAAY;oBAC3B,gBAAgB,EAAE,WAAW,CAAC,gBAAgB;oBAC9C,MAAM,EAAE,WAAW,CAAC,MAAM;oBAC1B,cAAc,EAAE,WAAW,CAAC,cAAc;oBAC1C,oBAAoB,EAAE,WAAW,CAAC,oBAAoB;oBACtD,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,gBAAgB;oBACrD,wBAAwB,EAAE,IAAI,CAAC,aAAa,CAAC,YAAY;iBACzD,CAAC;YACH,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACT,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAC;YACpD,CAAC;QACF,CAAC;QAED,OAAO,YAAY,CAAC;IACrB,CAAC;IAEO,qBAAqB,CAAC,IAAY,EAAE,KAAa;QACxD,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC;YAChC,SAAS,EAAE,kBAAkB;YAC7B,WAAW,EAAE,IAAI;YACjB,YAAY,EAAE,KAAK;YACnB,oBAAoB,EAAE,IAAI,CAAC,sBAAsB,EAAE,uBAAuB,EAAE;SAC5E,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;YAC7B,YAAY,EAAE,KAAK;YACnB,oBAAoB,EAAE,IAAI,CAAC,sBAAsB,EAAE,uBAAuB,EAAE;YAC5E,yBAAyB,EAAE,IAAI,CAAC,aAAa,CAAC,aAAa;YAC3D,4BAA4B,EAAE,IAAI,CAAC,aAAa,CAAC,gBAAgB;SACjE,CAAC,CAAC;QACH,IAAI,KAAK,GAAG,wBAAwB,EAAE,CAAC;YACtC,+BAA+B;YAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC;YAC1B,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,CACxC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAC/C,CAAC;QACH,CAAC;IACF,CAAC;IAEM,OAAO;QACb,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,sBAAsB,GAAG,SAAS,CAAC;IACzC,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { ISummarizerEvents } from \"@fluidframework/container-runtime-definitions/internal\";\nimport { assert, type IPromiseTimer, Timer } from \"@fluidframework/core-utils/internal\";\nimport { DriverErrorTypes, MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport { getRetryDelaySecondsFromError } from \"@fluidframework/driver-utils/internal\";\nimport { TelemetryContext } from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tisFluidError,\n\ttype ITelemetryLoggerExt,\n\tPerformanceEvent,\n\twrapError,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport type {\n\tIRefreshSummaryAckOptions,\n\tIRetriableFailureError,\n\tISubmitSummaryOptions,\n\tISummarizeHeuristicData,\n\tSubmitSummaryFailureData,\n\tSubmitSummaryResult,\n\tSummaryGeneratorTelemetry,\n} from \"../summarizerTypes.js\";\nimport {\n\tRetriableSummaryError,\n\tgetFailMessage,\n\traceTimer,\n\ttype SummarizeErrorCode,\n} from \"../summarizerUtils.js\";\nimport type { IClientSummaryWatcher } from \"../summaryCollection.js\";\n\nimport { SummarizeResultBuilder } from \"./summaryResultBuilder.js\";\nimport type { INackSummaryResult, ISummarizeResults } from \"./summaryResultTypes.js\";\n\n// Send some telemetry if generate summary takes too long\nconst maxSummarizeTimeoutTime = 20000; // 20 sec\nconst maxSummarizeTimeoutCount = 5; // Double and resend 5 times\n\n/**\n * This class generates and tracks a summary attempt.\n */\nexport class SummaryGenerator extends TypedEventEmitter<ISummarizerEvents> {\n\tprivate readonly summarizeTimer: Timer;\n\tprivate activeTelemetryContext?: TelemetryContext;\n\tconstructor(\n\t\tprivate readonly pendingAckTimer: IPromiseTimer,\n\t\tprivate readonly heuristicData: ISummarizeHeuristicData,\n\t\tprivate readonly submitSummaryCallback: (\n\t\t\toptions: ISubmitSummaryOptions,\n\t\t) => Promise<SubmitSummaryResult>,\n\t\tprivate readonly successfulSummaryCallback: () => void,\n\t\tprivate readonly refreshLatestSummaryCallback: (\n\t\t\toptions: IRefreshSummaryAckOptions,\n\t\t) => Promise<void>,\n\t\tprivate readonly summaryWatcher: Pick<IClientSummaryWatcher, \"watchSummary\">,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {\n\t\tsuper();\n\t\tthis.summarizeTimer = new Timer(maxSummarizeTimeoutTime, () =>\n\t\t\tthis.summarizeTimerHandler(maxSummarizeTimeoutTime, 1),\n\t\t);\n\t}\n\n\t/**\n\t * Generates summary and listens for broadcast and ack/nack.\n\t * Returns true for ack, false for nack, and undefined for failure or timeout.\n\t * @param summaryOptions - options controlling how the summary is generated or submitted.\n\t * @param resultsBuilder - optional, result builder to use to build pass or fail result.\n\t */\n\tpublic summarize(\n\t\tsummaryOptions: ISubmitSummaryOptions,\n\t\tresultsBuilder = new SummarizeResultBuilder(),\n\t): ISummarizeResults {\n\t\tthis.summarizeCore(summaryOptions, resultsBuilder).catch(\n\t\t\t(error: IRetriableFailureError) => {\n\t\t\t\tconst message = \"UnexpectedSummarizeError\";\n\t\t\t\tsummaryOptions.summaryLogger.sendErrorEvent({ eventName: message }, error);\n\t\t\t\tresultsBuilder.fail(message, error);\n\t\t\t},\n\t\t);\n\n\t\treturn resultsBuilder.build();\n\t}\n\n\tprivate async summarizeCore(\n\t\tsubmitSummaryOptions: ISubmitSummaryOptions,\n\t\tresultsBuilder: SummarizeResultBuilder,\n\t): Promise<void> {\n\t\tconst {\n\t\t\tsummaryLogger,\n\t\t\tcancellationToken,\n\t\t\ttelemetryContext = new TelemetryContext(),\n\t\t\t...summarizeOptions\n\t\t} = submitSummaryOptions;\n\n\t\ttelemetryContext.setCurrentSummarizeStep(\"submitSummary\");\n\t\tconst submitOptions = { ...submitSummaryOptions, telemetryContext };\n\t\tthis.activeTelemetryContext = telemetryContext;\n\n\t\t// Note: timeSinceLastAttempt and timeSinceLastSummary for the\n\t\t// first summary are basically the time since the summarizer was loaded.\n\t\tconst timeSinceLastAttempt = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n\t\tconst timeSinceLastSummary =\n\t\t\tDate.now() - this.heuristicData.lastSuccessfulSummary.summaryTime;\n\t\tlet summarizeTelemetryProps: SummaryGeneratorTelemetry = {\n\t\t\t...summarizeOptions,\n\t\t\tfullTree: summarizeOptions.fullTree ?? false,\n\t\t\ttimeSinceLastAttempt,\n\t\t\ttimeSinceLastSummary,\n\t\t\tnonRuntimeOpsSinceLastSummary: this.heuristicData.numNonRuntimeOps,\n\t\t\truntimeOpsSinceLastSummary: this.heuristicData.numRuntimeOps,\n\t\t};\n\n\t\tconst summarizeEvent = PerformanceEvent.start(\n\t\t\tsummaryLogger,\n\t\t\t{\n\t\t\t\teventName: \"Summarize\",\n\t\t\t\t...summarizeTelemetryProps,\n\t\t\t},\n\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t);\n\n\t\tlet summaryData: SubmitSummaryResult | undefined;\n\n\t\t/**\n\t\t * Summarization can fail during submit, during op broadcast or during nack.\n\t\t * For submit failures, submitFailureResult should be provided. For nack failures, nackSummaryResult should\n\t\t * be provided. For op broadcast failures, only errors / properties should be provided.\n\t\t */\n\t\tconst fail = (\n\t\t\terrorCode: SummarizeErrorCode,\n\t\t\terror: IRetriableFailureError,\n\t\t\tproperties?: SummaryGeneratorTelemetry,\n\t\t\tsubmitFailureResult?: SubmitSummaryFailureData,\n\t\t\tnackSummaryResult?: INackSummaryResult,\n\t\t): void => {\n\t\t\t// Report any failure as an error unless it was due to cancellation (like \"disconnected\" error)\n\t\t\t// If failure happened on upload, we may not yet realized that socket disconnected, so check\n\t\t\t// offlineError too.\n\t\t\tconst category =\n\t\t\t\tcancellationToken.cancelled ||\n\t\t\t\t(isFluidError(error) && error?.errorType === DriverErrorTypes.offlineError)\n\t\t\t\t\t? \"generic\"\n\t\t\t\t\t: \"error\";\n\n\t\t\tconst reason = getFailMessage(errorCode);\n\t\t\tsummarizeEvent.cancel(\n\t\t\t\t{\n\t\t\t\t\t...properties,\n\t\t\t\t\treason,\n\t\t\t\t\tcategory,\n\t\t\t\t\tretryAfterSeconds: error.retryAfterSeconds,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t); // disconnect & summaryAckTimeout do not have proper error.\n\n\t\t\tresultsBuilder.fail(reason, error, submitFailureResult, nackSummaryResult);\n\t\t};\n\n\t\t// Wait to generate and send summary\n\t\tthis.summarizeTimer.start();\n\t\ttry {\n\t\t\ttelemetryContext.setCurrentSummarizeStep(\"generateSummary\");\n\t\t\t// Need to save refSeqNum before we record new attempt (happens as part of submitSummaryCallback)\n\t\t\tconst lastAttemptRefSeqNum = this.heuristicData.lastAttempt.refSequenceNumber;\n\n\t\t\tsummaryData = await this.submitSummaryCallback(submitOptions);\n\t\t\ttelemetryContext.setCurrentSummarizeStep(\"submitSummaryOp\");\n\n\t\t\t// Cumulatively add telemetry properties based on how far generateSummary went.\n\t\t\tconst referenceSequenceNumber = summaryData.referenceSequenceNumber;\n\t\t\tsummarizeTelemetryProps = {\n\t\t\t\t...summarizeTelemetryProps,\n\t\t\t\treferenceSequenceNumber,\n\t\t\t\tminimumSequenceNumber: summaryData.minimumSequenceNumber,\n\t\t\t\topsSinceLastAttempt: referenceSequenceNumber - lastAttemptRefSeqNum,\n\t\t\t\topsSinceLastSummary:\n\t\t\t\t\treferenceSequenceNumber - this.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n\t\t\t\tstage: summaryData.stage,\n\t\t\t};\n\t\t\tsummarizeTelemetryProps = this.addSummaryDataToTelemetryProps(\n\t\t\t\tsummaryData,\n\t\t\t\tsummarizeTelemetryProps,\n\t\t\t);\n\n\t\t\tif (summaryData.stage !== \"submit\") {\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"submitSummaryFailure\";\n\t\t\t\tconst retriableError =\n\t\t\t\t\tsummaryData.error ?? new RetriableSummaryError(getFailMessage(errorCode));\n\t\t\t\treturn fail(errorCode, retriableError, summarizeTelemetryProps, {\n\t\t\t\t\tstage: summaryData.stage,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * With incremental summaries, if the full tree was not summarized, only data stores that changed should\n\t\t\t * be summarized. A data store is considered changed if either or both of the following is true:\n\t\t\t * - It has received an op.\n\t\t\t * - Its reference state changed, i.e., it went from referenced to unreferenced or vice-versa.\n\t\t\t *\n\t\t\t * In the extreme case, every op can be for a different data store and each op can result in the reference\n\t\t\t * state change of multiple data stores. So, the total number of data stores that are summarized should not\n\t\t\t * exceed the number of ops since last summary + number of data store whose reference state changed.\n\t\t\t */\n\t\t\tif (submitSummaryOptions.fullTree !== true) {\n\t\t\t\ttelemetryContext.setCurrentSummarizeStep(\"watchSummary\");\n\t\t\t\tconst { summarizedDataStoreCount, gcStateUpdatedDataStoreCount = 0 } =\n\t\t\t\t\tsummaryData.summaryStats;\n\t\t\t\tif (\n\t\t\t\t\tsummarizedDataStoreCount >\n\t\t\t\t\tgcStateUpdatedDataStoreCount + this.heuristicData.opsSinceLastSummary\n\t\t\t\t) {\n\t\t\t\t\tsummaryLogger.sendErrorEvent({\n\t\t\t\t\t\teventName: \"IncrementalSummaryViolation\",\n\t\t\t\t\t\tsummarizedDataStoreCount,\n\t\t\t\t\t\tgcStateUpdatedDataStoreCount,\n\t\t\t\t\t\topsSinceLastSummary: this.heuristicData.opsSinceLastSummary,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Log event here on summary success only, as Summarize_cancel duplicates failure logging.\n\t\t\tsummarizeEvent.reportEvent(\"generate\", { ...summarizeTelemetryProps });\n\t\t\tresultsBuilder.summarySubmitted.resolve({ success: true, data: summaryData });\n\t\t} catch (error) {\n\t\t\treturn fail(\n\t\t\t\t\"submitSummaryFailure\",\n\t\t\t\twrapError(\n\t\t\t\t\terror,\n\t\t\t\t\t(message) =>\n\t\t\t\t\t\tnew RetriableSummaryError(message, getRetryDelaySecondsFromError(error)),\n\t\t\t\t),\n\t\t\t\tundefined /* properties */,\n\t\t\t\t{\n\t\t\t\t\tstage: \"unknown\",\n\t\t\t\t},\n\t\t\t);\n\t\t} finally {\n\t\t\tif (summaryData === undefined) {\n\t\t\t\tthis.heuristicData.recordAttempt();\n\t\t\t}\n\t\t\tthis.summarizeTimer.clear();\n\t\t}\n\n\t\ttelemetryContext.setCurrentSummarizeStep(\"waitForSummaryAck\");\n\n\t\ttry {\n\t\t\tconst pendingTimeoutP = this.pendingAckTimer.start();\n\t\t\tconst summary = this.summaryWatcher.watchSummary(summaryData.clientSequenceNumber);\n\n\t\t\t// Wait for broadcast\n\t\t\tconst waitBroadcastResult = await raceTimer(\n\t\t\t\tsummary.waitBroadcast(),\n\t\t\t\tpendingTimeoutP,\n\t\t\t\tcancellationToken,\n\t\t\t);\n\t\t\tif (waitBroadcastResult.result === \"cancelled\") {\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"disconnect\";\n\t\t\t\treturn fail(errorCode, new RetriableSummaryError(getFailMessage(errorCode)));\n\t\t\t}\n\t\t\tif (waitBroadcastResult.result !== \"done\") {\n\t\t\t\t// The summary op may not have been received within the timeout due to a transient error. So,\n\t\t\t\t// fail with a retriable error to re-attempt the summary if possible.\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"summaryOpWaitTimeout\";\n\t\t\t\treturn fail(\n\t\t\t\t\terrorCode,\n\t\t\t\t\tnew RetriableSummaryError(getFailMessage(errorCode), 0 /* retryAfterSeconds */),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst summarizeOp = waitBroadcastResult.value;\n\n\t\t\tconst broadcastDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n\t\t\tresultsBuilder.summaryOpBroadcasted.resolve({\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { summarizeOp, broadcastDuration },\n\t\t\t});\n\n\t\t\tthis.heuristicData.lastAttempt.summarySequenceNumber = summarizeOp.sequenceNumber;\n\t\t\tsummaryLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"Summarize_Op\",\n\t\t\t\tduration: broadcastDuration,\n\t\t\t\treferenceSequenceNumber: summarizeOp.referenceSequenceNumber,\n\t\t\t\tsummarySequenceNumber: summarizeOp.sequenceNumber,\n\t\t\t\thandle: summarizeOp.contents.handle,\n\t\t\t});\n\n\t\t\t// Wait for ack/nack\n\t\t\tconst waitAckNackResult = await raceTimer(\n\t\t\t\tsummary.waitAckNack(),\n\t\t\t\tpendingTimeoutP,\n\t\t\t\tcancellationToken,\n\t\t\t);\n\t\t\tif (waitAckNackResult.result === \"cancelled\") {\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"disconnect\";\n\t\t\t\treturn fail(errorCode, new RetriableSummaryError(getFailMessage(errorCode)));\n\t\t\t}\n\t\t\tif (waitAckNackResult.result !== \"done\") {\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"summaryAckWaitTimeout\";\n\t\t\t\t// The summary ack may not have been received within the timeout due to a transient error. So,\n\t\t\t\t// fail with a retriable error to re-attempt the summary if possible.\n\t\t\t\treturn fail(\n\t\t\t\t\terrorCode,\n\t\t\t\t\tnew RetriableSummaryError(getFailMessage(errorCode), 0 /* retryAfterSeconds */),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst ackNackOp = waitAckNackResult.value;\n\t\t\tthis.pendingAckTimer.clear();\n\n\t\t\t// Update for success/failure\n\t\t\tconst ackNackDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n\n\t\t\t// adding new properties\n\t\t\tsummarizeTelemetryProps = {\n\t\t\t\tackWaitDuration: ackNackDuration,\n\t\t\t\tackNackSequenceNumber: ackNackOp.sequenceNumber,\n\t\t\t\tsummarySequenceNumber: ackNackOp.contents.summaryProposal.summarySequenceNumber,\n\t\t\t\t...summarizeTelemetryProps,\n\t\t\t};\n\t\t\tif (ackNackOp.type === MessageType.SummaryAck) {\n\t\t\t\ttelemetryContext.setCurrentSummarizeStep(\"ackReceived\");\n\t\t\t\tthis.heuristicData.markLastAttemptAsSuccessful();\n\t\t\t\tthis.successfulSummaryCallback();\n\t\t\t\tsummarizeEvent.end({\n\t\t\t\t\t...summarizeTelemetryProps,\n\t\t\t\t\thandle: ackNackOp.contents.handle,\n\t\t\t\t});\n\t\t\t\t// This processes the summary ack of the successful summary. This is so that the next summary does not\n\t\t\t\t// start before the ack of the previous summary is processed.\n\t\t\t\tawait this.refreshLatestSummaryCallback({\n\t\t\t\t\tproposalHandle: summarizeOp.contents.handle,\n\t\t\t\t\tackHandle: ackNackOp.contents.handle,\n\t\t\t\t\tsummaryRefSeq: summarizeOp.referenceSequenceNumber,\n\t\t\t\t\tsummaryLogger,\n\t\t\t\t});\n\t\t\t\tresultsBuilder.receivedSummaryAckOrNack.resolve({\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tsummaryAckOp: ackNackOp,\n\t\t\t\t\t\tackNackDuration,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Check for retryDelay in summaryNack response.\n\t\t\t\tassert(ackNackOp.type === MessageType.SummaryNack, 0x274 /* \"type check\" */);\n\t\t\t\ttelemetryContext.setCurrentSummarizeStep(\"nackReceived\");\n\t\t\t\tconst summaryNack = ackNackOp.contents;\n\t\t\t\tconst errorMessage = summaryNack?.message;\n\t\t\t\tconst retryAfterSeconds = summaryNack?.retryAfter;\n\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"summaryNack\";\n\n\t\t\t\t// pre-0.58 error message prefix: summaryNack\n\t\t\t\tconst error = new RetriableSummaryError(getFailMessage(errorCode), retryAfterSeconds, {\n\t\t\t\t\terrorMessage,\n\t\t\t\t});\n\n\t\t\t\tassert(\n\t\t\t\t\tgetRetryDelaySecondsFromError(error) === retryAfterSeconds,\n\t\t\t\t\t0x25f /* \"retryAfterSeconds\" */,\n\t\t\t\t);\n\t\t\t\t// This will only set resultsBuilder.receivedSummaryAckOrNack, as other promises are already set.\n\t\t\t\treturn fail(\n\t\t\t\t\terrorCode,\n\t\t\t\t\terror,\n\t\t\t\t\t{ ...summarizeTelemetryProps, nackRetryAfter: retryAfterSeconds },\n\t\t\t\t\tundefined /* submitFailureResult */,\n\t\t\t\t\t{ summaryNackOp: ackNackOp, ackNackDuration },\n\t\t\t\t);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.pendingAckTimer.clear();\n\t\t\tthis.activeTelemetryContext = undefined;\n\t\t}\n\t}\n\n\tprivate addSummaryDataToTelemetryProps(\n\t\tsummaryData: SubmitSummaryResult,\n\t\tinitialProps: SummaryGeneratorTelemetry,\n\t): SummaryGeneratorTelemetry {\n\t\tswitch (summaryData.stage) {\n\t\t\tcase \"base\": {\n\t\t\t\treturn initialProps;\n\t\t\t}\n\n\t\t\tcase \"generate\": {\n\t\t\t\treturn {\n\t\t\t\t\t...initialProps,\n\t\t\t\t\t...summaryData.summaryStats,\n\t\t\t\t\tgenerateDuration: summaryData.generateDuration,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"upload\": {\n\t\t\t\treturn {\n\t\t\t\t\t...initialProps,\n\t\t\t\t\t...summaryData.summaryStats,\n\t\t\t\t\tgenerateDuration: summaryData.generateDuration,\n\t\t\t\t\thandle: summaryData.handle,\n\t\t\t\t\tuploadDuration: summaryData.uploadDuration,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"submit\": {\n\t\t\t\treturn {\n\t\t\t\t\t...initialProps,\n\t\t\t\t\t...summaryData.summaryStats,\n\t\t\t\t\tgenerateDuration: summaryData.generateDuration,\n\t\t\t\t\thandle: summaryData.handle,\n\t\t\t\t\tuploadDuration: summaryData.uploadDuration,\n\t\t\t\t\tclientSequenceNumber: summaryData.clientSequenceNumber,\n\t\t\t\t\thasMissingOpData: this.heuristicData.hasMissingOpData,\n\t\t\t\t\topsSizesSinceLastSummary: this.heuristicData.totalOpsSize,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tassert(true, 0x397 /* Unexpected summary stage */);\n\t\t\t}\n\t\t}\n\n\t\treturn initialProps;\n\t}\n\n\tprivate summarizeTimerHandler(time: number, count: number): void {\n\t\tthis.logger.sendPerformanceEvent({\n\t\t\teventName: \"SummarizeTimeout\",\n\t\t\ttimeoutTime: time,\n\t\t\ttimeoutCount: count,\n\t\t\tcurrentSummarizeStep: this.activeTelemetryContext?.getCurrentSummarizeStep(),\n\t\t});\n\t\tthis.emit(\"summarizeTimeout\", {\n\t\t\ttimeoutCount: count,\n\t\t\tcurrentSummarizeStep: this.activeTelemetryContext?.getCurrentSummarizeStep(),\n\t\t\tnumUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,\n\t\t\tnumUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,\n\t\t});\n\t\tif (count < maxSummarizeTimeoutCount) {\n\t\t\t// Double and start a new timer\n\t\t\tconst nextTime = time * 2;\n\t\t\tthis.summarizeTimer.start(nextTime, () =>\n\t\t\t\tthis.summarizeTimerHandler(nextTime, count + 1),\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.summarizeTimer.clear();\n\t\tthis.activeTelemetryContext = undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"summaryGenerator.js","sourceRoot":"","sources":["../../../src/summary/summaryDelayLoadedModule/summaryGenerator.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 { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { ISummarizerEvents } from \"@fluidframework/container-runtime-definitions/internal\";\nimport { assert, type IPromiseTimer, Timer } from \"@fluidframework/core-utils/internal\";\nimport { DriverErrorTypes, MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport { getRetryDelaySecondsFromError } from \"@fluidframework/driver-utils/internal\";\nimport { TelemetryContext } from \"@fluidframework/runtime-utils/internal\";\nimport {\n\tisFluidError,\n\ttype ITelemetryLoggerExt,\n\tPerformanceEvent,\n\twrapError,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport type {\n\tIRefreshSummaryAckOptions,\n\tIRetriableFailureError,\n\tISubmitSummaryOptions,\n\tISummarizeHeuristicData,\n\tSubmitSummaryFailureData,\n\tSubmitSummaryResult,\n\tSummaryGeneratorTelemetry,\n} from \"../summarizerTypes.js\";\nimport {\n\tRetriableSummaryError,\n\tgetFailMessage,\n\traceTimer,\n\ttype SummarizeErrorCode,\n} from \"../summarizerUtils.js\";\nimport type { IClientSummaryWatcher } from \"../summaryCollection.js\";\n\nimport { SummarizeResultBuilder } from \"./summaryResultBuilder.js\";\nimport type { INackSummaryResult, ISummarizeResults } from \"./summaryResultTypes.js\";\n\n// Send some telemetry if generate summary takes too long\nconst maxSummarizeTimeoutTime = 20000; // 20 sec\nconst maxSummarizeTimeoutCount = 5; // Double and resend 5 times\n\n/**\n * This class generates and tracks a summary attempt.\n */\nexport class SummaryGenerator extends TypedEventEmitter<ISummarizerEvents> {\n\tprivate readonly summarizeTimer: Timer;\n\tprivate activeTelemetryContext?: TelemetryContext;\n\tconstructor(\n\t\tprivate readonly pendingAckTimer: IPromiseTimer,\n\t\tprivate readonly heuristicData: ISummarizeHeuristicData,\n\t\tprivate readonly submitSummaryCallback: (\n\t\t\toptions: ISubmitSummaryOptions,\n\t\t) => Promise<SubmitSummaryResult>,\n\t\tprivate readonly successfulSummaryCallback: () => void,\n\t\tprivate readonly refreshLatestSummaryCallback: (\n\t\t\toptions: IRefreshSummaryAckOptions,\n\t\t) => Promise<void>,\n\t\tprivate readonly summaryWatcher: Pick<IClientSummaryWatcher, \"watchSummary\">,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t) {\n\t\tsuper();\n\t\tthis.summarizeTimer = new Timer(maxSummarizeTimeoutTime, () =>\n\t\t\tthis.summarizeTimerHandler(maxSummarizeTimeoutTime, 1),\n\t\t);\n\t}\n\n\t/**\n\t * Generates summary and listens for broadcast and ack/nack.\n\t * Returns true for ack, false for nack, and undefined for failure or timeout.\n\t * @param summaryOptions - options controlling how the summary is generated or submitted.\n\t * @param resultsBuilder - optional, result builder to use to build pass or fail result.\n\t */\n\tpublic summarize(\n\t\tsummaryOptions: ISubmitSummaryOptions,\n\t\tresultsBuilder = new SummarizeResultBuilder(),\n\t): ISummarizeResults {\n\t\tthis.summarizeCore(summaryOptions, resultsBuilder).catch(\n\t\t\t(error: IRetriableFailureError) => {\n\t\t\t\tconst message = \"UnexpectedSummarizeError\";\n\t\t\t\tsummaryOptions.summaryLogger.sendErrorEvent({ eventName: message }, error);\n\t\t\t\tresultsBuilder.fail(message, error);\n\t\t\t},\n\t\t);\n\n\t\treturn resultsBuilder.build();\n\t}\n\n\tprivate async summarizeCore(\n\t\tsubmitSummaryOptions: ISubmitSummaryOptions,\n\t\tresultsBuilder: SummarizeResultBuilder,\n\t): Promise<void> {\n\t\tconst {\n\t\t\tsummaryLogger,\n\t\t\tcancellationToken,\n\t\t\ttelemetryContext = new TelemetryContext(),\n\t\t\t...summarizeOptions\n\t\t} = submitSummaryOptions;\n\n\t\ttelemetryContext.setCurrentSummarizeStep(\"submitSummary\");\n\t\tconst submitOptions = { ...submitSummaryOptions, telemetryContext };\n\t\tthis.activeTelemetryContext = telemetryContext;\n\n\t\t// Note: timeSinceLastAttempt and timeSinceLastSummary for the\n\t\t// first summary are basically the time since the summarizer was loaded.\n\t\tconst timeSinceLastAttempt = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n\t\tconst timeSinceLastSummary =\n\t\t\tDate.now() - this.heuristicData.lastSuccessfulSummary.summaryTime;\n\t\tlet summarizeTelemetryProps: SummaryGeneratorTelemetry = {\n\t\t\t...summarizeOptions,\n\t\t\tfullTree: summarizeOptions.fullTree ?? false,\n\t\t\ttimeSinceLastAttempt,\n\t\t\ttimeSinceLastSummary,\n\t\t\tnonRuntimeOpsSinceLastSummary: this.heuristicData.numNonRuntimeOps,\n\t\t\truntimeOpsSinceLastSummary: this.heuristicData.numRuntimeOps,\n\t\t};\n\n\t\tconst summarizeEvent = PerformanceEvent.start(\n\t\t\tsummaryLogger,\n\t\t\t{\n\t\t\t\teventName: \"Summarize\",\n\t\t\t\t...summarizeTelemetryProps,\n\t\t\t},\n\t\t\t{ start: true, end: true, cancel: \"generic\" },\n\t\t);\n\n\t\tlet summaryData: SubmitSummaryResult | undefined;\n\n\t\t/**\n\t\t * Summarization can fail during submit, during op broadcast or during nack.\n\t\t * For submit failures, submitFailureResult should be provided. For nack failures, nackSummaryResult should\n\t\t * be provided. For op broadcast failures, only errors / properties should be provided.\n\t\t */\n\t\tconst summaryFail = (\n\t\t\terrorCode: SummarizeErrorCode,\n\t\t\terror: IRetriableFailureError,\n\t\t\tproperties?: SummaryGeneratorTelemetry,\n\t\t\tsubmitFailureResult?: SubmitSummaryFailureData,\n\t\t\tnackSummaryResult?: INackSummaryResult,\n\t\t): void => {\n\t\t\t// Report any failure as an error unless it was due to cancellation (like \"disconnected\" error)\n\t\t\t// If failure happened on upload, we may not yet realized that socket disconnected, so check\n\t\t\t// offlineError too.\n\t\t\tconst category =\n\t\t\t\tcancellationToken.cancelled ||\n\t\t\t\t(isFluidError(error) && error?.errorType === DriverErrorTypes.offlineError)\n\t\t\t\t\t? \"generic\"\n\t\t\t\t\t: \"error\";\n\n\t\t\tconst reason = getFailMessage(errorCode);\n\t\t\tsummarizeEvent.cancel(\n\t\t\t\t{\n\t\t\t\t\t...properties,\n\t\t\t\t\treason,\n\t\t\t\t\tcategory,\n\t\t\t\t\tretryAfterSeconds: error.retryAfterSeconds,\n\t\t\t\t},\n\t\t\t\terror,\n\t\t\t); // disconnect & summaryAckTimeout do not have proper error.\n\n\t\t\tresultsBuilder.fail(reason, error, submitFailureResult, nackSummaryResult);\n\t\t};\n\n\t\t// Wait to generate and send summary\n\t\tthis.summarizeTimer.start();\n\t\ttry {\n\t\t\ttelemetryContext.setCurrentSummarizeStep(\"generateSummary\");\n\t\t\t// Need to save refSeqNum before we record new attempt (happens as part of submitSummaryCallback)\n\t\t\tconst lastAttemptRefSeqNum = this.heuristicData.lastAttempt.refSequenceNumber;\n\n\t\t\tsummaryData = await this.submitSummaryCallback(submitOptions);\n\t\t\ttelemetryContext.setCurrentSummarizeStep(\"submitSummaryOp\");\n\n\t\t\t// Cumulatively add telemetry properties based on how far generateSummary went.\n\t\t\tconst referenceSequenceNumber = summaryData.referenceSequenceNumber;\n\t\t\tsummarizeTelemetryProps = {\n\t\t\t\t...summarizeTelemetryProps,\n\t\t\t\treferenceSequenceNumber,\n\t\t\t\tminimumSequenceNumber: summaryData.minimumSequenceNumber,\n\t\t\t\topsSinceLastAttempt: referenceSequenceNumber - lastAttemptRefSeqNum,\n\t\t\t\topsSinceLastSummary:\n\t\t\t\t\treferenceSequenceNumber - this.heuristicData.lastSuccessfulSummary.refSequenceNumber,\n\t\t\t\tstage: summaryData.stage,\n\t\t\t};\n\t\t\tsummarizeTelemetryProps = this.addSummaryDataToTelemetryProps(\n\t\t\t\tsummaryData,\n\t\t\t\tsummarizeTelemetryProps,\n\t\t\t);\n\n\t\t\tif (summaryData.stage !== \"submit\") {\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"submitSummaryFailure\";\n\t\t\t\tconst retriableError =\n\t\t\t\t\tsummaryData.error ?? new RetriableSummaryError(getFailMessage(errorCode));\n\t\t\t\treturn summaryFail(errorCode, retriableError, summarizeTelemetryProps, {\n\t\t\t\t\tstage: summaryData.stage,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * With incremental summaries, if the full tree was not summarized, only data stores that changed should\n\t\t\t * be summarized. A data store is considered changed if either or both of the following is true:\n\t\t\t * - It has received an op.\n\t\t\t * - Its reference state changed, i.e., it went from referenced to unreferenced or vice-versa.\n\t\t\t *\n\t\t\t * In the extreme case, every op can be for a different data store and each op can result in the reference\n\t\t\t * state change of multiple data stores. So, the total number of data stores that are summarized should not\n\t\t\t * exceed the number of ops since last summary + number of data store whose reference state changed.\n\t\t\t */\n\t\t\tif (submitSummaryOptions.fullTree !== true) {\n\t\t\t\ttelemetryContext.setCurrentSummarizeStep(\"watchSummary\");\n\t\t\t\tconst { summarizedDataStoreCount, gcStateUpdatedDataStoreCount = 0 } =\n\t\t\t\t\tsummaryData.summaryStats;\n\t\t\t\tif (\n\t\t\t\t\tsummarizedDataStoreCount >\n\t\t\t\t\tgcStateUpdatedDataStoreCount + this.heuristicData.opsSinceLastSummary\n\t\t\t\t) {\n\t\t\t\t\tsummaryLogger.sendErrorEvent({\n\t\t\t\t\t\teventName: \"IncrementalSummaryViolation\",\n\t\t\t\t\t\tsummarizedDataStoreCount,\n\t\t\t\t\t\tgcStateUpdatedDataStoreCount,\n\t\t\t\t\t\topsSinceLastSummary: this.heuristicData.opsSinceLastSummary,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Log event here on summary success only, as Summarize_cancel duplicates failure logging.\n\t\t\tsummarizeEvent.reportEvent(\"generate\", { ...summarizeTelemetryProps });\n\t\t\tresultsBuilder.summarySubmitted.resolve({ success: true, data: summaryData });\n\t\t} catch (error) {\n\t\t\treturn summaryFail(\n\t\t\t\t\"submitSummaryFailure\",\n\t\t\t\twrapError(\n\t\t\t\t\terror,\n\t\t\t\t\t(message) =>\n\t\t\t\t\t\tnew RetriableSummaryError(message, getRetryDelaySecondsFromError(error)),\n\t\t\t\t),\n\t\t\t\tundefined /* properties */,\n\t\t\t\t{\n\t\t\t\t\tstage: \"unknown\",\n\t\t\t\t},\n\t\t\t);\n\t\t} finally {\n\t\t\tif (summaryData === undefined) {\n\t\t\t\tthis.heuristicData.recordAttempt();\n\t\t\t}\n\t\t\tthis.summarizeTimer.clear();\n\t\t}\n\n\t\ttelemetryContext.setCurrentSummarizeStep(\"waitForSummaryAck\");\n\n\t\ttry {\n\t\t\tconst pendingTimeoutP = this.pendingAckTimer.start();\n\t\t\tconst summary = this.summaryWatcher.watchSummary(summaryData.clientSequenceNumber);\n\n\t\t\t// Wait for broadcast\n\t\t\tconst waitBroadcastResult = await raceTimer(\n\t\t\t\tsummary.waitBroadcast(),\n\t\t\t\tpendingTimeoutP,\n\t\t\t\tcancellationToken,\n\t\t\t);\n\t\t\tif (waitBroadcastResult.result === \"cancelled\") {\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"disconnect\";\n\t\t\t\treturn summaryFail(errorCode, new RetriableSummaryError(getFailMessage(errorCode)));\n\t\t\t}\n\t\t\tif (waitBroadcastResult.result !== \"done\") {\n\t\t\t\t// The summary op may not have been received within the timeout due to a transient error. So,\n\t\t\t\t// fail with a retriable error to re-attempt the summary if possible.\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"summaryOpWaitTimeout\";\n\t\t\t\treturn summaryFail(\n\t\t\t\t\terrorCode,\n\t\t\t\t\tnew RetriableSummaryError(getFailMessage(errorCode), 0 /* retryAfterSeconds */),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst summarizeOp = waitBroadcastResult.value;\n\n\t\t\tconst broadcastDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n\t\t\tresultsBuilder.summaryOpBroadcasted.resolve({\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: { summarizeOp, broadcastDuration },\n\t\t\t});\n\n\t\t\tthis.heuristicData.lastAttempt.summarySequenceNumber = summarizeOp.sequenceNumber;\n\t\t\tsummaryLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"Summarize_Op\",\n\t\t\t\tduration: broadcastDuration,\n\t\t\t\treferenceSequenceNumber: summarizeOp.referenceSequenceNumber,\n\t\t\t\tsummarySequenceNumber: summarizeOp.sequenceNumber,\n\t\t\t\thandle: summarizeOp.contents.handle,\n\t\t\t});\n\n\t\t\t// Wait for ack/nack\n\t\t\tconst waitAckNackResult = await raceTimer(\n\t\t\t\tsummary.waitAckNack(),\n\t\t\t\tpendingTimeoutP,\n\t\t\t\tcancellationToken,\n\t\t\t);\n\t\t\tif (waitAckNackResult.result === \"cancelled\") {\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"disconnect\";\n\t\t\t\treturn summaryFail(errorCode, new RetriableSummaryError(getFailMessage(errorCode)));\n\t\t\t}\n\t\t\tif (waitAckNackResult.result !== \"done\") {\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"summaryAckWaitTimeout\";\n\t\t\t\t// The summary ack may not have been received within the timeout due to a transient error. So,\n\t\t\t\t// fail with a retriable error to re-attempt the summary if possible.\n\t\t\t\treturn summaryFail(\n\t\t\t\t\terrorCode,\n\t\t\t\t\tnew RetriableSummaryError(getFailMessage(errorCode), 0 /* retryAfterSeconds */),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst ackNackOp = waitAckNackResult.value;\n\t\t\tthis.pendingAckTimer.clear();\n\n\t\t\t// Update for success/failure\n\t\t\tconst ackNackDuration = Date.now() - this.heuristicData.lastAttempt.summaryTime;\n\n\t\t\t// adding new properties\n\t\t\tsummarizeTelemetryProps = {\n\t\t\t\tackWaitDuration: ackNackDuration,\n\t\t\t\tackNackSequenceNumber: ackNackOp.sequenceNumber,\n\t\t\t\tsummarySequenceNumber: ackNackOp.contents.summaryProposal.summarySequenceNumber,\n\t\t\t\t...summarizeTelemetryProps,\n\t\t\t};\n\t\t\tif (ackNackOp.type === MessageType.SummaryAck) {\n\t\t\t\ttelemetryContext.setCurrentSummarizeStep(\"ackReceived\");\n\t\t\t\tthis.heuristicData.markLastAttemptAsSuccessful();\n\t\t\t\tthis.successfulSummaryCallback();\n\t\t\t\tsummarizeEvent.end({\n\t\t\t\t\t...summarizeTelemetryProps,\n\t\t\t\t\thandle: ackNackOp.contents.handle,\n\t\t\t\t});\n\t\t\t\t// This processes the summary ack of the successful summary. This is so that the next summary does not\n\t\t\t\t// start before the ack of the previous summary is processed.\n\t\t\t\tawait this.refreshLatestSummaryCallback({\n\t\t\t\t\tproposalHandle: summarizeOp.contents.handle,\n\t\t\t\t\tackHandle: ackNackOp.contents.handle,\n\t\t\t\t\tsummaryRefSeq: summarizeOp.referenceSequenceNumber,\n\t\t\t\t\tsummaryLogger,\n\t\t\t\t});\n\t\t\t\tresultsBuilder.receivedSummaryAckOrNack.resolve({\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tsummaryAckOp: ackNackOp,\n\t\t\t\t\t\tackNackDuration,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Check for retryDelay in summaryNack response.\n\t\t\t\tassert(ackNackOp.type === MessageType.SummaryNack, 0x274 /* \"type check\" */);\n\t\t\t\ttelemetryContext.setCurrentSummarizeStep(\"nackReceived\");\n\t\t\t\tconst summaryNack = ackNackOp.contents;\n\t\t\t\tconst errorMessage = summaryNack?.message;\n\t\t\t\tconst retryAfterSeconds = summaryNack?.retryAfter;\n\n\t\t\t\tconst errorCode: SummarizeErrorCode = \"summaryNack\";\n\n\t\t\t\t// pre-0.58 error message prefix: summaryNack\n\t\t\t\tconst error = new RetriableSummaryError(getFailMessage(errorCode), retryAfterSeconds, {\n\t\t\t\t\terrorMessage,\n\t\t\t\t});\n\n\t\t\t\tassert(\n\t\t\t\t\tgetRetryDelaySecondsFromError(error) === retryAfterSeconds,\n\t\t\t\t\t0x25f /* \"retryAfterSeconds\" */,\n\t\t\t\t);\n\t\t\t\t// This will only set resultsBuilder.receivedSummaryAckOrNack, as other promises are already set.\n\t\t\t\treturn summaryFail(\n\t\t\t\t\terrorCode,\n\t\t\t\t\terror,\n\t\t\t\t\t{ ...summarizeTelemetryProps, nackRetryAfter: retryAfterSeconds },\n\t\t\t\t\tundefined /* submitFailureResult */,\n\t\t\t\t\t{ summaryNackOp: ackNackOp, ackNackDuration },\n\t\t\t\t);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.pendingAckTimer.clear();\n\t\t\tthis.activeTelemetryContext = undefined;\n\t\t}\n\t}\n\n\tprivate addSummaryDataToTelemetryProps(\n\t\tsummaryData: SubmitSummaryResult,\n\t\tinitialProps: SummaryGeneratorTelemetry,\n\t): SummaryGeneratorTelemetry {\n\t\tswitch (summaryData.stage) {\n\t\t\tcase \"base\": {\n\t\t\t\treturn initialProps;\n\t\t\t}\n\n\t\t\tcase \"generate\": {\n\t\t\t\treturn {\n\t\t\t\t\t...initialProps,\n\t\t\t\t\t...summaryData.summaryStats,\n\t\t\t\t\tgenerateDuration: summaryData.generateDuration,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"upload\": {\n\t\t\t\treturn {\n\t\t\t\t\t...initialProps,\n\t\t\t\t\t...summaryData.summaryStats,\n\t\t\t\t\tgenerateDuration: summaryData.generateDuration,\n\t\t\t\t\thandle: summaryData.handle,\n\t\t\t\t\tuploadDuration: summaryData.uploadDuration,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"submit\": {\n\t\t\t\treturn {\n\t\t\t\t\t...initialProps,\n\t\t\t\t\t...summaryData.summaryStats,\n\t\t\t\t\tgenerateDuration: summaryData.generateDuration,\n\t\t\t\t\thandle: summaryData.handle,\n\t\t\t\t\tuploadDuration: summaryData.uploadDuration,\n\t\t\t\t\tclientSequenceNumber: summaryData.clientSequenceNumber,\n\t\t\t\t\thasMissingOpData: this.heuristicData.hasMissingOpData,\n\t\t\t\t\topsSizesSinceLastSummary: this.heuristicData.totalOpsSize,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tassert(true, 0x397 /* Unexpected summary stage */);\n\t\t\t}\n\t\t}\n\n\t\treturn initialProps;\n\t}\n\n\tprivate summarizeTimerHandler(time: number, count: number): void {\n\t\tthis.logger.sendPerformanceEvent({\n\t\t\teventName: \"SummarizeTimeout\",\n\t\t\ttimeoutTime: time,\n\t\t\ttimeoutCount: count,\n\t\t\tcurrentSummarizeStep: this.activeTelemetryContext?.getCurrentSummarizeStep(),\n\t\t});\n\t\tthis.emit(\"summarizeTimeout\", {\n\t\t\ttimeoutCount: count,\n\t\t\tcurrentSummarizeStep: this.activeTelemetryContext?.getCurrentSummarizeStep(),\n\t\t\tnumUnsummarizedRuntimeOps: this.heuristicData.numRuntimeOps,\n\t\t\tnumUnsummarizedNonRuntimeOps: this.heuristicData.numNonRuntimeOps,\n\t\t});\n\t\tif (count < maxSummarizeTimeoutCount) {\n\t\t\t// Double and start a new timer\n\t\t\tconst nextTime = time * 2;\n\t\t\tthis.summarizeTimer.start(nextTime, () =>\n\t\t\t\tthis.summarizeTimerHandler(nextTime, count + 1),\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic dispose(): void {\n\t\tthis.summarizeTimer.clear();\n\t\tthis.activeTelemetryContext = undefined;\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-runtime",
3
- "version": "2.80.0",
3
+ "version": "2.81.0",
4
4
  "description": "Fluid container runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -119,18 +119,18 @@
119
119
  "temp-directory": "nyc/.nyc_output"
120
120
  },
121
121
  "dependencies": {
122
- "@fluid-internal/client-utils": "~2.80.0",
123
- "@fluidframework/container-definitions": "~2.80.0",
124
- "@fluidframework/container-runtime-definitions": "~2.80.0",
125
- "@fluidframework/core-interfaces": "~2.80.0",
126
- "@fluidframework/core-utils": "~2.80.0",
127
- "@fluidframework/datastore": "~2.80.0",
128
- "@fluidframework/driver-definitions": "~2.80.0",
129
- "@fluidframework/driver-utils": "~2.80.0",
130
- "@fluidframework/id-compressor": "~2.80.0",
131
- "@fluidframework/runtime-definitions": "~2.80.0",
132
- "@fluidframework/runtime-utils": "~2.80.0",
133
- "@fluidframework/telemetry-utils": "~2.80.0",
122
+ "@fluid-internal/client-utils": "~2.81.0",
123
+ "@fluidframework/container-definitions": "~2.81.0",
124
+ "@fluidframework/container-runtime-definitions": "~2.81.0",
125
+ "@fluidframework/core-interfaces": "~2.81.0",
126
+ "@fluidframework/core-utils": "~2.81.0",
127
+ "@fluidframework/datastore": "~2.81.0",
128
+ "@fluidframework/driver-definitions": "~2.81.0",
129
+ "@fluidframework/driver-utils": "~2.81.0",
130
+ "@fluidframework/id-compressor": "~2.81.0",
131
+ "@fluidframework/runtime-definitions": "~2.81.0",
132
+ "@fluidframework/runtime-utils": "~2.81.0",
133
+ "@fluidframework/telemetry-utils": "~2.81.0",
134
134
  "@tylerbu/sorted-btree-es6": "^1.8.0",
135
135
  "double-ended-queue": "^2.1.0-0",
136
136
  "lz4js": "^0.2.0",
@@ -140,16 +140,16 @@
140
140
  "devDependencies": {
141
141
  "@arethetypeswrong/cli": "^0.18.2",
142
142
  "@biomejs/biome": "~1.9.3",
143
- "@fluid-internal/mocha-test-setup": "~2.80.0",
144
- "@fluid-private/stochastic-test-utils": "~2.80.0",
145
- "@fluid-private/test-pairwise-generator": "~2.80.0",
146
- "@fluid-tools/benchmark": "^0.51.0",
147
- "@fluid-tools/build-cli": "^0.62.0",
143
+ "@fluid-internal/mocha-test-setup": "~2.81.0",
144
+ "@fluid-private/stochastic-test-utils": "~2.81.0",
145
+ "@fluid-private/test-pairwise-generator": "~2.81.0",
146
+ "@fluid-tools/benchmark": "^0.52.0",
147
+ "@fluid-tools/build-cli": "^0.63.0",
148
148
  "@fluidframework/build-common": "^2.0.3",
149
- "@fluidframework/build-tools": "^0.62.0",
150
- "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.74.0",
151
- "@fluidframework/eslint-config-fluid": "~2.80.0",
152
- "@fluidframework/test-runtime-utils": "~2.80.0",
149
+ "@fluidframework/build-tools": "^0.63.0",
150
+ "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.80.0",
151
+ "@fluidframework/eslint-config-fluid": "~2.81.0",
152
+ "@fluidframework/test-runtime-utils": "~2.81.0",
153
153
  "@microsoft/api-extractor": "7.52.11",
154
154
  "@types/double-ended-queue": "^2.1.0",
155
155
  "@types/lz4js": "^0.2.0",
@@ -580,6 +580,7 @@ export abstract class FluidDataStoreContext
580
580
  !this.detachedRuntimeCreation,
581
581
  0x13d /* "Detached runtime creation on realize()" */,
582
582
  );
583
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
583
584
  if (!this.channelP) {
584
585
  this.channelP = this.realizeCore(this.existing).catch((error) => {
585
586
  const errorWrapped = DataProcessingError.wrapIfUnrecognized(
@@ -69,6 +69,7 @@ export class DeltaScheduler {
69
69
  }
70
70
 
71
71
  private readonly batchBegin = (message: ISequencedDocumentMessage): void => {
72
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
72
73
  if (this.processingStartTime === undefined) {
73
74
  this.processingStartTime = performanceNow();
74
75
  }