@fluidframework/container-runtime 2.0.0-internal.4.3.1 → 2.0.0-internal.4.4.1

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 (103) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/blobManager.d.ts.map +1 -1
  3. package/dist/blobManager.js +3 -2
  4. package/dist/blobManager.js.map +1 -1
  5. package/dist/containerRuntime.d.ts.map +1 -1
  6. package/dist/containerRuntime.js +13 -7
  7. package/dist/containerRuntime.js.map +1 -1
  8. package/dist/dataStoreContext.d.ts.map +1 -1
  9. package/dist/dataStoreContext.js +1 -2
  10. package/dist/dataStoreContext.js.map +1 -1
  11. package/dist/gc/garbageCollection.d.ts +55 -43
  12. package/dist/gc/garbageCollection.d.ts.map +1 -1
  13. package/dist/gc/garbageCollection.js +219 -203
  14. package/dist/gc/garbageCollection.js.map +1 -1
  15. package/dist/gc/gcConfigs.d.ts.map +1 -1
  16. package/dist/gc/gcConfigs.js +8 -10
  17. package/dist/gc/gcConfigs.js.map +1 -1
  18. package/dist/gc/gcDefinitions.d.ts +2 -0
  19. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  20. package/dist/gc/gcDefinitions.js.map +1 -1
  21. package/dist/gc/gcHelpers.d.ts +11 -1
  22. package/dist/gc/gcHelpers.d.ts.map +1 -1
  23. package/dist/gc/gcHelpers.js +18 -3
  24. package/dist/gc/gcHelpers.js.map +1 -1
  25. package/dist/gc/gcSummaryStateTracker.d.ts +6 -2
  26. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  27. package/dist/gc/gcSummaryStateTracker.js +16 -6
  28. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  29. package/dist/gc/gcTelemetry.d.ts +2 -2
  30. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  31. package/dist/gc/gcTelemetry.js +42 -22
  32. package/dist/gc/gcTelemetry.js.map +1 -1
  33. package/dist/gc/index.d.ts +1 -2
  34. package/dist/gc/index.d.ts.map +1 -1
  35. package/dist/gc/index.js +2 -5
  36. package/dist/gc/index.js.map +1 -1
  37. package/dist/packageVersion.d.ts +1 -1
  38. package/dist/packageVersion.js +1 -1
  39. package/dist/packageVersion.js.map +1 -1
  40. package/dist/scheduleManager.js +15 -4
  41. package/dist/scheduleManager.js.map +1 -1
  42. package/lib/blobManager.d.ts.map +1 -1
  43. package/lib/blobManager.js +3 -2
  44. package/lib/blobManager.js.map +1 -1
  45. package/lib/containerRuntime.d.ts.map +1 -1
  46. package/lib/containerRuntime.js +13 -7
  47. package/lib/containerRuntime.js.map +1 -1
  48. package/lib/dataStoreContext.d.ts.map +1 -1
  49. package/lib/dataStoreContext.js +1 -2
  50. package/lib/dataStoreContext.js.map +1 -1
  51. package/lib/gc/garbageCollection.d.ts +55 -43
  52. package/lib/gc/garbageCollection.d.ts.map +1 -1
  53. package/lib/gc/garbageCollection.js +219 -203
  54. package/lib/gc/garbageCollection.js.map +1 -1
  55. package/lib/gc/gcConfigs.d.ts.map +1 -1
  56. package/lib/gc/gcConfigs.js +8 -10
  57. package/lib/gc/gcConfigs.js.map +1 -1
  58. package/lib/gc/gcDefinitions.d.ts +2 -0
  59. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  60. package/lib/gc/gcDefinitions.js.map +1 -1
  61. package/lib/gc/gcHelpers.d.ts +11 -1
  62. package/lib/gc/gcHelpers.d.ts.map +1 -1
  63. package/lib/gc/gcHelpers.js +16 -2
  64. package/lib/gc/gcHelpers.js.map +1 -1
  65. package/lib/gc/gcSummaryStateTracker.d.ts +6 -2
  66. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  67. package/lib/gc/gcSummaryStateTracker.js +16 -6
  68. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  69. package/lib/gc/gcTelemetry.d.ts +2 -2
  70. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  71. package/lib/gc/gcTelemetry.js +43 -23
  72. package/lib/gc/gcTelemetry.js.map +1 -1
  73. package/lib/gc/index.d.ts +1 -2
  74. package/lib/gc/index.d.ts.map +1 -1
  75. package/lib/gc/index.js +1 -2
  76. package/lib/gc/index.js.map +1 -1
  77. package/lib/packageVersion.d.ts +1 -1
  78. package/lib/packageVersion.js +1 -1
  79. package/lib/packageVersion.js.map +1 -1
  80. package/lib/scheduleManager.js +15 -4
  81. package/lib/scheduleManager.js.map +1 -1
  82. package/package.json +15 -16
  83. package/src/blobManager.ts +3 -2
  84. package/src/containerRuntime.ts +10 -4
  85. package/src/dataStoreContext.ts +1 -2
  86. package/src/gc/garbageCollection.ts +274 -257
  87. package/src/gc/gcConfigs.ts +12 -11
  88. package/src/gc/gcDefinitions.ts +2 -0
  89. package/src/gc/gcHelpers.ts +20 -2
  90. package/src/gc/gcSummaryStateTracker.ts +19 -7
  91. package/src/gc/gcTelemetry.ts +52 -37
  92. package/src/gc/index.ts +1 -5
  93. package/src/packageVersion.ts +1 -1
  94. package/src/scheduleManager.ts +19 -7
  95. package/dist/gc/gcSweepReadyUsageDetection.d.ts +0 -53
  96. package/dist/gc/gcSweepReadyUsageDetection.d.ts.map +0 -1
  97. package/dist/gc/gcSweepReadyUsageDetection.js +0 -130
  98. package/dist/gc/gcSweepReadyUsageDetection.js.map +0 -1
  99. package/lib/gc/gcSweepReadyUsageDetection.d.ts +0 -53
  100. package/lib/gc/gcSweepReadyUsageDetection.d.ts.map +0 -1
  101. package/lib/gc/gcSweepReadyUsageDetection.js +0 -125
  102. package/lib/gc/gcSweepReadyUsageDetection.js.map +0 -1
  103. package/src/gc/gcSweepReadyUsageDetection.ts +0 -145
@@ -1 +1 @@
1
- {"version":3,"file":"gcTelemetry.js","sourceRoot":"","sources":["../../src/gc/gcTelemetry.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryGenericEvent, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IGarbageCollectionData } from \"@fluidframework/runtime-definitions\";\nimport { packagePathToTelemetryProperty } from \"@fluidframework/runtime-utils\";\nimport {\n\tgenerateStack,\n\tMonitoringContext,\n\tTelemetryDataTag,\n} from \"@fluidframework/telemetry-utils\";\nimport { ICreateContainerMetadata } from \"../summary\";\nimport {\n\tdisableSweepLogKey,\n\tGCNodeType,\n\tUnreferencedState,\n\tIGarbageCollectorConfigs,\n\tdisableTombstoneKey,\n\tthrowOnTombstoneUsageKey,\n\tthrowOnTombstoneLoadKey,\n\trunSweepKey,\n} from \"./gcDefinitions\";\nimport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker\";\n\ntype NodeUsageType = \"Changed\" | \"Loaded\" | \"Revived\";\n\n/** Properties that are common to IUnreferencedEventProps and INodeUsageProps */\ninterface ICommonProps {\n\tusageType: NodeUsageType;\n\tcompletedGCRuns: number;\n\tisTombstoned: boolean;\n\tlastSummaryTime?: number;\n\tfromId?: string;\n\tviaHandle?: boolean;\n}\n\n/** The event that is logged when unreferenced node is used after a certain time. */\ninterface IUnreferencedEventProps extends ICreateContainerMetadata, ICommonProps {\n\tstate: UnreferencedState;\n\tid: string;\n\ttype: GCNodeType;\n\tunrefTime: number;\n\tage: number;\n\ttimeout?: number;\n}\n\n/** Properties passed to nodeUsed function when a node is used. */\ninterface INodeUsageProps extends ICommonProps {\n\tnodeId: string;\n\tcurrentReferenceTimestampMs: number | undefined;\n\tpackagePath: readonly string[] | undefined;\n}\n\n/**\n * Encapsulates the logic that tracks the various telemetry logged by the Garbage Collector. There are 4 types of\n * telemetry logged:\n * 1. inactiveObject telemetry - When an inactive node is used - A node that has been unreferenced for inactiveTimeoutMs.\n * 2. sweepReadyObject telemetry - When a sweep ready node is used - A node that has been unreferenced for sweepTimeoutMs.\n * 3. Tombstone telemetry - When a tombstoned node is used - A node that that has been marked as tombstone.\n * 4. Sweep / deleted telemetry - When a node is detected as sweep ready in the sweep phase.\n * 5. Unknown outbound reference telemetry - When a node is referenced but GC is not explicitly notified of it.\n */\nexport class GCTelemetryTracker {\n\t// Keeps track of unreferenced events that are logged for a node. This is used to limit the log generation to one\n\t// per event per node.\n\tprivate readonly loggedUnreferencedEvents: Set<string> = new Set();\n\t// Queue for unreferenced events that should be logged the next time GC runs.\n\tprivate pendingEventsQueue: IUnreferencedEventProps[] = [];\n\n\tconstructor(\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly configs: Pick<\n\t\t\tIGarbageCollectorConfigs,\n\t\t\t\"inactiveTimeoutMs\" | \"sweepTimeoutMs\"\n\t\t>,\n\t\tprivate readonly isSummarizerClient: boolean,\n\t\tprivate readonly gcTombstoneEnforcementAllowed: boolean,\n\t\tprivate readonly createContainerMetadata: ICreateContainerMetadata,\n\t\tprivate readonly getNodeType: (nodeId: string) => GCNodeType,\n\t\tprivate readonly getNodeStateTracker: (\n\t\t\tnodeId: string,\n\t\t) => UnreferencedStateTracker | undefined,\n\t\tprivate readonly getNodePackagePath: (\n\t\t\tnodePath: string,\n\t\t) => Promise<readonly string[] | undefined>,\n\t) {}\n\n\t/**\n\t * Returns whether an event should be logged for a node that isn't active anymore. Some scenarios where we won't log:\n\t * 1. When a DDS is changed or loaded. The corresponding data store's event will be logged instead.\n\t * 2. An event is logged only once per container instance per event per node.\n\t */\n\tprivate shouldLogNonActiveEvent(\n\t\tnodeId: string,\n\t\tnodeType: GCNodeType,\n\t\tusageType: NodeUsageType,\n\t\tnodeStateTracker: UnreferencedStateTracker,\n\t\tuniqueEventId: string,\n\t) {\n\t\tif (nodeStateTracker.state === UnreferencedState.Active) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// For sub data store (DDS) nodes, if they are changed or loaded, its data store will also be changed or loaded,\n\t\t// so skip logging to make the telemetry less noisy.\n\t\tif (nodeType === GCNodeType.SubDataStore && usageType !== \"Revived\") {\n\t\t\treturn false;\n\t\t}\n\t\tif (nodeType === GCNodeType.Other) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Called when a node is used. If the node is not active, log an event indicating object is used when its not active.\n\t */\n\tpublic nodeUsed(nodeUsageProps: INodeUsageProps) {\n\t\t// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip\n\t\t// logging as nothing interesting would have happened worth logging.\n\t\t// If the node is not unreferenced, skip logging.\n\t\tconst nodeStateTracker = this.getNodeStateTracker(nodeUsageProps.nodeId);\n\t\tif (!nodeStateTracker || nodeUsageProps.currentReferenceTimestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We log these events once per event per node. A unique id is generated by joining node state (inactive / sweep ready),\n\t\t// node's id and usage (loaded / changed / revived).\n\t\tconst uniqueEventId = `${nodeStateTracker.state}-${nodeUsageProps.nodeId}-${nodeUsageProps.usageType}`;\n\t\tconst nodeType = this.getNodeType(nodeUsageProps.nodeId);\n\t\tif (\n\t\t\t!this.shouldLogNonActiveEvent(\n\t\t\t\tnodeUsageProps.nodeId,\n\t\t\t\tnodeType,\n\t\t\t\tnodeUsageProps.usageType,\n\t\t\t\tnodeStateTracker,\n\t\t\t\tuniqueEventId,\n\t\t\t)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Add the unique event id so that we don't generate a log for this event again in this session..\n\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\n\t\tconst state = nodeStateTracker.state;\n\t\tconst { usageType, currentReferenceTimestampMs, packagePath, ...propsToLog } =\n\t\t\tnodeUsageProps;\n\t\tconst eventProps: Omit<IUnreferencedEventProps, \"state\" | \"usageType\"> = {\n\t\t\tid: nodeUsageProps.nodeId,\n\t\t\ttype: nodeType,\n\t\t\tunrefTime: nodeStateTracker.unreferencedTimestampMs,\n\t\t\tage:\n\t\t\t\tnodeUsageProps.currentReferenceTimestampMs -\n\t\t\t\tnodeStateTracker.unreferencedTimestampMs,\n\t\t\ttimeout:\n\t\t\t\tstate === UnreferencedState.Inactive\n\t\t\t\t\t? this.configs.inactiveTimeoutMs\n\t\t\t\t\t: this.configs.sweepTimeoutMs,\n\t\t\t...propsToLog,\n\t\t\t...this.createContainerMetadata,\n\t\t};\n\n\t\t// This will log the following events:\n\t\t// GC_Tombstone_DataStore_Revived, GC_Tombstone_SubDataStore_Revived, GC_Tombstone_Blob_Revived\n\t\tif (nodeUsageProps.usageType === \"Revived\" && nodeUsageProps.isTombstoned) {\n\t\t\tsendGCUnexpectedUsageEvent(\n\t\t\t\tthis.mc,\n\t\t\t\t{\n\t\t\t\t\teventName: `GC_Tombstone_${nodeType}_Revived`,\n\t\t\t\t\tcategory: \"generic\",\n\t\t\t\t\turl: nodeUsageProps.nodeId,\n\t\t\t\t\tgcTombstoneEnforcementAllowed: this.gcTombstoneEnforcementAllowed,\n\t\t\t\t},\n\t\t\t\tundefined /* packagePath */,\n\t\t\t);\n\t\t}\n\n\t\t// For summarizer client, queue the event so it is logged the next time GC runs if the event is still valid.\n\t\t// For non-summarizer client, log the event now since GC won't run on it. This may result in false positives\n\t\t// but it's a good signal nonetheless and we can consume it with a grain of salt.\n\t\t// Inactive errors are usages of Objects that are unreferenced for at least a period of 7 days.\n\t\t// SweepReady errors are usages of Objects that will be deleted by GC Sweep!\n\t\tif (this.isSummarizerClient) {\n\t\t\tthis.pendingEventsQueue.push({\n\t\t\t\t...eventProps,\n\t\t\t\tusageType: nodeUsageProps.usageType,\n\t\t\t\tstate,\n\t\t\t});\n\t\t} else {\n\t\t\t// For non-summarizer clients, only log \"Loaded\" type events since these objects may not be loaded in the\n\t\t\t// summarizer clients if they are based off of user actions (such as scrolling to content for these objects)\n\t\t\t// Events generated:\n\t\t\t// InactiveObject_Loaded, SweepReadyObject_Loaded\n\t\t\tif (nodeUsageProps.usageType === \"Loaded\") {\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${nodeUsageProps.usageType}`,\n\t\t\t\t\tpkg: packagePathToTelemetryProperty(nodeUsageProps.packagePath),\n\t\t\t\t\tstack: generateStack(),\n\t\t\t\t\t...eventProps,\n\t\t\t\t};\n\n\t\t\t\t// Do not log the inactive object x events as error events as they are not the best signal for\n\t\t\t\t// detecting something wrong with GC either from the partner or from the runtime itself.\n\t\t\t\tif (state === UnreferencedState.Inactive) {\n\t\t\t\t\tthis.mc.logger.sendTelemetryEvent(event);\n\t\t\t\t} else {\n\t\t\t\t\tthis.mc.logger.sendErrorEvent(event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log all new references or outbound routes in the current graph that haven't been explicitly notified to GC.\n\t * The principle is that every new reference or outbound route must be notified to GC via the\n\t * addedOutboundReference method. It it hasn't, its a bug and we want to identify these scenarios.\n\t *\n\t * In more simple terms:\n\t * Missing Explicit References = Current References - Previous References - Explicitly Added References;\n\t *\n\t * @param currentGCData - The GC data (reference graph) from the current GC run.\n\t * @param previousGCData - The GC data (reference graph) from the previous GC run.\n\t * @param explicitReferences - New references added explicity between the previous and the current run.\n\t */\n\tpublic logIfMissingExplicitReferences(\n\t\tcurrentGCData: IGarbageCollectionData,\n\t\tpreviousGCData: IGarbageCollectionData,\n\t\texplicitReferences: Map<string, string[]>,\n\t\tlogger: ITelemetryLogger,\n\t) {\n\t\tfor (const [nodeId, currentOutboundRoutes] of Object.entries(currentGCData.gcNodes)) {\n\t\t\tconst previousRoutes = previousGCData.gcNodes[nodeId] ?? [];\n\t\t\tconst explicitRoutes = explicitReferences.get(nodeId) ?? [];\n\n\t\t\t/**\n\t\t\t * 1. For routes in the current GC data, routes that were not present in previous GC data and did not have\n\t\t\t * explicit references should be added to missing explicit routes list.\n\t\t\t * 2. Only include data store and blob routes since GC only works for these two.\n\t\t\t * Note: Due to a bug with de-duped blobs, only adding data store routes for now.\n\t\t\t * 3. Ignore DDS routes to their parent datastores since those were added implicitly. So, there won't be\n\t\t\t * explicit routes to them.\n\t\t\t */\n\t\t\tconst missingExplicitRoutes: string[] = [];\n\t\t\tfor (const route of currentOutboundRoutes) {\n\t\t\t\tconst nodeType = this.getNodeType(route);\n\t\t\t\tif (\n\t\t\t\t\t(nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob) &&\n\t\t\t\t\t!nodeId.startsWith(route) &&\n\t\t\t\t\t!previousRoutes.includes(route) &&\n\t\t\t\t\t!explicitRoutes.includes(route)\n\t\t\t\t) {\n\t\t\t\t\tmissingExplicitRoutes.push(route);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (missingExplicitRoutes.length > 0) {\n\t\t\t\tlogger.sendErrorEvent({\n\t\t\t\t\teventName: \"gcUnknownOutboundReferences\",\n\t\t\t\t\tgcNodeId: nodeId,\n\t\t\t\t\tgcRoutes: JSON.stringify(missingExplicitRoutes),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log events that are pending in pendingEventsQueue. This is called after GC runs in the summarizer client\n\t * so that the state of an unreferenced node is updated.\n\t */\n\tpublic async logPendingEvents(logger: ITelemetryLogger) {\n\t\t// Events sent come only from the summarizer client. In between summaries, events are pushed to a queue and at\n\t\t// summary time they are then logged.\n\t\t// Events generated:\n\t\t// InactiveObject_Loaded, InactiveObject_Changed, InactiveObject_Revived\n\t\t// SweepReadyObject_Loaded, SweepReadyObject_Changed, SweepReadyObject_Revived\n\t\tfor (const eventProps of this.pendingEventsQueue) {\n\t\t\tconst { usageType, state, ...propsToLog } = eventProps;\n\t\t\t/**\n\t\t\t * Revived event is logged only if the node is active. If the node is not active, the reference to it was\n\t\t\t * from another unreferenced node and this scenario is not interesting to log.\n\t\t\t * Loaded and Changed events are logged only if the node is not active. If the node is active, it was\n\t\t\t * revived and a Revived event will be logged for it.\n\t\t\t */\n\t\t\tconst nodeStateTracker = this.getNodeStateTracker(eventProps.id);\n\t\t\tconst active =\n\t\t\t\tnodeStateTracker === undefined ||\n\t\t\t\tnodeStateTracker.state === UnreferencedState.Active;\n\t\t\tif ((usageType === \"Revived\") === active) {\n\t\t\t\tconst pkg = await this.getNodePackagePath(eventProps.id);\n\t\t\t\tconst fromPkg = eventProps.fromId\n\t\t\t\t\t? await this.getNodePackagePath(eventProps.fromId)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst event = {\n\t\t\t\t\t...propsToLog,\n\t\t\t\t\teventName: `${state}Object_${usageType}`,\n\t\t\t\t\tpkg: pkg\n\t\t\t\t\t\t? { value: pkg.join(\"/\"), tag: TelemetryDataTag.CodeArtifact }\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tfromPkg: fromPkg\n\t\t\t\t\t\t? { value: fromPkg.join(\"/\"), tag: TelemetryDataTag.CodeArtifact }\n\t\t\t\t\t\t: undefined,\n\t\t\t\t};\n\n\t\t\t\tif (state === UnreferencedState.Inactive) {\n\t\t\t\t\tlogger.sendTelemetryEvent(event);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.sendErrorEvent(event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.pendingEventsQueue = [];\n\t}\n\n\t/**\n\t * For nodes that are ready to sweep, log an event for now. Until we start running sweep which deletes objects,\n\t * this will give us a view into how much deleted content a container has.\n\t */\n\tpublic logSweepEvents(\n\t\tlogger: ITelemetryLogger,\n\t\tcurrentReferenceTimestampMs: number,\n\t\tunreferencedNodesState: Map<string, UnreferencedStateTracker>,\n\t\tcompletedGCRuns: number,\n\t\tlastSummaryTime?: number,\n\t) {\n\t\tif (\n\t\t\tthis.mc.config.getBoolean(disableSweepLogKey) === true ||\n\t\t\tthis.configs.sweepTimeoutMs === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const [nodeId, nodeStateTracker] of unreferencedNodesState) {\n\t\t\tif (nodeStateTracker.state !== UnreferencedState.SweepReady) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst nodeType = this.getNodeType(nodeId);\n\t\t\tif (nodeType !== GCNodeType.DataStore && nodeType !== GCNodeType.Blob) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Log deleted event for each node only once to reduce noise in telemetry.\n\t\t\tconst uniqueEventId = `Deleted-${nodeId}`;\n\t\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\t\t\tlogger.sendTelemetryEvent({\n\t\t\t\teventName: \"GCObjectDeleted\",\n\t\t\t\tid: nodeId,\n\t\t\t\ttype: nodeType,\n\t\t\t\tage: currentReferenceTimestampMs - nodeStateTracker.unreferencedTimestampMs,\n\t\t\t\ttimeout: this.configs.sweepTimeoutMs,\n\t\t\t\tcompletedGCRuns,\n\t\t\t\tlastSummaryTime,\n\t\t\t\t...this.createContainerMetadata,\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEvent & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = packagePathToTelemetryProperty(packagePath);\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n"]}
1
+ {"version":3,"file":"gcTelemetry.js","sourceRoot":"","sources":["../../src/gc/gcTelemetry.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryGenericEvent, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IGarbageCollectionData } from \"@fluidframework/runtime-definitions\";\nimport { packagePathToTelemetryProperty } from \"@fluidframework/runtime-utils\";\nimport { generateStack, MonitoringContext } from \"@fluidframework/telemetry-utils\";\nimport { ICreateContainerMetadata } from \"../summary\";\nimport {\n\tdisableSweepLogKey,\n\tGCNodeType,\n\tUnreferencedState,\n\tIGarbageCollectorConfigs,\n\tdisableTombstoneKey,\n\tthrowOnTombstoneUsageKey,\n\tthrowOnTombstoneLoadKey,\n\trunSweepKey,\n} from \"./gcDefinitions\";\nimport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker\";\nimport { tagAsCodeArtifact } from \"./gcHelpers\";\n\ntype NodeUsageType = \"Changed\" | \"Loaded\" | \"Revived\";\n\n/** Properties that are common to IUnreferencedEventProps and INodeUsageProps */\ninterface ICommonProps {\n\tusageType: NodeUsageType;\n\tcompletedGCRuns: number;\n\tisTombstoned: boolean;\n\tlastSummaryTime?: number;\n\tviaHandle?: boolean;\n}\n\n/** The event that is logged when unreferenced node is used after a certain time. */\ninterface IUnreferencedEventProps extends ICreateContainerMetadata, ICommonProps {\n\tstate: UnreferencedState;\n\tid: {\n\t\tvalue: string;\n\t\ttag: string;\n\t};\n\ttype: GCNodeType;\n\tunrefTime: number;\n\tage: number;\n\ttimeout?: number;\n\tfromId?: {\n\t\tvalue: string;\n\t\ttag: string;\n\t};\n}\n\n/** Properties passed to nodeUsed function when a node is used. */\ninterface INodeUsageProps extends ICommonProps {\n\tid: string;\n\tcurrentReferenceTimestampMs: number | undefined;\n\tpackagePath: readonly string[] | undefined;\n\tfromId?: string;\n}\n\n/**\n * Encapsulates the logic that tracks the various telemetry logged by the Garbage Collector. There are 4 types of\n * telemetry logged:\n * 1. inactiveObject telemetry - When an inactive node is used - A node that has been unreferenced for inactiveTimeoutMs.\n * 2. sweepReadyObject telemetry - When a sweep ready node is used - A node that has been unreferenced for sweepTimeoutMs.\n * 3. Tombstone telemetry - When a tombstoned node is used - A node that that has been marked as tombstone.\n * 4. Sweep / deleted telemetry - When a node is detected as sweep ready in the sweep phase.\n * 5. Unknown outbound reference telemetry - When a node is referenced but GC is not explicitly notified of it.\n */\nexport class GCTelemetryTracker {\n\t// Keeps track of unreferenced events that are logged for a node. This is used to limit the log generation to one\n\t// per event per node.\n\tprivate readonly loggedUnreferencedEvents: Set<string> = new Set();\n\t// Queue for unreferenced events that should be logged the next time GC runs.\n\tprivate pendingEventsQueue: IUnreferencedEventProps[] = [];\n\n\tconstructor(\n\t\tprivate readonly mc: MonitoringContext,\n\t\tprivate readonly configs: Pick<\n\t\t\tIGarbageCollectorConfigs,\n\t\t\t\"inactiveTimeoutMs\" | \"sweepTimeoutMs\"\n\t\t>,\n\t\tprivate readonly isSummarizerClient: boolean,\n\t\tprivate readonly gcTombstoneEnforcementAllowed: boolean,\n\t\tprivate readonly createContainerMetadata: ICreateContainerMetadata,\n\t\tprivate readonly getNodeType: (nodeId: string) => GCNodeType,\n\t\tprivate readonly getNodeStateTracker: (\n\t\t\tnodeId: string,\n\t\t) => UnreferencedStateTracker | undefined,\n\t\tprivate readonly getNodePackagePath: (\n\t\t\tnodePath: string,\n\t\t) => Promise<readonly string[] | undefined>,\n\t) {}\n\n\t/**\n\t * Returns whether an event should be logged for a node that isn't active anymore. Some scenarios where we won't log:\n\t * 1. When a DDS is changed or loaded. The corresponding data store's event will be logged instead.\n\t * 2. An event is logged only once per container instance per event per node.\n\t */\n\tprivate shouldLogNonActiveEvent(\n\t\tnodeId: string,\n\t\tnodeType: GCNodeType,\n\t\tusageType: NodeUsageType,\n\t\tnodeStateTracker: UnreferencedStateTracker,\n\t\tuniqueEventId: string,\n\t) {\n\t\tif (nodeStateTracker.state === UnreferencedState.Active) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// For sub data store (DDS) nodes, if they are changed or loaded, its data store will also be changed or loaded,\n\t\t// so skip logging to make the telemetry less noisy.\n\t\tif (nodeType === GCNodeType.SubDataStore && usageType !== \"Revived\") {\n\t\t\treturn false;\n\t\t}\n\t\tif (nodeType === GCNodeType.Other) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Called when a node is used. If the node is not active, log an event indicating object is used when its not active.\n\t */\n\tpublic nodeUsed(nodeUsageProps: INodeUsageProps) {\n\t\t// If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip\n\t\t// logging as nothing interesting would have happened worth logging.\n\t\t// If the node is not unreferenced, skip logging.\n\t\tconst nodeStateTracker = this.getNodeStateTracker(nodeUsageProps.id);\n\t\tif (!nodeStateTracker || nodeUsageProps.currentReferenceTimestampMs === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We log these events once per event per node. A unique id is generated by joining node state (inactive / sweep ready),\n\t\t// node's id and usage (loaded / changed / revived).\n\t\tconst uniqueEventId = `${nodeStateTracker.state}-${nodeUsageProps.id}-${nodeUsageProps.usageType}`;\n\t\tconst nodeType = this.getNodeType(nodeUsageProps.id);\n\t\tif (\n\t\t\t!this.shouldLogNonActiveEvent(\n\t\t\t\tnodeUsageProps.id,\n\t\t\t\tnodeType,\n\t\t\t\tnodeUsageProps.usageType,\n\t\t\t\tnodeStateTracker,\n\t\t\t\tuniqueEventId,\n\t\t\t)\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Add the unique event id so that we don't generate a log for this event again in this session..\n\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\n\t\tconst state = nodeStateTracker.state;\n\t\tconst { usageType, currentReferenceTimestampMs, packagePath, id, fromId, ...propsToLog } =\n\t\t\tnodeUsageProps;\n\t\tconst eventProps: Omit<IUnreferencedEventProps, \"state\" | \"usageType\"> = {\n\t\t\tid: tagAsCodeArtifact(id),\n\t\t\ttype: nodeType,\n\t\t\tunrefTime: nodeStateTracker.unreferencedTimestampMs,\n\t\t\tage:\n\t\t\t\tnodeUsageProps.currentReferenceTimestampMs -\n\t\t\t\tnodeStateTracker.unreferencedTimestampMs,\n\t\t\ttimeout:\n\t\t\t\tstate === UnreferencedState.Inactive\n\t\t\t\t\t? this.configs.inactiveTimeoutMs\n\t\t\t\t\t: this.configs.sweepTimeoutMs,\n\t\t\tfromId: fromId ? tagAsCodeArtifact(fromId) : undefined,\n\t\t\t...propsToLog,\n\t\t\t...this.createContainerMetadata,\n\t\t};\n\n\t\t// This will log the following events:\n\t\t// GC_Tombstone_DataStore_Revived, GC_Tombstone_SubDataStore_Revived, GC_Tombstone_Blob_Revived\n\t\tif (nodeUsageProps.usageType === \"Revived\" && nodeUsageProps.isTombstoned) {\n\t\t\tsendGCUnexpectedUsageEvent(\n\t\t\t\tthis.mc,\n\t\t\t\t{\n\t\t\t\t\teventName: `GC_Tombstone_${nodeType}_Revived`,\n\t\t\t\t\tcategory: \"generic\",\n\t\t\t\t\turl: tagAsCodeArtifact(id),\n\t\t\t\t\tgcTombstoneEnforcementAllowed: this.gcTombstoneEnforcementAllowed,\n\t\t\t\t},\n\t\t\t\tundefined /* packagePath */,\n\t\t\t);\n\t\t}\n\n\t\t// For summarizer client, queue the event so it is logged the next time GC runs if the event is still valid.\n\t\t// For non-summarizer client, log the event now since GC won't run on it. This may result in false positives\n\t\t// but it's a good signal nonetheless and we can consume it with a grain of salt.\n\t\t// Inactive errors are usages of Objects that are unreferenced for at least a period of 7 days.\n\t\t// SweepReady errors are usages of Objects that will be deleted by GC Sweep!\n\t\tif (this.isSummarizerClient) {\n\t\t\tthis.pendingEventsQueue.push({\n\t\t\t\t...eventProps,\n\t\t\t\tusageType: nodeUsageProps.usageType,\n\t\t\t\tstate,\n\t\t\t});\n\t\t} else {\n\t\t\t// For non-summarizer clients, only log \"Loaded\" type events since these objects may not be loaded in the\n\t\t\t// summarizer clients if they are based off of user actions (such as scrolling to content for these objects)\n\t\t\t// Events generated:\n\t\t\t// InactiveObject_Loaded, SweepReadyObject_Loaded\n\t\t\tif (nodeUsageProps.usageType === \"Loaded\") {\n\t\t\t\tconst { id: taggedId, fromId: taggedFromId, ...otherProps } = eventProps;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${nodeUsageProps.usageType}`,\n\t\t\t\t\tpkg: packagePathToTelemetryProperty(nodeUsageProps.packagePath),\n\t\t\t\t\tstack: generateStack(),\n\t\t\t\t\tid: taggedId,\n\t\t\t\t\tfromId: taggedFromId,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t...otherProps,\n\t\t\t\t\t}),\n\t\t\t\t};\n\n\t\t\t\t// Do not log the inactive object x events as error events as they are not the best signal for\n\t\t\t\t// detecting something wrong with GC either from the partner or from the runtime itself.\n\t\t\t\tif (state === UnreferencedState.Inactive) {\n\t\t\t\t\tthis.mc.logger.sendTelemetryEvent(event);\n\t\t\t\t} else {\n\t\t\t\t\tthis.mc.logger.sendErrorEvent(event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log all new references or outbound routes in the current graph that haven't been explicitly notified to GC.\n\t * The principle is that every new reference or outbound route must be notified to GC via the\n\t * addedOutboundReference method. It it hasn't, its a bug and we want to identify these scenarios.\n\t *\n\t * In more simple terms:\n\t * Missing Explicit References = Current References - Previous References - Explicitly Added References;\n\t *\n\t * @param currentGCData - The GC data (reference graph) from the current GC run.\n\t * @param previousGCData - The GC data (reference graph) from the previous GC run.\n\t * @param explicitReferences - New references added explicity between the previous and the current run.\n\t */\n\tpublic logIfMissingExplicitReferences(\n\t\tcurrentGCData: IGarbageCollectionData,\n\t\tpreviousGCData: IGarbageCollectionData,\n\t\texplicitReferences: Map<string, string[]>,\n\t\tlogger: ITelemetryLogger,\n\t) {\n\t\tfor (const [nodeId, currentOutboundRoutes] of Object.entries(currentGCData.gcNodes)) {\n\t\t\tconst previousRoutes = previousGCData.gcNodes[nodeId] ?? [];\n\t\t\tconst explicitRoutes = explicitReferences.get(nodeId) ?? [];\n\n\t\t\t/**\n\t\t\t * 1. For routes in the current GC data, routes that were not present in previous GC data and did not have\n\t\t\t * explicit references should be added to missing explicit routes list.\n\t\t\t * 2. Only include data store and blob routes since GC only works for these two.\n\t\t\t * Note: Due to a bug with de-duped blobs, only adding data store routes for now.\n\t\t\t * 3. Ignore DDS routes to their parent datastores since those were added implicitly. So, there won't be\n\t\t\t * explicit routes to them.\n\t\t\t */\n\t\t\tconst missingExplicitRoutes: string[] = [];\n\t\t\tfor (const route of currentOutboundRoutes) {\n\t\t\t\tconst nodeType = this.getNodeType(route);\n\t\t\t\tif (\n\t\t\t\t\t(nodeType === GCNodeType.DataStore || nodeType === GCNodeType.Blob) &&\n\t\t\t\t\t!nodeId.startsWith(route) &&\n\t\t\t\t\t!previousRoutes.includes(route) &&\n\t\t\t\t\t!explicitRoutes.includes(route)\n\t\t\t\t) {\n\t\t\t\t\tmissingExplicitRoutes.push(route);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (missingExplicitRoutes.length > 0) {\n\t\t\t\tlogger.sendErrorEvent({\n\t\t\t\t\teventName: \"gcUnknownOutboundReferences\",\n\t\t\t\t\tid: tagAsCodeArtifact(nodeId),\n\t\t\t\t\troutes: tagAsCodeArtifact(JSON.stringify(missingExplicitRoutes)),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Log events that are pending in pendingEventsQueue. This is called after GC runs in the summarizer client\n\t * so that the state of an unreferenced node is updated.\n\t */\n\tpublic async logPendingEvents(logger: ITelemetryLogger) {\n\t\t// Events sent come only from the summarizer client. In between summaries, events are pushed to a queue and at\n\t\t// summary time they are then logged.\n\t\t// Events generated:\n\t\t// InactiveObject_Loaded, InactiveObject_Changed, InactiveObject_Revived\n\t\t// SweepReadyObject_Loaded, SweepReadyObject_Changed, SweepReadyObject_Revived\n\t\tfor (const eventProps of this.pendingEventsQueue) {\n\t\t\tconst { usageType, state, id, fromId, ...propsToLog } = eventProps;\n\t\t\t/**\n\t\t\t * Revived event is logged only if the node is active. If the node is not active, the reference to it was\n\t\t\t * from another unreferenced node and this scenario is not interesting to log.\n\t\t\t * Loaded and Changed events are logged only if the node is not active. If the node is active, it was\n\t\t\t * revived and a Revived event will be logged for it.\n\t\t\t */\n\t\t\tconst nodeStateTracker = this.getNodeStateTracker(eventProps.id.value);\n\t\t\tconst active =\n\t\t\t\tnodeStateTracker === undefined ||\n\t\t\t\tnodeStateTracker.state === UnreferencedState.Active;\n\t\t\tif ((usageType === \"Revived\") === active) {\n\t\t\t\tconst pkg = await this.getNodePackagePath(eventProps.id.value);\n\t\t\t\tconst fromPkg = eventProps.fromId\n\t\t\t\t\t? await this.getNodePackagePath(eventProps.fromId.value)\n\t\t\t\t\t: undefined;\n\t\t\t\tconst event = {\n\t\t\t\t\teventName: `${state}Object_${usageType}`,\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\t...propsToLog,\n\t\t\t\t\t}),\n\t\t\t\t\tid,\n\t\t\t\t\tfromId,\n\t\t\t\t\tpkg: pkg ? tagAsCodeArtifact(pkg.join(\"/\")) : undefined,\n\t\t\t\t\tfromPkg: fromPkg ? tagAsCodeArtifact(fromPkg.join(\"/\")) : undefined,\n\t\t\t\t};\n\n\t\t\t\tif (state === UnreferencedState.Inactive) {\n\t\t\t\t\tlogger.sendTelemetryEvent(event);\n\t\t\t\t} else {\n\t\t\t\t\tlogger.sendErrorEvent(event);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.pendingEventsQueue = [];\n\t}\n\n\t/**\n\t * For nodes that are ready to sweep, log an event for now. Until we start running sweep which deletes objects,\n\t * this will give us a view into how much deleted content a container has.\n\t */\n\tpublic logSweepEvents(\n\t\tlogger: ITelemetryLogger,\n\t\tcurrentReferenceTimestampMs: number,\n\t\tunreferencedNodesState: Map<string, UnreferencedStateTracker>,\n\t\tcompletedGCRuns: number,\n\t\tlastSummaryTime?: number,\n\t) {\n\t\tif (\n\t\t\tthis.mc.config.getBoolean(disableSweepLogKey) === true ||\n\t\t\tthis.configs.sweepTimeoutMs === undefined\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst deletedNodeIds: string[] = [];\n\t\tfor (const [nodeId, nodeStateTracker] of unreferencedNodesState) {\n\t\t\tif (nodeStateTracker.state !== UnreferencedState.SweepReady) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst nodeType = this.getNodeType(nodeId);\n\t\t\tif (nodeType !== GCNodeType.DataStore && nodeType !== GCNodeType.Blob) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Log deleted event for each node only once to reduce noise in telemetry.\n\t\t\tconst uniqueEventId = `Deleted-${nodeId}`;\n\t\t\tif (this.loggedUnreferencedEvents.has(uniqueEventId)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.loggedUnreferencedEvents.add(uniqueEventId);\n\t\t\tdeletedNodeIds.push(nodeId);\n\t\t}\n\n\t\tif (deletedNodeIds.length > 0) {\n\t\t\tlogger.sendTelemetryEvent({\n\t\t\t\teventName: \"GC_SweepReadyObjects_Delete\",\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\ttimeout: this.configs.sweepTimeoutMs,\n\t\t\t\t\tcompletedGCRuns,\n\t\t\t\t\tlastSummaryTime,\n\t\t\t\t\t...this.createContainerMetadata,\n\t\t\t\t}),\n\t\t\t\tid: tagAsCodeArtifact(JSON.stringify(deletedNodeIds)),\n\t\t\t});\n\t\t}\n\t}\n}\n\n/**\n * Consolidates info / logic for logging when we encounter unexpected usage of GC'd objects. For example, when a\n * tombstoned or deleted object is loaded.\n */\nexport function sendGCUnexpectedUsageEvent(\n\tmc: MonitoringContext,\n\tevent: ITelemetryGenericEvent & {\n\t\tcategory: \"error\" | \"generic\";\n\t\tgcTombstoneEnforcementAllowed: boolean | undefined;\n\t},\n\tpackagePath: readonly string[] | undefined,\n\terror?: unknown,\n) {\n\tevent.pkg = packagePathToTelemetryProperty(packagePath);\n\tevent.tombstoneFlags = JSON.stringify({\n\t\tDisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n\t\tThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n\t\tThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),\n\t});\n\tevent.sweepFlags = JSON.stringify({\n\t\tEnableSweepFlag: mc.config.getBoolean(runSweepKey),\n\t});\n\n\tmc.logger.sendTelemetryEvent(event, error);\n}\n"]}
@@ -4,11 +4,10 @@
4
4
  */
5
5
  export { GarbageCollector } from "./garbageCollection";
6
6
  export { currentGCVersion, defaultInactiveTimeoutMs, defaultSessionExpiryDurationMs, disableSweepLogKey, GCNodeType, gcTestModeKey, gcTombstoneGenerationOptionName, gcSweepGenerationOptionName, GCFeatureMatrix, GCVersion, gcVersionUpgradeToV3Key, IGarbageCollectionRuntime, IGarbageCollector, IGarbageCollectorConfigs, IGarbageCollectorCreateParams, IGCMetadata, IGCResult, IGCRuntimeOptions, IGCStats, oneDayMs, runGCKey, runSessionExpiryKey, runSweepKey, stableGCVersion, sweepAttachmentBlobsKey, sweepDatastoresKey, throwOnTombstoneLoadKey, throwOnTombstoneUsageKey, UnreferencedState, } from "./gcDefinitions";
7
- export { cloneGCData, concatGarbageCollectionStates, getGCDataFromSnapshot, shouldAllowGcTombstoneEnforcement, shouldAllowGcSweep, trimLeadingAndTrailingSlashes, unpackChildNodesGCDetails, } from "./gcHelpers";
7
+ export { cloneGCData, concatGarbageCollectionStates, getGCDataFromSnapshot, shouldAllowGcTombstoneEnforcement, shouldAllowGcSweep, trimLeadingAndTrailingSlashes, unpackChildNodesGCDetails, tagAsCodeArtifact, } from "./gcHelpers";
8
8
  export { runGarbageCollection } from "./gcReferenceGraphAlgorithm";
9
9
  export { IGarbageCollectionNodeData, IGarbageCollectionSnapshotData, IGarbageCollectionState, IGarbageCollectionSummaryDetailsLegacy, } from "./gcSummaryDefinitions";
10
10
  export { gcStateBlobKey, GCSummaryStateTracker, IGCSummaryTrackingData, } from "./gcSummaryStateTracker";
11
- export { skipClosureForXDaysKey, closuresMapLocalStorageKey, SweepReadyUsageDetectionHandler, } from "./gcSweepReadyUsageDetection";
12
11
  export { GCTelemetryTracker, sendGCUnexpectedUsageEvent } from "./gcTelemetry";
13
12
  export { UnreferencedStateTracker } from "./gcUnreferencedStateTracker";
14
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,8BAA8B,EAC9B,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,+BAA+B,EAC/B,2BAA2B,EAC3B,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,WAAW,EACX,6BAA6B,EAC7B,qBAAqB,EACrB,iCAAiC,EACjC,kBAAkB,EAClB,6BAA6B,EAC7B,yBAAyB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EACN,0BAA0B,EAC1B,8BAA8B,EAC9B,uBAAuB,EACvB,sCAAsC,GACtC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,cAAc,EACd,qBAAqB,EACrB,sBAAsB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACN,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,GAC/B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EACN,gBAAgB,EAChB,wBAAwB,EACxB,8BAA8B,EAC9B,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,+BAA+B,EAC/B,2BAA2B,EAC3B,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,wBAAwB,EACxB,6BAA6B,EAC7B,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,WAAW,EACX,6BAA6B,EAC7B,qBAAqB,EACrB,iCAAiC,EACjC,kBAAkB,EAClB,6BAA6B,EAC7B,yBAAyB,EACzB,iBAAiB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EACN,0BAA0B,EAC1B,8BAA8B,EAC9B,uBAAuB,EACvB,sCAAsC,GACtC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,cAAc,EACd,qBAAqB,EACrB,sBAAsB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC"}
package/dist/gc/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.UnreferencedStateTracker = exports.sendGCUnexpectedUsageEvent = exports.GCTelemetryTracker = exports.SweepReadyUsageDetectionHandler = exports.closuresMapLocalStorageKey = exports.skipClosureForXDaysKey = exports.GCSummaryStateTracker = exports.gcStateBlobKey = exports.runGarbageCollection = exports.unpackChildNodesGCDetails = exports.trimLeadingAndTrailingSlashes = exports.shouldAllowGcSweep = exports.shouldAllowGcTombstoneEnforcement = exports.getGCDataFromSnapshot = exports.concatGarbageCollectionStates = exports.cloneGCData = exports.UnreferencedState = exports.throwOnTombstoneUsageKey = exports.throwOnTombstoneLoadKey = exports.sweepDatastoresKey = exports.sweepAttachmentBlobsKey = exports.stableGCVersion = exports.runSweepKey = exports.runSessionExpiryKey = exports.runGCKey = exports.oneDayMs = exports.gcVersionUpgradeToV3Key = exports.gcSweepGenerationOptionName = exports.gcTombstoneGenerationOptionName = exports.gcTestModeKey = exports.GCNodeType = exports.disableSweepLogKey = exports.defaultSessionExpiryDurationMs = exports.defaultInactiveTimeoutMs = exports.currentGCVersion = exports.GarbageCollector = void 0;
7
+ exports.UnreferencedStateTracker = exports.sendGCUnexpectedUsageEvent = exports.GCTelemetryTracker = exports.GCSummaryStateTracker = exports.gcStateBlobKey = exports.runGarbageCollection = exports.tagAsCodeArtifact = exports.unpackChildNodesGCDetails = exports.trimLeadingAndTrailingSlashes = exports.shouldAllowGcSweep = exports.shouldAllowGcTombstoneEnforcement = exports.getGCDataFromSnapshot = exports.concatGarbageCollectionStates = exports.cloneGCData = exports.UnreferencedState = exports.throwOnTombstoneUsageKey = exports.throwOnTombstoneLoadKey = exports.sweepDatastoresKey = exports.sweepAttachmentBlobsKey = exports.stableGCVersion = exports.runSweepKey = exports.runSessionExpiryKey = exports.runGCKey = exports.oneDayMs = exports.gcVersionUpgradeToV3Key = exports.gcSweepGenerationOptionName = exports.gcTombstoneGenerationOptionName = exports.gcTestModeKey = exports.GCNodeType = exports.disableSweepLogKey = exports.defaultSessionExpiryDurationMs = exports.defaultInactiveTimeoutMs = exports.currentGCVersion = exports.GarbageCollector = void 0;
8
8
  var garbageCollection_1 = require("./garbageCollection");
9
9
  Object.defineProperty(exports, "GarbageCollector", { enumerable: true, get: function () { return garbageCollection_1.GarbageCollector; } });
10
10
  var gcDefinitions_1 = require("./gcDefinitions");
@@ -35,15 +35,12 @@ Object.defineProperty(exports, "shouldAllowGcTombstoneEnforcement", { enumerable
35
35
  Object.defineProperty(exports, "shouldAllowGcSweep", { enumerable: true, get: function () { return gcHelpers_1.shouldAllowGcSweep; } });
36
36
  Object.defineProperty(exports, "trimLeadingAndTrailingSlashes", { enumerable: true, get: function () { return gcHelpers_1.trimLeadingAndTrailingSlashes; } });
37
37
  Object.defineProperty(exports, "unpackChildNodesGCDetails", { enumerable: true, get: function () { return gcHelpers_1.unpackChildNodesGCDetails; } });
38
+ Object.defineProperty(exports, "tagAsCodeArtifact", { enumerable: true, get: function () { return gcHelpers_1.tagAsCodeArtifact; } });
38
39
  var gcReferenceGraphAlgorithm_1 = require("./gcReferenceGraphAlgorithm");
39
40
  Object.defineProperty(exports, "runGarbageCollection", { enumerable: true, get: function () { return gcReferenceGraphAlgorithm_1.runGarbageCollection; } });
40
41
  var gcSummaryStateTracker_1 = require("./gcSummaryStateTracker");
41
42
  Object.defineProperty(exports, "gcStateBlobKey", { enumerable: true, get: function () { return gcSummaryStateTracker_1.gcStateBlobKey; } });
42
43
  Object.defineProperty(exports, "GCSummaryStateTracker", { enumerable: true, get: function () { return gcSummaryStateTracker_1.GCSummaryStateTracker; } });
43
- var gcSweepReadyUsageDetection_1 = require("./gcSweepReadyUsageDetection");
44
- Object.defineProperty(exports, "skipClosureForXDaysKey", { enumerable: true, get: function () { return gcSweepReadyUsageDetection_1.skipClosureForXDaysKey; } });
45
- Object.defineProperty(exports, "closuresMapLocalStorageKey", { enumerable: true, get: function () { return gcSweepReadyUsageDetection_1.closuresMapLocalStorageKey; } });
46
- Object.defineProperty(exports, "SweepReadyUsageDetectionHandler", { enumerable: true, get: function () { return gcSweepReadyUsageDetection_1.SweepReadyUsageDetectionHandler; } });
47
44
  var gcTelemetry_1 = require("./gcTelemetry");
48
45
  Object.defineProperty(exports, "GCTelemetryTracker", { enumerable: true, get: function () { return gcTelemetry_1.GCTelemetryTracker; } });
49
46
  Object.defineProperty(exports, "sendGCUnexpectedUsageEvent", { enumerable: true, get: function () { return gcTelemetry_1.sendGCUnexpectedUsageEvent; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AACzB,iDA8ByB;AA7BxB,iHAAA,gBAAgB,OAAA;AAChB,yHAAA,wBAAwB,OAAA;AACxB,+HAAA,8BAA8B,OAAA;AAC9B,mHAAA,kBAAkB,OAAA;AAClB,2GAAA,UAAU,OAAA;AACV,8GAAA,aAAa,OAAA;AACb,gIAAA,+BAA+B,OAAA;AAC/B,4HAAA,2BAA2B,OAAA;AAG3B,wHAAA,uBAAuB,OAAA;AASvB,yGAAA,QAAQ,OAAA;AACR,yGAAA,QAAQ,OAAA;AACR,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,gHAAA,eAAe,OAAA;AACf,wHAAA,uBAAuB,OAAA;AACvB,mHAAA,kBAAkB,OAAA;AAClB,wHAAA,uBAAuB,OAAA;AACvB,yHAAA,wBAAwB,OAAA;AACxB,kHAAA,iBAAiB,OAAA;AAElB,yCAQqB;AAPpB,wGAAA,WAAW,OAAA;AACX,0HAAA,6BAA6B,OAAA;AAC7B,kHAAA,qBAAqB,OAAA;AACrB,8HAAA,iCAAiC,OAAA;AACjC,+GAAA,kBAAkB,OAAA;AAClB,0HAAA,6BAA6B,OAAA;AAC7B,sHAAA,yBAAyB,OAAA;AAE1B,yEAAmE;AAA1D,iIAAA,oBAAoB,OAAA;AAO7B,iEAIiC;AAHhC,uHAAA,cAAc,OAAA;AACd,8HAAA,qBAAqB,OAAA;AAGtB,2EAIsC;AAHrC,oIAAA,sBAAsB,OAAA;AACtB,wIAAA,0BAA0B,OAAA;AAC1B,6IAAA,+BAA+B,OAAA;AAEhC,6CAA+E;AAAtE,iHAAA,kBAAkB,OAAA;AAAE,yHAAA,0BAA0B,OAAA;AACvD,2EAAwE;AAA/D,sIAAA,wBAAwB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { GarbageCollector } from \"./garbageCollection\";\nexport {\n\tcurrentGCVersion,\n\tdefaultInactiveTimeoutMs,\n\tdefaultSessionExpiryDurationMs,\n\tdisableSweepLogKey,\n\tGCNodeType,\n\tgcTestModeKey,\n\tgcTombstoneGenerationOptionName,\n\tgcSweepGenerationOptionName,\n\tGCFeatureMatrix,\n\tGCVersion,\n\tgcVersionUpgradeToV3Key,\n\tIGarbageCollectionRuntime,\n\tIGarbageCollector,\n\tIGarbageCollectorConfigs,\n\tIGarbageCollectorCreateParams,\n\tIGCMetadata,\n\tIGCResult,\n\tIGCRuntimeOptions,\n\tIGCStats,\n\toneDayMs,\n\trunGCKey,\n\trunSessionExpiryKey,\n\trunSweepKey,\n\tstableGCVersion,\n\tsweepAttachmentBlobsKey,\n\tsweepDatastoresKey,\n\tthrowOnTombstoneLoadKey,\n\tthrowOnTombstoneUsageKey,\n\tUnreferencedState,\n} from \"./gcDefinitions\";\nexport {\n\tcloneGCData,\n\tconcatGarbageCollectionStates,\n\tgetGCDataFromSnapshot,\n\tshouldAllowGcTombstoneEnforcement,\n\tshouldAllowGcSweep,\n\ttrimLeadingAndTrailingSlashes,\n\tunpackChildNodesGCDetails,\n} from \"./gcHelpers\";\nexport { runGarbageCollection } from \"./gcReferenceGraphAlgorithm\";\nexport {\n\tIGarbageCollectionNodeData,\n\tIGarbageCollectionSnapshotData,\n\tIGarbageCollectionState,\n\tIGarbageCollectionSummaryDetailsLegacy,\n} from \"./gcSummaryDefinitions\";\nexport {\n\tgcStateBlobKey,\n\tGCSummaryStateTracker,\n\tIGCSummaryTrackingData,\n} from \"./gcSummaryStateTracker\";\nexport {\n\tskipClosureForXDaysKey,\n\tclosuresMapLocalStorageKey,\n\tSweepReadyUsageDetectionHandler,\n} from \"./gcSweepReadyUsageDetection\";\nexport { GCTelemetryTracker, sendGCUnexpectedUsageEvent } from \"./gcTelemetry\";\nexport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gc/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AACzB,iDA8ByB;AA7BxB,iHAAA,gBAAgB,OAAA;AAChB,yHAAA,wBAAwB,OAAA;AACxB,+HAAA,8BAA8B,OAAA;AAC9B,mHAAA,kBAAkB,OAAA;AAClB,2GAAA,UAAU,OAAA;AACV,8GAAA,aAAa,OAAA;AACb,gIAAA,+BAA+B,OAAA;AAC/B,4HAAA,2BAA2B,OAAA;AAG3B,wHAAA,uBAAuB,OAAA;AASvB,yGAAA,QAAQ,OAAA;AACR,yGAAA,QAAQ,OAAA;AACR,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,gHAAA,eAAe,OAAA;AACf,wHAAA,uBAAuB,OAAA;AACvB,mHAAA,kBAAkB,OAAA;AAClB,wHAAA,uBAAuB,OAAA;AACvB,yHAAA,wBAAwB,OAAA;AACxB,kHAAA,iBAAiB,OAAA;AAElB,yCASqB;AARpB,wGAAA,WAAW,OAAA;AACX,0HAAA,6BAA6B,OAAA;AAC7B,kHAAA,qBAAqB,OAAA;AACrB,8HAAA,iCAAiC,OAAA;AACjC,+GAAA,kBAAkB,OAAA;AAClB,0HAAA,6BAA6B,OAAA;AAC7B,sHAAA,yBAAyB,OAAA;AACzB,8GAAA,iBAAiB,OAAA;AAElB,yEAAmE;AAA1D,iIAAA,oBAAoB,OAAA;AAO7B,iEAIiC;AAHhC,uHAAA,cAAc,OAAA;AACd,8HAAA,qBAAqB,OAAA;AAGtB,6CAA+E;AAAtE,iHAAA,kBAAkB,OAAA;AAAE,yHAAA,0BAA0B,OAAA;AACvD,2EAAwE;AAA/D,sIAAA,wBAAwB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { GarbageCollector } from \"./garbageCollection\";\nexport {\n\tcurrentGCVersion,\n\tdefaultInactiveTimeoutMs,\n\tdefaultSessionExpiryDurationMs,\n\tdisableSweepLogKey,\n\tGCNodeType,\n\tgcTestModeKey,\n\tgcTombstoneGenerationOptionName,\n\tgcSweepGenerationOptionName,\n\tGCFeatureMatrix,\n\tGCVersion,\n\tgcVersionUpgradeToV3Key,\n\tIGarbageCollectionRuntime,\n\tIGarbageCollector,\n\tIGarbageCollectorConfigs,\n\tIGarbageCollectorCreateParams,\n\tIGCMetadata,\n\tIGCResult,\n\tIGCRuntimeOptions,\n\tIGCStats,\n\toneDayMs,\n\trunGCKey,\n\trunSessionExpiryKey,\n\trunSweepKey,\n\tstableGCVersion,\n\tsweepAttachmentBlobsKey,\n\tsweepDatastoresKey,\n\tthrowOnTombstoneLoadKey,\n\tthrowOnTombstoneUsageKey,\n\tUnreferencedState,\n} from \"./gcDefinitions\";\nexport {\n\tcloneGCData,\n\tconcatGarbageCollectionStates,\n\tgetGCDataFromSnapshot,\n\tshouldAllowGcTombstoneEnforcement,\n\tshouldAllowGcSweep,\n\ttrimLeadingAndTrailingSlashes,\n\tunpackChildNodesGCDetails,\n\ttagAsCodeArtifact,\n} from \"./gcHelpers\";\nexport { runGarbageCollection } from \"./gcReferenceGraphAlgorithm\";\nexport {\n\tIGarbageCollectionNodeData,\n\tIGarbageCollectionSnapshotData,\n\tIGarbageCollectionState,\n\tIGarbageCollectionSummaryDetailsLegacy,\n} from \"./gcSummaryDefinitions\";\nexport {\n\tgcStateBlobKey,\n\tGCSummaryStateTracker,\n\tIGCSummaryTrackingData,\n} from \"./gcSummaryStateTracker\";\nexport { GCTelemetryTracker, sendGCUnexpectedUsageEvent } from \"./gcTelemetry\";\nexport { UnreferencedStateTracker } from \"./gcUnreferencedStateTracker\";\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.0.0-internal.4.3.1";
8
+ export declare const pkgVersion = "2.0.0-internal.4.4.1";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/container-runtime";
11
- exports.pkgVersion = "2.0.0-internal.4.3.1";
11
+ exports.pkgVersion = "2.0.0-internal.4.4.1";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,mCAAmC,CAAC;AAC9C,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-internal.4.3.1\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,mCAAmC,CAAC;AAC9C,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-internal.4.4.1\";\n"]}
@@ -106,13 +106,14 @@ class ScheduleManagerCore {
106
106
  // We are intentionally directly listening to the "op" to inspect system ops as well.
107
107
  // If we do not observe system ops, we are likely to hit 0x296 assert when system ops
108
108
  // precedes start of incomplete batch.
109
- this.deltaManager.on("op", (message) => this.afterOpProcessing(message.sequenceNumber));
109
+ this.deltaManager.on("op", (message) => this.afterOpProcessing(message));
110
110
  }
111
111
  /**
112
112
  * The only public function in this class - called when we processed an op,
113
113
  * to make decision if op processing should be paused or not after that.
114
114
  */
115
- afterOpProcessing(sequenceNumber) {
115
+ afterOpProcessing(message) {
116
+ var _a;
116
117
  (0, common_utils_1.assert)(!this.localPaused, 0x294 /* "can't have op processing paused if we are processing an op" */);
117
118
  // If the inbound queue is ever empty, nothing to do!
118
119
  if (this.deltaManager.inbound.length === 0) {
@@ -126,9 +127,19 @@ class ScheduleManagerCore {
126
127
  // 2. resumed when batch end comes in (in trackPending())
127
128
  // do we have incomplete batch to worry about?
128
129
  if (this.pauseSequenceNumber !== undefined) {
129
- (0, common_utils_1.assert)(sequenceNumber < this.pauseSequenceNumber, 0x296 /* "we should never start processing incomplete batch!" */);
130
+ if (message.sequenceNumber >= this.pauseSequenceNumber) {
131
+ throw container_utils_1.DataProcessingError.create(
132
+ // Former assert 0x296
133
+ "Incomplete batch", "ScheduleManager", message, {
134
+ type: message.type,
135
+ contentType: typeof message.contents,
136
+ batch: (_a = message.metadata) === null || _a === void 0 ? void 0 : _a.batch,
137
+ compression: message.compression,
138
+ pauseSeqNum: this.pauseSequenceNumber,
139
+ });
140
+ }
130
141
  // If the next op is the start of incomplete batch, then we can't process it until it's fully in - pause!
131
- if (sequenceNumber + 1 === this.pauseSequenceNumber) {
142
+ if (message.sequenceNumber + 1 === this.pauseSequenceNumber) {
132
143
  this.pauseQueue();
133
144
  }
134
145
  }
@@ -1 +1 @@
1
- {"version":3,"file":"scheduleManager.js","sourceRoot":"","sources":["../src/scheduleManager.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 */\nimport { EventEmitter } from \"events\";\nimport { IDeltaManager } from \"@fluidframework/container-definitions\";\nimport { IDocumentMessage, ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { assert, performance } from \"@fluidframework/common-utils\";\nimport { isRuntimeMessage } from \"@fluidframework/driver-utils\";\nimport {\n\tDataCorruptionError,\n\tDataProcessingError,\n\textractSafePropertiesFromMessage,\n} from \"@fluidframework/container-utils\";\nimport { DeltaScheduler } from \"./deltaScheduler\";\nimport { pkgVersion } from \"./packageVersion\";\n\ntype IRuntimeMessageMetadata =\n\t| undefined\n\t| {\n\t\t\tbatch?: boolean;\n\t };\n\n/**\n * This class has the following responsibilities:\n *\n * 1. It tracks batches as we process ops and raises \"batchBegin\" and \"batchEnd\" events.\n * As part of it, it validates batch correctness (i.e. no system ops in the middle of batch)\n *\n * 2. It creates instance of ScheduleManagerCore that ensures we never start processing ops from batch\n * unless all ops of the batch are in.\n */\nexport class ScheduleManager {\n\tprivate readonly deltaScheduler: DeltaScheduler;\n\tprivate batchClientId: string | undefined;\n\tprivate hitError = false;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n\t\tprivate readonly emitter: EventEmitter,\n\t\treadonly getClientId: () => string | undefined,\n\t\tprivate readonly logger: ITelemetryLogger,\n\t) {\n\t\tthis.deltaScheduler = new DeltaScheduler(\n\t\t\tthis.deltaManager,\n\t\t\tChildLogger.create(this.logger, \"DeltaScheduler\"),\n\t\t);\n\t\tvoid new ScheduleManagerCore(deltaManager, getClientId, logger);\n\t}\n\n\tpublic beforeOpProcessing(message: ISequencedDocumentMessage) {\n\t\tif (this.batchClientId !== message.clientId) {\n\t\t\tassert(\n\t\t\t\tthis.batchClientId === undefined,\n\t\t\t\t0x2a2 /* \"Batch is interrupted by other client op. Should be caught by trackPending()\" */,\n\t\t\t);\n\n\t\t\t// This could be the beginning of a new batch or an individual message.\n\t\t\tthis.emitter.emit(\"batchBegin\", message);\n\t\t\tthis.deltaScheduler.batchBegin(message);\n\n\t\t\tconst batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;\n\t\t\tthis.batchClientId = batch ? message.clientId : undefined;\n\t\t}\n\t}\n\n\tpublic afterOpProcessing(error: any | undefined, message: ISequencedDocumentMessage) {\n\t\t// If this is no longer true, we need to revisit what we do where we set this.hitError.\n\t\tassert(!this.hitError, 0x2a3 /* \"container should be closed on any error\" */);\n\n\t\tif (error) {\n\t\t\t// We assume here that loader will close container and stop processing all future ops.\n\t\t\t// This is implicit dependency. If this flow changes, this code might no longer be correct.\n\t\t\tthis.hitError = true;\n\t\t\tthis.batchClientId = undefined;\n\t\t\tthis.emitter.emit(\"batchEnd\", error, message);\n\t\t\tthis.deltaScheduler.batchEnd(message);\n\t\t\treturn;\n\t\t}\n\n\t\tconst batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;\n\t\t// If no batchClientId has been set then we're in an individual batch. Else, if we get\n\t\t// batch end metadata, this is end of the current batch.\n\t\tif (this.batchClientId === undefined || batch === false) {\n\t\t\tthis.batchClientId = undefined;\n\t\t\tthis.emitter.emit(\"batchEnd\", undefined, message);\n\t\t\tthis.deltaScheduler.batchEnd(message);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/**\n * This class controls pausing and resuming of inbound queue to ensure that we never\n * start processing ops in a batch IF we do not have all ops in the batch.\n */\nclass ScheduleManagerCore {\n\tprivate pauseSequenceNumber: number | undefined;\n\tprivate currentBatchClientId: string | undefined;\n\tprivate localPaused = false;\n\tprivate timePaused = 0;\n\tprivate batchCount = 0;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n\t\tprivate readonly getClientId: () => string | undefined,\n\t\tprivate readonly logger: ITelemetryLogger,\n\t) {\n\t\t// Listen for delta manager sends and add batch metadata to messages\n\t\tthis.deltaManager.on(\"prepareSend\", (messages: IDocumentMessage[]) => {\n\t\t\tif (messages.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// First message will have the batch flag set to true if doing a batched send\n\t\t\tconst firstMessageMetadata = messages[0].metadata as IRuntimeMessageMetadata;\n\t\t\tif (!firstMessageMetadata?.batch) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If the batch contains only a single op, clear the batch flag.\n\t\t\tif (messages.length === 1) {\n\t\t\t\tdelete firstMessageMetadata.batch;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the batch flag to false on the last message to indicate the end of the send batch\n\t\t\tconst lastMessage = messages[messages.length - 1];\n\t\t\tlastMessage.metadata = { ...lastMessage.metadata, batch: false };\n\t\t});\n\n\t\t// Listen for updates and peek at the inbound\n\t\tthis.deltaManager.inbound.on(\"push\", (message: ISequencedDocumentMessage) => {\n\t\t\tthis.trackPending(message);\n\t\t});\n\n\t\t// Start with baseline - empty inbound queue.\n\t\tassert(!this.localPaused, 0x293 /* \"initial state\" */);\n\n\t\tconst allPending = this.deltaManager.inbound.toArray();\n\t\tfor (const pending of allPending) {\n\t\t\tthis.trackPending(pending);\n\t\t}\n\n\t\t// We are intentionally directly listening to the \"op\" to inspect system ops as well.\n\t\t// If we do not observe system ops, we are likely to hit 0x296 assert when system ops\n\t\t// precedes start of incomplete batch.\n\t\tthis.deltaManager.on(\"op\", (message) => this.afterOpProcessing(message.sequenceNumber));\n\t}\n\n\t/**\n\t * The only public function in this class - called when we processed an op,\n\t * to make decision if op processing should be paused or not after that.\n\t */\n\tpublic afterOpProcessing(sequenceNumber: number) {\n\t\tassert(\n\t\t\t!this.localPaused,\n\t\t\t0x294 /* \"can't have op processing paused if we are processing an op\" */,\n\t\t);\n\n\t\t// If the inbound queue is ever empty, nothing to do!\n\t\tif (this.deltaManager.inbound.length === 0) {\n\t\t\tassert(\n\t\t\t\tthis.pauseSequenceNumber === undefined,\n\t\t\t\t0x295 /* \"there should be no pending batch if we have no ops\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// The queue is\n\t\t// 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:\n\t\t// - here (processing ops until reaching start of incomplete batch)\n\t\t// - in trackPending(), when queue was empty and start of batch showed up.\n\t\t// 2. resumed when batch end comes in (in trackPending())\n\n\t\t// do we have incomplete batch to worry about?\n\t\tif (this.pauseSequenceNumber !== undefined) {\n\t\t\tassert(\n\t\t\t\tsequenceNumber < this.pauseSequenceNumber,\n\t\t\t\t0x296 /* \"we should never start processing incomplete batch!\" */,\n\t\t\t);\n\t\t\t// If the next op is the start of incomplete batch, then we can't process it until it's fully in - pause!\n\t\t\tif (sequenceNumber + 1 === this.pauseSequenceNumber) {\n\t\t\t\tthis.pauseQueue();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pauseQueue() {\n\t\tassert(!this.localPaused, 0x297 /* \"always called from resumed state\" */);\n\t\tthis.localPaused = true;\n\t\tthis.timePaused = performance.now();\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tthis.deltaManager.inbound.pause();\n\t}\n\n\tprivate resumeQueue(startBatch: number, messageEndBatch: ISequencedDocumentMessage) {\n\t\tconst endBatch = messageEndBatch.sequenceNumber;\n\t\tconst duration = this.localPaused ? performance.now() - this.timePaused : undefined;\n\n\t\tthis.batchCount++;\n\t\tif (this.batchCount % 1000 === 1) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"BatchStats\",\n\t\t\t\tsequenceNumber: endBatch,\n\t\t\t\tlength: endBatch - startBatch + 1,\n\t\t\t\tmsnDistance: endBatch - messageEndBatch.minimumSequenceNumber,\n\t\t\t\tduration,\n\t\t\t\tbatchCount: this.batchCount,\n\t\t\t\tinterrupted: this.localPaused,\n\t\t\t});\n\t\t}\n\n\t\t// Return early if no change in value\n\t\tif (!this.localPaused) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.localPaused = false;\n\n\t\tthis.deltaManager.inbound.resume();\n\t}\n\n\t/**\n\t * Called for each incoming op (i.e. inbound \"push\" notification)\n\t */\n\tprivate trackPending(message: ISequencedDocumentMessage) {\n\t\tassert(\n\t\t\tthis.deltaManager.inbound.length !== 0,\n\t\t\t0x298 /* \"we have something in the queue that generates this event\" */,\n\t\t);\n\n\t\tassert(\n\t\t\t(this.currentBatchClientId === undefined) === (this.pauseSequenceNumber === undefined),\n\t\t\t0x299 /* \"non-synchronized state\" */,\n\t\t);\n\n\t\tconst metadata = message.metadata as IRuntimeMessageMetadata;\n\t\t// batchMetadata will be true for the message that starts a batch, false for the one that ends it, and\n\t\t// undefined for all other messages.\n\t\tconst batchMetadata = metadata?.batch;\n\n\t\t// Protocol messages are never part of a runtime batch of messages\n\t\tif (!isRuntimeMessage(message)) {\n\t\t\t// Protocol messages should never show up in the middle of the batch!\n\t\t\tif (this.currentBatchClientId !== undefined) {\n\t\t\t\tthrow DataProcessingError.create(\n\t\t\t\t\t\"Received a system message during batch processing\", // Formerly known as assert 0x29a\n\t\t\t\t\t\"trackPending\",\n\t\t\t\t\tmessage,\n\t\t\t\t\t{\n\t\t\t\t\t\truntimeVersion: pkgVersion,\n\t\t\t\t\t\tbatchClientId: this.currentBatchClientId,\n\t\t\t\t\t\tpauseSequenceNumber: this.pauseSequenceNumber,\n\t\t\t\t\t\tlocalBatch: this.currentBatchClientId === this.getClientId(),\n\t\t\t\t\t\tmessageType: message.type,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tassert(batchMetadata === undefined, 0x29b /* \"system op in a batch?\" */);\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29c /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.currentBatchClientId === undefined && batchMetadata === undefined) {\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29d /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// If we got here, the message is part of a batch. Either starting, in progress, or ending.\n\n\t\t// If this is not the start of the batch, error out if the message was sent by a client other than the one that\n\t\t// started the current batch (it should not be possible for ops from other clients to get interleaved with a batch).\n\t\tif (\n\t\t\tthis.currentBatchClientId !== undefined &&\n\t\t\tthis.currentBatchClientId !== message.clientId\n\t\t) {\n\t\t\tthrow new DataCorruptionError(\"OpBatchIncomplete\", {\n\t\t\t\truntimeVersion: pkgVersion,\n\t\t\t\tbatchClientId: this.currentBatchClientId,\n\t\t\t\tpauseSequenceNumber: this.pauseSequenceNumber,\n\t\t\t\tlocalBatch: this.currentBatchClientId === this.getClientId(),\n\t\t\t\tlocalMessage: message.clientId === this.getClientId(),\n\t\t\t\t...extractSafePropertiesFromMessage(message),\n\t\t\t});\n\t\t}\n\n\t\t// The queue is\n\t\t// 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:\n\t\t// - in afterOpProcessing() - processing ops until reaching start of incomplete batch\n\t\t// - here, when queue was empty and start of batch showed up (batchMetadata === true below).\n\t\t// 2. resumed when batch end comes in (batchMetadata === false below)\n\n\t\tif (batchMetadata) {\n\t\t\tassert(\n\t\t\t\tthis.currentBatchClientId === undefined,\n\t\t\t\t0x29e /* \"there can't be active batch\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29f /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\tthis.pauseSequenceNumber = message.sequenceNumber;\n\t\t\tthis.currentBatchClientId = message.clientId;\n\t\t\t// Start of the batch\n\t\t\t// Only pause processing if queue has no other ops!\n\t\t\t// If there are any other ops in the queue, processing will be stopped when they are processed!\n\t\t\tif (this.deltaManager.inbound.length === 1) {\n\t\t\t\tthis.pauseQueue();\n\t\t\t}\n\t\t} else if (batchMetadata === false) {\n\t\t\tassert(\n\t\t\t\tthis.pauseSequenceNumber !== undefined,\n\t\t\t\t0x2a0 /* \"batch presence was validated above\" */,\n\t\t\t);\n\t\t\t// Batch is complete, we can process it!\n\t\t\tthis.resumeQueue(this.pauseSequenceNumber, message);\n\t\t\tthis.pauseSequenceNumber = undefined;\n\t\t\tthis.currentBatchClientId = undefined;\n\t\t} else {\n\t\t\t// Continuation of current batch. Do nothing\n\t\t\tassert(this.currentBatchClientId !== undefined, 0x2a1 /* \"logic error\" */);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"scheduleManager.js","sourceRoot":"","sources":["../src/scheduleManager.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 */\nimport { EventEmitter } from \"events\";\nimport { IDeltaManager } from \"@fluidframework/container-definitions\";\nimport { IDocumentMessage, ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { assert, performance } from \"@fluidframework/common-utils\";\nimport { isRuntimeMessage } from \"@fluidframework/driver-utils\";\nimport {\n\tDataCorruptionError,\n\tDataProcessingError,\n\textractSafePropertiesFromMessage,\n} from \"@fluidframework/container-utils\";\nimport { DeltaScheduler } from \"./deltaScheduler\";\nimport { pkgVersion } from \"./packageVersion\";\n\ntype IRuntimeMessageMetadata =\n\t| undefined\n\t| {\n\t\t\tbatch?: boolean;\n\t };\n\n/**\n * This class has the following responsibilities:\n *\n * 1. It tracks batches as we process ops and raises \"batchBegin\" and \"batchEnd\" events.\n * As part of it, it validates batch correctness (i.e. no system ops in the middle of batch)\n *\n * 2. It creates instance of ScheduleManagerCore that ensures we never start processing ops from batch\n * unless all ops of the batch are in.\n */\nexport class ScheduleManager {\n\tprivate readonly deltaScheduler: DeltaScheduler;\n\tprivate batchClientId: string | undefined;\n\tprivate hitError = false;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n\t\tprivate readonly emitter: EventEmitter,\n\t\treadonly getClientId: () => string | undefined,\n\t\tprivate readonly logger: ITelemetryLogger,\n\t) {\n\t\tthis.deltaScheduler = new DeltaScheduler(\n\t\t\tthis.deltaManager,\n\t\t\tChildLogger.create(this.logger, \"DeltaScheduler\"),\n\t\t);\n\t\tvoid new ScheduleManagerCore(deltaManager, getClientId, logger);\n\t}\n\n\tpublic beforeOpProcessing(message: ISequencedDocumentMessage) {\n\t\tif (this.batchClientId !== message.clientId) {\n\t\t\tassert(\n\t\t\t\tthis.batchClientId === undefined,\n\t\t\t\t0x2a2 /* \"Batch is interrupted by other client op. Should be caught by trackPending()\" */,\n\t\t\t);\n\n\t\t\t// This could be the beginning of a new batch or an individual message.\n\t\t\tthis.emitter.emit(\"batchBegin\", message);\n\t\t\tthis.deltaScheduler.batchBegin(message);\n\n\t\t\tconst batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;\n\t\t\tthis.batchClientId = batch ? message.clientId : undefined;\n\t\t}\n\t}\n\n\tpublic afterOpProcessing(error: any | undefined, message: ISequencedDocumentMessage) {\n\t\t// If this is no longer true, we need to revisit what we do where we set this.hitError.\n\t\tassert(!this.hitError, 0x2a3 /* \"container should be closed on any error\" */);\n\n\t\tif (error) {\n\t\t\t// We assume here that loader will close container and stop processing all future ops.\n\t\t\t// This is implicit dependency. If this flow changes, this code might no longer be correct.\n\t\t\tthis.hitError = true;\n\t\t\tthis.batchClientId = undefined;\n\t\t\tthis.emitter.emit(\"batchEnd\", error, message);\n\t\t\tthis.deltaScheduler.batchEnd(message);\n\t\t\treturn;\n\t\t}\n\n\t\tconst batch = (message?.metadata as IRuntimeMessageMetadata)?.batch;\n\t\t// If no batchClientId has been set then we're in an individual batch. Else, if we get\n\t\t// batch end metadata, this is end of the current batch.\n\t\tif (this.batchClientId === undefined || batch === false) {\n\t\t\tthis.batchClientId = undefined;\n\t\t\tthis.emitter.emit(\"batchEnd\", undefined, message);\n\t\t\tthis.deltaScheduler.batchEnd(message);\n\t\t\treturn;\n\t\t}\n\t}\n}\n\n/**\n * This class controls pausing and resuming of inbound queue to ensure that we never\n * start processing ops in a batch IF we do not have all ops in the batch.\n */\nclass ScheduleManagerCore {\n\tprivate pauseSequenceNumber: number | undefined;\n\tprivate currentBatchClientId: string | undefined;\n\tprivate localPaused = false;\n\tprivate timePaused = 0;\n\tprivate batchCount = 0;\n\n\tconstructor(\n\t\tprivate readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n\t\tprivate readonly getClientId: () => string | undefined,\n\t\tprivate readonly logger: ITelemetryLogger,\n\t) {\n\t\t// Listen for delta manager sends and add batch metadata to messages\n\t\tthis.deltaManager.on(\"prepareSend\", (messages: IDocumentMessage[]) => {\n\t\t\tif (messages.length === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// First message will have the batch flag set to true if doing a batched send\n\t\t\tconst firstMessageMetadata = messages[0].metadata as IRuntimeMessageMetadata;\n\t\t\tif (!firstMessageMetadata?.batch) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If the batch contains only a single op, clear the batch flag.\n\t\t\tif (messages.length === 1) {\n\t\t\t\tdelete firstMessageMetadata.batch;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the batch flag to false on the last message to indicate the end of the send batch\n\t\t\tconst lastMessage = messages[messages.length - 1];\n\t\t\tlastMessage.metadata = { ...lastMessage.metadata, batch: false };\n\t\t});\n\n\t\t// Listen for updates and peek at the inbound\n\t\tthis.deltaManager.inbound.on(\"push\", (message: ISequencedDocumentMessage) => {\n\t\t\tthis.trackPending(message);\n\t\t});\n\n\t\t// Start with baseline - empty inbound queue.\n\t\tassert(!this.localPaused, 0x293 /* \"initial state\" */);\n\n\t\tconst allPending = this.deltaManager.inbound.toArray();\n\t\tfor (const pending of allPending) {\n\t\t\tthis.trackPending(pending);\n\t\t}\n\n\t\t// We are intentionally directly listening to the \"op\" to inspect system ops as well.\n\t\t// If we do not observe system ops, we are likely to hit 0x296 assert when system ops\n\t\t// precedes start of incomplete batch.\n\t\tthis.deltaManager.on(\"op\", (message) => this.afterOpProcessing(message));\n\t}\n\n\t/**\n\t * The only public function in this class - called when we processed an op,\n\t * to make decision if op processing should be paused or not after that.\n\t */\n\tpublic afterOpProcessing(message: ISequencedDocumentMessage) {\n\t\tassert(\n\t\t\t!this.localPaused,\n\t\t\t0x294 /* \"can't have op processing paused if we are processing an op\" */,\n\t\t);\n\n\t\t// If the inbound queue is ever empty, nothing to do!\n\t\tif (this.deltaManager.inbound.length === 0) {\n\t\t\tassert(\n\t\t\t\tthis.pauseSequenceNumber === undefined,\n\t\t\t\t0x295 /* \"there should be no pending batch if we have no ops\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// The queue is\n\t\t// 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:\n\t\t// - here (processing ops until reaching start of incomplete batch)\n\t\t// - in trackPending(), when queue was empty and start of batch showed up.\n\t\t// 2. resumed when batch end comes in (in trackPending())\n\n\t\t// do we have incomplete batch to worry about?\n\t\tif (this.pauseSequenceNumber !== undefined) {\n\t\t\tif (message.sequenceNumber >= this.pauseSequenceNumber) {\n\t\t\t\tthrow DataProcessingError.create(\n\t\t\t\t\t// Former assert 0x296\n\t\t\t\t\t\"Incomplete batch\",\n\t\t\t\t\t\"ScheduleManager\",\n\t\t\t\t\tmessage,\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: message.type,\n\t\t\t\t\t\tcontentType: typeof message.contents,\n\t\t\t\t\t\tbatch: message.metadata?.batch,\n\t\t\t\t\t\tcompression: message.compression,\n\t\t\t\t\t\tpauseSeqNum: this.pauseSequenceNumber,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// If the next op is the start of incomplete batch, then we can't process it until it's fully in - pause!\n\t\t\tif (message.sequenceNumber + 1 === this.pauseSequenceNumber) {\n\t\t\t\tthis.pauseQueue();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate pauseQueue() {\n\t\tassert(!this.localPaused, 0x297 /* \"always called from resumed state\" */);\n\t\tthis.localPaused = true;\n\t\tthis.timePaused = performance.now();\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises\n\t\tthis.deltaManager.inbound.pause();\n\t}\n\n\tprivate resumeQueue(startBatch: number, messageEndBatch: ISequencedDocumentMessage) {\n\t\tconst endBatch = messageEndBatch.sequenceNumber;\n\t\tconst duration = this.localPaused ? performance.now() - this.timePaused : undefined;\n\n\t\tthis.batchCount++;\n\t\tif (this.batchCount % 1000 === 1) {\n\t\t\tthis.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"BatchStats\",\n\t\t\t\tsequenceNumber: endBatch,\n\t\t\t\tlength: endBatch - startBatch + 1,\n\t\t\t\tmsnDistance: endBatch - messageEndBatch.minimumSequenceNumber,\n\t\t\t\tduration,\n\t\t\t\tbatchCount: this.batchCount,\n\t\t\t\tinterrupted: this.localPaused,\n\t\t\t});\n\t\t}\n\n\t\t// Return early if no change in value\n\t\tif (!this.localPaused) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.localPaused = false;\n\n\t\tthis.deltaManager.inbound.resume();\n\t}\n\n\t/**\n\t * Called for each incoming op (i.e. inbound \"push\" notification)\n\t */\n\tprivate trackPending(message: ISequencedDocumentMessage) {\n\t\tassert(\n\t\t\tthis.deltaManager.inbound.length !== 0,\n\t\t\t0x298 /* \"we have something in the queue that generates this event\" */,\n\t\t);\n\n\t\tassert(\n\t\t\t(this.currentBatchClientId === undefined) === (this.pauseSequenceNumber === undefined),\n\t\t\t0x299 /* \"non-synchronized state\" */,\n\t\t);\n\n\t\tconst metadata = message.metadata as IRuntimeMessageMetadata;\n\t\t// batchMetadata will be true for the message that starts a batch, false for the one that ends it, and\n\t\t// undefined for all other messages.\n\t\tconst batchMetadata = metadata?.batch;\n\n\t\t// Protocol messages are never part of a runtime batch of messages\n\t\tif (!isRuntimeMessage(message)) {\n\t\t\t// Protocol messages should never show up in the middle of the batch!\n\t\t\tif (this.currentBatchClientId !== undefined) {\n\t\t\t\tthrow DataProcessingError.create(\n\t\t\t\t\t\"Received a system message during batch processing\", // Formerly known as assert 0x29a\n\t\t\t\t\t\"trackPending\",\n\t\t\t\t\tmessage,\n\t\t\t\t\t{\n\t\t\t\t\t\truntimeVersion: pkgVersion,\n\t\t\t\t\t\tbatchClientId: this.currentBatchClientId,\n\t\t\t\t\t\tpauseSequenceNumber: this.pauseSequenceNumber,\n\t\t\t\t\t\tlocalBatch: this.currentBatchClientId === this.getClientId(),\n\t\t\t\t\t\tmessageType: message.type,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tassert(batchMetadata === undefined, 0x29b /* \"system op in a batch?\" */);\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29c /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.currentBatchClientId === undefined && batchMetadata === undefined) {\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29d /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// If we got here, the message is part of a batch. Either starting, in progress, or ending.\n\n\t\t// If this is not the start of the batch, error out if the message was sent by a client other than the one that\n\t\t// started the current batch (it should not be possible for ops from other clients to get interleaved with a batch).\n\t\tif (\n\t\t\tthis.currentBatchClientId !== undefined &&\n\t\t\tthis.currentBatchClientId !== message.clientId\n\t\t) {\n\t\t\tthrow new DataCorruptionError(\"OpBatchIncomplete\", {\n\t\t\t\truntimeVersion: pkgVersion,\n\t\t\t\tbatchClientId: this.currentBatchClientId,\n\t\t\t\tpauseSequenceNumber: this.pauseSequenceNumber,\n\t\t\t\tlocalBatch: this.currentBatchClientId === this.getClientId(),\n\t\t\t\tlocalMessage: message.clientId === this.getClientId(),\n\t\t\t\t...extractSafePropertiesFromMessage(message),\n\t\t\t});\n\t\t}\n\n\t\t// The queue is\n\t\t// 1. paused only when the next message to be processed is the beginning of a batch. Done in two places:\n\t\t// - in afterOpProcessing() - processing ops until reaching start of incomplete batch\n\t\t// - here, when queue was empty and start of batch showed up (batchMetadata === true below).\n\t\t// 2. resumed when batch end comes in (batchMetadata === false below)\n\n\t\tif (batchMetadata) {\n\t\t\tassert(\n\t\t\t\tthis.currentBatchClientId === undefined,\n\t\t\t\t0x29e /* \"there can't be active batch\" */,\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!this.localPaused,\n\t\t\t\t0x29f /* \"we should be processing ops when there is no active batch\" */,\n\t\t\t);\n\t\t\tthis.pauseSequenceNumber = message.sequenceNumber;\n\t\t\tthis.currentBatchClientId = message.clientId;\n\t\t\t// Start of the batch\n\t\t\t// Only pause processing if queue has no other ops!\n\t\t\t// If there are any other ops in the queue, processing will be stopped when they are processed!\n\t\t\tif (this.deltaManager.inbound.length === 1) {\n\t\t\t\tthis.pauseQueue();\n\t\t\t}\n\t\t} else if (batchMetadata === false) {\n\t\t\tassert(\n\t\t\t\tthis.pauseSequenceNumber !== undefined,\n\t\t\t\t0x2a0 /* \"batch presence was validated above\" */,\n\t\t\t);\n\t\t\t// Batch is complete, we can process it!\n\t\t\tthis.resumeQueue(this.pauseSequenceNumber, message);\n\t\t\tthis.pauseSequenceNumber = undefined;\n\t\t\tthis.currentBatchClientId = undefined;\n\t\t} else {\n\t\t\t// Continuation of current batch. Do nothing\n\t\t\tassert(this.currentBatchClientId !== undefined, 0x2a1 /* \"logic error\" */);\n\t\t}\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"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"}
@@ -298,8 +298,9 @@ export class BlobManager extends TypedEventEmitter {
298
298
  onUploadResolve(localId, response) {
299
299
  var _a;
300
300
  const entry = this.pendingBlobs.get(localId);
301
- assert((entry === null || entry === void 0 ? void 0 : entry.status) === PendingBlobStatus.OnlinePendingUpload ||
302
- (entry === null || entry === void 0 ? void 0 : entry.status) === PendingBlobStatus.OfflinePendingUpload, 0x386 /* Must have pending blob entry for uploaded blob */);
301
+ assert(entry !== undefined, 0x6c8 /* pending blob entry not found for uploaded blob */);
302
+ assert(entry.status === PendingBlobStatus.OnlinePendingUpload ||
303
+ entry.status === PendingBlobStatus.OfflinePendingUpload, 0x386 /* Must have pending blob entry for uploaded blob */);
303
304
  entry.storageId = response.id;
304
305
  entry.uploadTime = Date.now();
305
306
  entry.minTTLInSeconds = response.minTTLInSeconds;