@fluidframework/container-runtime 0.58.2002 → 0.58.3000-61081

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 (83) hide show
  1. package/dist/blobManager.d.ts +3 -2
  2. package/dist/blobManager.d.ts.map +1 -1
  3. package/dist/blobManager.js +13 -9
  4. package/dist/blobManager.js.map +1 -1
  5. package/dist/connectionTelemetry.d.ts.map +1 -1
  6. package/dist/connectionTelemetry.js +63 -23
  7. package/dist/connectionTelemetry.js.map +1 -1
  8. package/dist/containerRuntime.d.ts +12 -4
  9. package/dist/containerRuntime.d.ts.map +1 -1
  10. package/dist/containerRuntime.js +61 -15
  11. package/dist/containerRuntime.js.map +1 -1
  12. package/dist/opTelemetry.d.ts +22 -0
  13. package/dist/opTelemetry.d.ts.map +1 -0
  14. package/dist/opTelemetry.js +59 -0
  15. package/dist/opTelemetry.js.map +1 -0
  16. package/dist/orderedClientElection.d.ts +57 -6
  17. package/dist/orderedClientElection.d.ts.map +1 -1
  18. package/dist/orderedClientElection.js +140 -25
  19. package/dist/orderedClientElection.js.map +1 -1
  20. package/dist/packageVersion.d.ts +1 -1
  21. package/dist/packageVersion.d.ts.map +1 -1
  22. package/dist/packageVersion.js +1 -1
  23. package/dist/packageVersion.js.map +1 -1
  24. package/dist/summarizerClientElection.d.ts +2 -0
  25. package/dist/summarizerClientElection.d.ts.map +1 -1
  26. package/dist/summarizerClientElection.js +7 -2
  27. package/dist/summarizerClientElection.js.map +1 -1
  28. package/dist/summarizerTypes.d.ts +9 -0
  29. package/dist/summarizerTypes.d.ts.map +1 -1
  30. package/dist/summarizerTypes.js.map +1 -1
  31. package/dist/summaryGenerator.d.ts.map +1 -1
  32. package/dist/summaryGenerator.js +1 -1
  33. package/dist/summaryGenerator.js.map +1 -1
  34. package/dist/summaryManager.d.ts.map +1 -1
  35. package/dist/summaryManager.js +14 -3
  36. package/dist/summaryManager.js.map +1 -1
  37. package/lib/blobManager.d.ts +3 -2
  38. package/lib/blobManager.d.ts.map +1 -1
  39. package/lib/blobManager.js +14 -10
  40. package/lib/blobManager.js.map +1 -1
  41. package/lib/connectionTelemetry.d.ts.map +1 -1
  42. package/lib/connectionTelemetry.js +63 -23
  43. package/lib/connectionTelemetry.js.map +1 -1
  44. package/lib/containerRuntime.d.ts +12 -4
  45. package/lib/containerRuntime.d.ts.map +1 -1
  46. package/lib/containerRuntime.js +62 -16
  47. package/lib/containerRuntime.js.map +1 -1
  48. package/lib/opTelemetry.d.ts +22 -0
  49. package/lib/opTelemetry.d.ts.map +1 -0
  50. package/lib/opTelemetry.js +55 -0
  51. package/lib/opTelemetry.js.map +1 -0
  52. package/lib/orderedClientElection.d.ts +57 -6
  53. package/lib/orderedClientElection.d.ts.map +1 -1
  54. package/lib/orderedClientElection.js +140 -25
  55. package/lib/orderedClientElection.js.map +1 -1
  56. package/lib/packageVersion.d.ts +1 -1
  57. package/lib/packageVersion.d.ts.map +1 -1
  58. package/lib/packageVersion.js +1 -1
  59. package/lib/packageVersion.js.map +1 -1
  60. package/lib/summarizerClientElection.d.ts +2 -0
  61. package/lib/summarizerClientElection.d.ts.map +1 -1
  62. package/lib/summarizerClientElection.js +7 -2
  63. package/lib/summarizerClientElection.js.map +1 -1
  64. package/lib/summarizerTypes.d.ts +9 -0
  65. package/lib/summarizerTypes.d.ts.map +1 -1
  66. package/lib/summarizerTypes.js.map +1 -1
  67. package/lib/summaryGenerator.d.ts.map +1 -1
  68. package/lib/summaryGenerator.js +1 -1
  69. package/lib/summaryGenerator.js.map +1 -1
  70. package/lib/summaryManager.d.ts.map +1 -1
  71. package/lib/summaryManager.js +14 -3
  72. package/lib/summaryManager.js.map +1 -1
  73. package/package.json +47 -15
  74. package/src/blobManager.ts +19 -11
  75. package/src/connectionTelemetry.ts +110 -19
  76. package/src/containerRuntime.ts +85 -19
  77. package/src/opTelemetry.ts +71 -0
  78. package/src/orderedClientElection.ts +154 -25
  79. package/src/packageVersion.ts +1 -1
  80. package/src/summarizerClientElection.ts +7 -2
  81. package/src/summarizerTypes.ts +9 -0
  82. package/src/summaryGenerator.ts +9 -1
  83. package/src/summaryManager.ts +15 -4
@@ -1 +1 @@
1
- {"version":3,"file":"summaryManager.js","sourceRoot":"","sources":["../src/summaryManager.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 { IDisposable, IEvent, IEventProvider, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ChildLogger, PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { ISummarizerClientElection } from \"./summarizerClientElection\";\nimport { IThrottler } from \"./throttler\";\nimport {\n ISummarizer,\n ISummarizerOptions,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nimport { SummaryCollection } from \"./summaryCollection\";\n\nconst defaultInitialDelayMs = 5000;\nconst defaultOpsToBypassInitialDelay = 4000;\n\nexport enum SummaryManagerState {\n Off = 0,\n Starting = 1,\n Running = 2,\n Stopping = 3,\n}\n\n// Please note that all reasons in this list are not errors,\n// and thus they are not raised today to parent container as error.\n// If this needs to be changed in future, we should re-evaluate what and how we raise to summarizer\ntype StopReason = Extract<SummarizerStopReason, \"parentNotConnected\" | \"parentShouldNotSummarize\">;\ntype ShouldSummarizeState =\n | { shouldSummarize: true; }\n | { shouldSummarize: false; stopReason: StopReason; };\n\nexport interface IConnectedEvents extends IEvent {\n (event: \"connected\", listener: (clientId: string) => void);\n (event: \"disconnected\", listener: () => void);\n}\n\n/**\n * IConnectedState describes an object that SummaryManager can watch to observe connection/disconnection.\n *\n * Under current implementation, its role will be fulfilled by the ContainerRuntime, but this could be replaced\n * with anything else that fulfills the contract if we want to shift the layer that the SummaryManager lives at.\n */\nexport interface IConnectedState extends IEventProvider<IConnectedEvents> {\n readonly connected: boolean;\n\n /**\n * Under current implementation this is undefined if we've never connected, otherwise it's the clientId from our\n * latest connection (even if we've since disconnected!). Although this happens to be the behavior we want in\n * SummaryManager, I suspect that globally we may eventually want to modify this behavior (e.g. make clientId\n * undefined while disconnected). To protect against this, let's assume this field can't be trusted while\n * disconnected and instead separately track \"latest clientId\" in SummaryManager.\n */\n readonly clientId: string | undefined;\n}\n\nexport interface ISummaryManagerConfig {\n initialDelayMs: number;\n opsToBypassInitialDelay: number;\n}\n\n/**\n * SummaryManager is created by parent container (i.e. interactive container with clientType !== \"summarizer\") only.\n * It observes changes in calculated summarizer and reacts to changes by either creating summarizer client or\n * stopping existing summarizer client.\n */\nexport class SummaryManager implements IDisposable {\n private readonly logger: ITelemetryLogger;\n private readonly opsToBypassInitialDelay: number;\n private readonly initialDelayMs: number;\n private latestClientId: string | undefined;\n private state = SummaryManagerState.Off;\n private summarizer?: ISummarizer;\n private _disposed = false;\n\n public get disposed() {\n return this._disposed;\n }\n\n public get currentState() { return this.state; }\n\n constructor(\n private readonly clientElection: ISummarizerClientElection,\n private readonly connectedState: IConnectedState,\n private readonly summaryCollection:\n Pick<SummaryCollection, \"opsSinceLastAck\" | \"addOpListener\" | \"removeOpListener\">,\n parentLogger: ITelemetryLogger,\n /** Creates summarizer by asking interactive container to spawn summarizing container and\n * get back its Summarizer instance. */\n private readonly requestSummarizerFn: () => Promise<ISummarizer>,\n private readonly startThrottler: IThrottler,\n {\n initialDelayMs = defaultInitialDelayMs,\n opsToBypassInitialDelay = defaultOpsToBypassInitialDelay,\n }: Readonly<Partial<ISummaryManagerConfig>> = {},\n private readonly summarizerOptions?: Readonly<Partial<ISummarizerOptions>>,\n ) {\n this.logger = ChildLogger.create(\n parentLogger,\n \"SummaryManager\",\n {all:{ clientId: () => this.latestClientId }});\n\n this.connectedState.on(\"connected\", this.handleConnected);\n this.connectedState.on(\"disconnected\", this.handleDisconnected);\n this.latestClientId = this.connectedState.clientId;\n\n this.opsToBypassInitialDelay = opsToBypassInitialDelay;\n this.initialDelayMs = initialDelayMs;\n }\n\n /**\n * Until start is called, the SummaryManager won't begin attempting to start summarization. This ensures there's\n * a window between construction and starting where the caller can attach listeners.\n */\n public start(): void {\n this.clientElection.on(\"electedSummarizerChanged\", this.refreshSummarizer);\n this.refreshSummarizer();\n }\n\n private readonly handleConnected = (clientId: string) => {\n this.latestClientId = clientId;\n // If we have a summarizer, it should have been either cancelled on disconnected by now.\n // But because of lastSummary process, it can still hang around, so there is not much we can\n // check or assert.\n this.refreshSummarizer();\n };\n\n private readonly handleDisconnected = () => {\n this.refreshSummarizer();\n };\n\n private static readonly isStartingOrRunning = (state: SummaryManagerState) =>\n state === SummaryManagerState.Starting || state === SummaryManagerState.Running;\n\n private getShouldSummarizeState(): ShouldSummarizeState {\n if (!this.connectedState.connected) {\n return { shouldSummarize: false, stopReason: \"parentNotConnected\" };\n } else if (this.connectedState.clientId !== this.clientElection.electedClientId) {\n return { shouldSummarize: false, stopReason: \"parentShouldNotSummarize\" };\n } else if (this.disposed) {\n assert(false, 0x260 /* \"Disposed should mean disconnected!\" */);\n } else {\n return { shouldSummarize: true };\n }\n }\n\n private readonly refreshSummarizer = () => {\n // Transition states depending on shouldSummarize, which is a calculated property\n // that is only true if this client is connected and is the elected summarizer.\n const shouldSummarizeState = this.getShouldSummarizeState();\n switch (this.state) {\n case SummaryManagerState.Off: {\n if (shouldSummarizeState.shouldSummarize) {\n this.startSummarization();\n }\n return;\n }\n case SummaryManagerState.Starting: {\n // Cannot take any action until summarizer is created\n // state transition will occur after creation\n return;\n }\n case SummaryManagerState.Running: {\n if (shouldSummarizeState.shouldSummarize === false) {\n this.stop(shouldSummarizeState.stopReason);\n }\n return;\n }\n case SummaryManagerState.Stopping: {\n // Cannot take any action until running summarizer finishes\n // state transition will occur after it stops\n return;\n }\n default: {\n return;\n }\n }\n };\n\n private startSummarization() {\n assert(this.state === SummaryManagerState.Off, 0x261 /* \"Expected: off\" */);\n this.state = SummaryManagerState.Starting;\n\n assert(this.summarizer === undefined, 0x262 /* \"Old summarizer is still working!\" */);\n\n let reason = \"unknown\";\n\n this.delayBeforeCreatingSummarizer().then(async (startWithInitialDelay: boolean) => {\n // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n // but only if creation was delayed. If it was not, then we want to ensure we always create\n // a summarizer to kick off lastSummary. Without that, we would not be able to summarize and get\n // document out of broken state if it has too many ops and ordering service keeps nacking main\n // container (and thus it goes into cycle of reconnects)\n if (startWithInitialDelay && this.getShouldSummarizeState().shouldSummarize === false) {\n return;\n }\n\n const summarizer = await this.requestSummarizerFn();\n\n // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n const shouldSummarizeState = this.getShouldSummarizeState();\n if (shouldSummarizeState.shouldSummarize === false) {\n summarizer.stop(shouldSummarizeState.stopReason);\n return;\n }\n\n assert(this.state === SummaryManagerState.Starting, 0x263 /* \"Expected: starting\" */);\n this.state = SummaryManagerState.Running;\n\n this.summarizer = summarizer;\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const clientId = this.latestClientId!;\n\n reason = await PerformanceEvent.timedExecAsync(\n this.logger,\n { eventName: \"RunningSummarizer\", attempt: this.startThrottler.numAttempts },\n async () => summarizer.run(clientId, this.summarizerOptions),\n );\n }).catch((error) => {\n // Most of exceptions happen due to container being closed while loading it, due to\n // summarizer container loosing connection while load.\n // Not worth reporting such errors as errors. That said, we might miss some real errors if\n // we ignore blindly, so try to narrow signature we are looking for - skip logging\n // error only if this client should no longer be a summarizer (which in practice\n // means it also lost connection), and error happened on load (we do not have summarizer).\n // We could annotate the error raised in Container.load where the container closed during load with no error\n // and check for that case here, but that does not seem to be necessary.\n if (this.getShouldSummarizeState().shouldSummarize || this.summarizer !== undefined) {\n // Report any failure as an error unless it was due to cancellation (like \"disconnected\" error)\n // If failure happened on container load, we may not yet realized that socket disconnected, so check\n // offlineError.\n const category = error?.errorType === DriverErrorType.offlineError ? \"generic\" : \"error\";\n this.logger.sendTelemetryEvent(\n {\n eventName: \"SummarizerException\",\n category,\n },\n error);\n\n // Note that summarizer may keep going (like doing last summary).\n // Ideally we await stopping process, but this code path is due to a bug\n // that needs to be fixed either way.\n if (SummaryManager.isStartingOrRunning(this.state)) {\n this.stop(\"summarizerException\");\n }\n }\n }).finally(() => {\n assert(this.state !== SummaryManagerState.Off, 0x264 /* \"Expected: Not Off\" */);\n this.state = SummaryManagerState.Off;\n\n this.summarizer = undefined;\n\n this.logger.sendTelemetryEvent({\n eventName: \"EndingSummarizer\",\n reason,\n });\n\n if (this.getShouldSummarizeState().shouldSummarize) {\n this.startSummarization();\n }\n });\n }\n\n private stop(reason: SummarizerStopReason) {\n if (!SummaryManager.isStartingOrRunning(this.state)) {\n return;\n }\n this.state = SummaryManagerState.Stopping;\n\n // Stopping the running summarizer client should trigger a change\n // in states when the running summarizer closes\n this.summarizer?.stop(reason);\n }\n\n /**\n * Implements initial delay before creating summarizer\n * @returns true, if creation is delayed due to heuristics (not many ops to summarize).\n * False if summarizer should start immediately due to too many unsummarized ops.\n */\n private async delayBeforeCreatingSummarizer(): Promise<boolean> {\n // throttle creation of new summarizer containers to prevent spamming the server with websocket connections\n let delayMs = this.startThrottler.getDelay();\n\n // We have been elected the summarizer. Some day we may be able to summarize with a live document but for\n // now we play it safe and launch a second copy.\n this.logger.sendTelemetryEvent({\n eventName: \"CreatingSummarizer\",\n throttlerDelay: delayMs,\n initialDelay: this.initialDelayMs,\n startThrottlerMaxDelayMs: this.startThrottler.maxDelayMs,\n opsSinceLastAck: this.summaryCollection.opsSinceLastAck,\n opsToBypassInitialDelay: this.opsToBypassInitialDelay,\n });\n\n // This delay helps ensure that last summarizer that might be left from previous client\n // has enough time to complete its last summary and thus new summarizer not conflict with previous one.\n // If, however, there are too many unsummarized ops, try to resolve it as quickly as possible, with\n // understanding that we may see nacks because of such quick action.\n // A better design would be for summarizer election logic to always select current summarizer as\n // summarizing client (i.e. clientType === \"summarizer\" can be elected) to ensure that nobody else can\n // summarizer while it finishes its work and moves to exit.\n // It also helps with pure boot scenario (single client) to offset expensive work a bit out from\n // critical boot sequence.\n let startWithInitialDelay = false;\n if (this.summaryCollection.opsSinceLastAck < this.opsToBypassInitialDelay) {\n startWithInitialDelay = true;\n delayMs = Math.max(delayMs, this.initialDelayMs);\n }\n\n if (delayMs > 0) {\n let timer;\n let resolveOpPromiseFn;\n // Create a listener that will break the delay if we've exceeded the initial delay ops count.\n const opsListenerFn = () => {\n if (this.summaryCollection.opsSinceLastAck >= this.opsToBypassInitialDelay) {\n clearTimeout(timer);\n resolveOpPromiseFn();\n }\n };\n // Create a Promise that will resolve when the delay expires.\n const delayPromise = new Promise<void>((resolve) => {\n timer = setTimeout(() => resolve(), delayMs);\n });\n // Create a Promise that will resolve if the ops count passes the threshold.\n const opPromise = new Promise<void>((resolve) => { resolveOpPromiseFn = resolve; });\n this.summaryCollection.addOpListener(opsListenerFn);\n await Promise.race([ delayPromise, opPromise ]);\n this.summaryCollection.removeOpListener(opsListenerFn);\n }\n return startWithInitialDelay;\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n if (this.summarizer === undefined) {\n throw Error(\"No running summarizer client\");\n // TODO: could spawn a summarizer client temporarily.\n }\n return this.summarizer.summarizeOnDemand(...args);\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this.summarizer === undefined) {\n throw Error(\"No running summarizer client\");\n // TODO: could spawn a summarizer client temporarily.\n }\n return this.summarizer.enqueueSummarize(...args);\n };\n\n public dispose() {\n this.clientElection.off(\"electedSummarizerChanged\", this.refreshSummarizer);\n this.connectedState.off(\"connected\", this.handleConnected);\n this.connectedState.off(\"disconnected\", this.handleDisconnected);\n this._disposed = true;\n }\n}\n"]}
1
+ {"version":3,"file":"summaryManager.js","sourceRoot":"","sources":["../src/summaryManager.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 { IDisposable, IEvent, IEventProvider, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ChildLogger, PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { ISummarizerClientElection } from \"./summarizerClientElection\";\nimport { IThrottler } from \"./throttler\";\nimport {\n ISummarizer,\n ISummarizerOptions,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nimport { SummaryCollection } from \"./summaryCollection\";\n\nconst defaultInitialDelayMs = 5000;\nconst defaultOpsToBypassInitialDelay = 4000;\n\nexport enum SummaryManagerState {\n Off = 0,\n Starting = 1,\n Running = 2,\n Stopping = 3,\n}\n\n// Please note that all reasons in this list are not errors,\n// and thus they are not raised today to parent container as error.\n// If this needs to be changed in future, we should re-evaluate what and how we raise to summarizer\ntype StopReason = Extract<SummarizerStopReason, \"parentNotConnected\" | \"parentShouldNotSummarize\">;\ntype ShouldSummarizeState =\n | { shouldSummarize: true; }\n | { shouldSummarize: false; stopReason: StopReason; };\n\nexport interface IConnectedEvents extends IEvent {\n (event: \"connected\", listener: (clientId: string) => void);\n (event: \"disconnected\", listener: () => void);\n}\n\n/**\n * IConnectedState describes an object that SummaryManager can watch to observe connection/disconnection.\n *\n * Under current implementation, its role will be fulfilled by the ContainerRuntime, but this could be replaced\n * with anything else that fulfills the contract if we want to shift the layer that the SummaryManager lives at.\n */\nexport interface IConnectedState extends IEventProvider<IConnectedEvents> {\n readonly connected: boolean;\n\n /**\n * Under current implementation this is undefined if we've never connected, otherwise it's the clientId from our\n * latest connection (even if we've since disconnected!). Although this happens to be the behavior we want in\n * SummaryManager, I suspect that globally we may eventually want to modify this behavior (e.g. make clientId\n * undefined while disconnected). To protect against this, let's assume this field can't be trusted while\n * disconnected and instead separately track \"latest clientId\" in SummaryManager.\n */\n readonly clientId: string | undefined;\n}\n\nexport interface ISummaryManagerConfig {\n initialDelayMs: number;\n opsToBypassInitialDelay: number;\n}\n\n/**\n * SummaryManager is created by parent container (i.e. interactive container with clientType !== \"summarizer\") only.\n * It observes changes in calculated summarizer and reacts to changes by either creating summarizer client or\n * stopping existing summarizer client.\n */\nexport class SummaryManager implements IDisposable {\n private readonly logger: ITelemetryLogger;\n private readonly opsToBypassInitialDelay: number;\n private readonly initialDelayMs: number;\n private latestClientId: string | undefined;\n private state = SummaryManagerState.Off;\n private summarizer?: ISummarizer;\n private _disposed = false;\n\n public get disposed() {\n return this._disposed;\n }\n\n public get currentState() { return this.state; }\n\n constructor(\n private readonly clientElection: ISummarizerClientElection,\n private readonly connectedState: IConnectedState,\n private readonly summaryCollection:\n Pick<SummaryCollection, \"opsSinceLastAck\" | \"addOpListener\" | \"removeOpListener\">,\n parentLogger: ITelemetryLogger,\n /** Creates summarizer by asking interactive container to spawn summarizing container and\n * get back its Summarizer instance. */\n private readonly requestSummarizerFn: () => Promise<ISummarizer>,\n private readonly startThrottler: IThrottler,\n {\n initialDelayMs = defaultInitialDelayMs,\n opsToBypassInitialDelay = defaultOpsToBypassInitialDelay,\n }: Readonly<Partial<ISummaryManagerConfig>> = {},\n private readonly summarizerOptions?: Readonly<Partial<ISummarizerOptions>>,\n ) {\n this.logger = ChildLogger.create(\n parentLogger,\n \"SummaryManager\",\n {all:{ clientId: () => this.latestClientId }});\n\n this.connectedState.on(\"connected\", this.handleConnected);\n this.connectedState.on(\"disconnected\", this.handleDisconnected);\n this.latestClientId = this.connectedState.clientId;\n\n this.opsToBypassInitialDelay = opsToBypassInitialDelay;\n this.initialDelayMs = initialDelayMs;\n }\n\n /**\n * Until start is called, the SummaryManager won't begin attempting to start summarization. This ensures there's\n * a window between construction and starting where the caller can attach listeners.\n */\n public start(): void {\n this.clientElection.on(\"electedSummarizerChanged\", this.refreshSummarizer);\n this.refreshSummarizer();\n }\n\n private readonly handleConnected = (clientId: string) => {\n this.latestClientId = clientId;\n // If we have a summarizer, it should have been either cancelled on disconnected by now.\n // But because of lastSummary process, it can still hang around, so there is not much we can\n // check or assert.\n this.refreshSummarizer();\n };\n\n private readonly handleDisconnected = () => {\n this.refreshSummarizer();\n };\n\n private static readonly isStartingOrRunning = (state: SummaryManagerState) =>\n state === SummaryManagerState.Starting || state === SummaryManagerState.Running;\n\n private getShouldSummarizeState(): ShouldSummarizeState {\n // Note that if we're in the Running state, the electedClient may be a summarizer client, so we can't\n // enforce connectedState.clientId === clientElection.electedClientId. But once we're Running, we should\n // only transition to Stopping when the electedParentId changes. Stopping the summarizer without\n // changing the electedParent will just cause us to transition to Starting again.\n if (!this.connectedState.connected) {\n return { shouldSummarize: false, stopReason: \"parentNotConnected\" };\n } else if (this.connectedState.clientId !== this.clientElection.electedParentId ||\n (this.state !== SummaryManagerState.Running &&\n this.connectedState.clientId !== this.clientElection.electedClientId)) {\n return { shouldSummarize: false, stopReason: \"parentShouldNotSummarize\" };\n } else if (this.disposed) {\n assert(false, 0x260 /* \"Disposed should mean disconnected!\" */);\n } else {\n return { shouldSummarize: true };\n }\n }\n\n private readonly refreshSummarizer = () => {\n // Transition states depending on shouldSummarize, which is a calculated property\n // that is only true if this client is connected and is the elected summarizer.\n const shouldSummarizeState = this.getShouldSummarizeState();\n switch (this.state) {\n case SummaryManagerState.Off: {\n if (shouldSummarizeState.shouldSummarize) {\n this.startSummarization();\n }\n return;\n }\n case SummaryManagerState.Starting: {\n // Cannot take any action until summarizer is created\n // state transition will occur after creation\n return;\n }\n case SummaryManagerState.Running: {\n if (shouldSummarizeState.shouldSummarize === false) {\n this.stop(shouldSummarizeState.stopReason);\n }\n return;\n }\n case SummaryManagerState.Stopping: {\n // Cannot take any action until running summarizer finishes\n // state transition will occur after it stops\n return;\n }\n default: {\n return;\n }\n }\n };\n\n private startSummarization() {\n assert(this.state === SummaryManagerState.Off, 0x261 /* \"Expected: off\" */);\n this.state = SummaryManagerState.Starting;\n\n assert(this.summarizer === undefined, 0x262 /* \"Old summarizer is still working!\" */);\n\n let reason = \"unknown\";\n\n this.delayBeforeCreatingSummarizer().then(async (startWithInitialDelay: boolean) => {\n // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n // but only if creation was delayed. If it was not, then we want to ensure we always create\n // a summarizer to kick off lastSummary. Without that, we would not be able to summarize and get\n // document out of broken state if it has too many ops and ordering service keeps nacking main\n // container (and thus it goes into cycle of reconnects)\n if (startWithInitialDelay && this.getShouldSummarizeState().shouldSummarize === false) {\n return;\n }\n\n // We transition to Running before requesting the summarizer, because after requesting we can't predict\n // when the electedClient will be replaced with the new summarizer client.\n // The alternative would be to let connectedState.clientId !== clientElection.electedClientId when\n // state === Starting || state === Running.\n assert(this.state === SummaryManagerState.Starting, 0x263 /* \"Expected: starting\" */);\n this.state = SummaryManagerState.Running;\n\n const summarizer = await this.requestSummarizerFn();\n\n // Re-validate that it need to be running. Due to asynchrony, it may be not the case anymore\n const shouldSummarizeState = this.getShouldSummarizeState();\n if (shouldSummarizeState.shouldSummarize === false) {\n this.state = SummaryManagerState.Starting;\n summarizer.stop(shouldSummarizeState.stopReason);\n return;\n }\n\n this.summarizer = summarizer;\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const clientId = this.latestClientId!;\n\n reason = await PerformanceEvent.timedExecAsync(\n this.logger,\n { eventName: \"RunningSummarizer\", attempt: this.startThrottler.numAttempts },\n async () => summarizer.run(clientId, this.summarizerOptions),\n );\n }).catch((error) => {\n // Most of exceptions happen due to container being closed while loading it, due to\n // summarizer container loosing connection while load.\n // Not worth reporting such errors as errors. That said, we might miss some real errors if\n // we ignore blindly, so try to narrow signature we are looking for - skip logging\n // error only if this client should no longer be a summarizer (which in practice\n // means it also lost connection), and error happened on load (we do not have summarizer).\n // We could annotate the error raised in Container.load where the container closed during load with no error\n // and check for that case here, but that does not seem to be necessary.\n if (this.getShouldSummarizeState().shouldSummarize || this.summarizer !== undefined) {\n // Report any failure as an error unless it was due to cancellation (like \"disconnected\" error)\n // If failure happened on container load, we may not yet realized that socket disconnected, so check\n // offlineError.\n const category = error?.errorType === DriverErrorType.offlineError ? \"generic\" : \"error\";\n this.logger.sendTelemetryEvent(\n {\n eventName: \"SummarizerException\",\n category,\n },\n error);\n\n // Note that summarizer may keep going (like doing last summary).\n // Ideally we await stopping process, but this code path is due to a bug\n // that needs to be fixed either way.\n if (SummaryManager.isStartingOrRunning(this.state)) {\n this.stop(\"summarizerException\");\n }\n }\n }).finally(() => {\n assert(this.state !== SummaryManagerState.Off, 0x264 /* \"Expected: Not Off\" */);\n this.state = SummaryManagerState.Off;\n\n this.summarizer = undefined;\n\n this.logger.sendTelemetryEvent({\n eventName: \"EndingSummarizer\",\n reason,\n });\n\n if (this.getShouldSummarizeState().shouldSummarize) {\n this.startSummarization();\n }\n });\n }\n\n private stop(reason: SummarizerStopReason) {\n if (!SummaryManager.isStartingOrRunning(this.state)) {\n return;\n }\n this.state = SummaryManagerState.Stopping;\n\n // Stopping the running summarizer client should trigger a change\n // in states when the running summarizer closes\n this.summarizer?.stop(reason);\n }\n\n /**\n * Implements initial delay before creating summarizer\n * @returns true, if creation is delayed due to heuristics (not many ops to summarize).\n * False if summarizer should start immediately due to too many unsummarized ops.\n */\n private async delayBeforeCreatingSummarizer(): Promise<boolean> {\n // throttle creation of new summarizer containers to prevent spamming the server with websocket connections\n let delayMs = this.startThrottler.getDelay();\n\n // We have been elected the summarizer. Some day we may be able to summarize with a live document but for\n // now we play it safe and launch a second copy.\n this.logger.sendTelemetryEvent({\n eventName: \"CreatingSummarizer\",\n throttlerDelay: delayMs,\n initialDelay: this.initialDelayMs,\n startThrottlerMaxDelayMs: this.startThrottler.maxDelayMs,\n opsSinceLastAck: this.summaryCollection.opsSinceLastAck,\n opsToBypassInitialDelay: this.opsToBypassInitialDelay,\n });\n\n // This delay helps ensure that last summarizer that might be left from previous client\n // has enough time to complete its last summary and thus new summarizer not conflict with previous one.\n // If, however, there are too many unsummarized ops, try to resolve it as quickly as possible, with\n // understanding that we may see nacks because of such quick action.\n // A better design would be for summarizer election logic to always select current summarizer as\n // summarizing client (i.e. clientType === \"summarizer\" can be elected) to ensure that nobody else can\n // summarizer while it finishes its work and moves to exit.\n // It also helps with pure boot scenario (single client) to offset expensive work a bit out from\n // critical boot sequence.\n let startWithInitialDelay = false;\n if (this.summaryCollection.opsSinceLastAck < this.opsToBypassInitialDelay) {\n startWithInitialDelay = true;\n delayMs = Math.max(delayMs, this.initialDelayMs);\n }\n\n if (delayMs > 0) {\n let timer;\n let resolveOpPromiseFn;\n // Create a listener that will break the delay if we've exceeded the initial delay ops count.\n const opsListenerFn = () => {\n if (this.summaryCollection.opsSinceLastAck >= this.opsToBypassInitialDelay) {\n clearTimeout(timer);\n resolveOpPromiseFn();\n }\n };\n // Create a Promise that will resolve when the delay expires.\n const delayPromise = new Promise<void>((resolve) => {\n timer = setTimeout(() => resolve(), delayMs);\n });\n // Create a Promise that will resolve if the ops count passes the threshold.\n const opPromise = new Promise<void>((resolve) => { resolveOpPromiseFn = resolve; });\n this.summaryCollection.addOpListener(opsListenerFn);\n await Promise.race([ delayPromise, opPromise ]);\n this.summaryCollection.removeOpListener(opsListenerFn);\n }\n return startWithInitialDelay;\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n if (this.summarizer === undefined) {\n throw Error(\"No running summarizer client\");\n // TODO: could spawn a summarizer client temporarily.\n }\n return this.summarizer.summarizeOnDemand(...args);\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this.summarizer === undefined) {\n throw Error(\"No running summarizer client\");\n // TODO: could spawn a summarizer client temporarily.\n }\n return this.summarizer.enqueueSummarize(...args);\n };\n\n public dispose() {\n this.clientElection.off(\"electedSummarizerChanged\", this.refreshSummarizer);\n this.connectedState.off(\"connected\", this.handleConnected);\n this.connectedState.off(\"disconnected\", this.handleDisconnected);\n this._disposed = true;\n }\n}\n"]}
@@ -4,9 +4,10 @@
4
4
  */
5
5
  import { IFluidHandle, IFluidHandleContext } from "@fluidframework/core-interfaces";
6
6
  import { IDocumentStorageService } from "@fluidframework/driver-definitions";
7
- import { ISnapshotTree, ITree } from "@fluidframework/protocol-definitions";
7
+ import { ISnapshotTree } from "@fluidframework/protocol-definitions";
8
8
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
9
9
  import { IContainerRuntime } from "@fluidframework/container-runtime-definitions";
10
+ import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
10
11
  /**
11
12
  * This class represents blob (long string)
12
13
  * This object is used only when creating (writing) new blob and serialization purposes.
@@ -69,7 +70,7 @@ export declare class BlobManager {
69
70
  * attachment types returned in snapshot() with blobs.
70
71
  */
71
72
  private load;
72
- snapshot(): ITree;
73
+ summarize(): ISummaryTreeWithStats;
73
74
  setRedirectTable(table: Map<string, string>): void;
74
75
  }
75
76
  //# sourceMappingURL=blobManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,OAAO,EAAE,aAAa,EAAE,KAAK,EAAc,MAAM,sCAAsC,CAAC;AAExF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAGlF;;;;;;GAMG;AACH,qBAAa,UAAW,YAAW,YAAY,CAAC,eAAe,CAAC;aAYxC,IAAI,EAAE,MAAM;aACZ,YAAY,EAAE,mBAAmB;IAC1C,GAAG,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC;IAblC,OAAO,CAAC,QAAQ,CAAkB;IAElC,IAAW,YAAY,IAAI,YAAY,CAAiB;IAExD,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,SAAgB,YAAY,EAAE,MAAM,CAAC;gBAGjB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,mBAAmB,EAC1C,GAAG,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC;IAK3B,WAAW;IAIX,IAAI,CAAC,MAAM,EAAE,YAAY;CAGnC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CACtC;AAED,qBAAa,WAAW;IAchB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAlB3B,gBAAuB,QAAQ,YAAY;IAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAoB;IAEjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAGlD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0C;IAEzE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAE1D,OAAO,CAAC,aAAa,CAAkC;gBAGlC,YAAY,EAAE,mBAAmB,EAClD,QAAQ,EAAE,oBAAoB,EACb,UAAU,EAAE,MAAM,uBAAuB,EACzC,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAC5C,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,gBAAgB;IAU7C,OAAO,CAAC,OAAO;IAIF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAsB/D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAmC/E,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;IAOzD;;OAEG;WACiB,IAAI,CACpB,SAAS,EAAE,aAAa,GAAG,SAAS,EACpC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAC1D,OAAO,CAAC,oBAAoB,CAAC;IAchC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,IAAI;IAeL,QAAQ,IAAI,KAAK;IAejB,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;CAWrD"}
1
+ {"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAErE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAElF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAE5E;;;;;;GAMG;AACH,qBAAa,UAAW,YAAW,YAAY,CAAC,eAAe,CAAC;aAYxC,IAAI,EAAE,MAAM;aACZ,YAAY,EAAE,mBAAmB;IAC1C,GAAG,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC;IAblC,OAAO,CAAC,QAAQ,CAAkB;IAElC,IAAW,YAAY,IAAI,YAAY,CAAiB;IAExD,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,SAAgB,YAAY,EAAE,MAAM,CAAC;gBAGjB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,mBAAmB,EAC1C,GAAG,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC;IAK3B,WAAW;IAIX,IAAI,CAAC,MAAM,EAAE,YAAY;CAGnC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CACtC;AAED,qBAAa,WAAW;IAchB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAlB3B,gBAAuB,QAAQ,YAAY;IAC3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAoB;IAEjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAGlD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0C;IAEzE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;IAE1D,OAAO,CAAC,aAAa,CAAkC;gBAGlC,YAAY,EAAE,mBAAmB,EAClD,QAAQ,EAAE,oBAAoB,EACb,UAAU,EAAE,MAAM,uBAAuB,EACzC,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAC5C,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,gBAAgB;IAU7C,OAAO,CAAC,OAAO;IAIF,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAsB/D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAmC/E,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;IAUzD;;OAEG;WACiB,IAAI,CACpB,SAAS,EAAE,aAAa,GAAG,SAAS,EACpC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAC1D,OAAO,CAAC,oBAAoB,CAAC;IAchC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,IAAI;IAeL,SAAS,IAAI,qBAAqB;IAoBlC,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;CAWrD"}
@@ -2,8 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { AttachmentTreeEntry, BlobTreeEntry } from "@fluidframework/protocol-base";
6
- import { generateHandleContextPath } from "@fluidframework/runtime-utils";
5
+ import { generateHandleContextPath, SummaryTreeBuilder } from "@fluidframework/runtime-utils";
7
6
  import { assert, Deferred } from "@fluidframework/common-utils";
8
7
  import { AttachState } from "@fluidframework/container-definitions";
9
8
  /**
@@ -99,10 +98,12 @@ export class BlobManager {
99
98
  return handle;
100
99
  }
101
100
  processBlobAttachOp(blobId, local) {
102
- var _a;
103
- assert(!local || this.pendingBlobIds.has(blobId), 0x1f8 /* "local BlobAttach op with no pending blob" */);
104
- (_a = this.pendingBlobIds.get(blobId)) === null || _a === void 0 ? void 0 : _a.resolve();
105
- this.pendingBlobIds.delete(blobId);
101
+ if (local) {
102
+ const pendingBlobP = this.pendingBlobIds.get(blobId);
103
+ assert(pendingBlobP !== undefined, 0x1f8 /* "local BlobAttach op with no pending blob" */);
104
+ pendingBlobP.resolve();
105
+ this.pendingBlobIds.delete(blobId);
106
+ }
106
107
  this.blobIds.add(blobId);
107
108
  }
108
109
  /**
@@ -150,16 +151,19 @@ export class BlobManager {
150
151
  redirectTable: (_c = snapshot.redirectTable) === null || _c === void 0 ? void 0 : _c.length,
151
152
  });
152
153
  }
153
- snapshot() {
154
+ summarize() {
154
155
  // If we have a redirect table it means the container is about to transition to "Attaching" state, so we need
155
156
  // to return an actual snapshot containing all the real storage IDs we know about.
156
157
  const attachingOrAttached = !!this.redirectTable || this.runtime.attachState !== AttachState.Detached;
157
158
  const blobIds = attachingOrAttached ? this.blobIds : this.detachedBlobIds;
158
- const entries = [...blobIds].map((id) => new AttachmentTreeEntry(id, id));
159
+ const builder = new SummaryTreeBuilder();
160
+ blobIds.forEach((blobId) => {
161
+ builder.addAttachment(blobId);
162
+ });
159
163
  if (this.redirectTable && this.redirectTable.size > 0) {
160
- entries.push(new BlobTreeEntry(BlobManager.redirectTableBlobName, JSON.stringify(Array.from(this.redirectTable.entries()))));
164
+ builder.addBlob(BlobManager.redirectTableBlobName, JSON.stringify(Array.from(this.redirectTable.entries())));
161
165
  }
162
- return { entries };
166
+ return builder.getSummaryTree();
163
167
  }
164
168
  setRedirectTable(table) {
165
169
  assert(this.runtime.attachState === AttachState.Detached, 0x252 /* "redirect table can only be set in detached container" */);
@@ -1 +1 @@
1
- {"version":3,"file":"blobManager.js","sourceRoot":"","sources":["../src/blobManager.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 { IFluidHandle, IFluidHandleContext } from \"@fluidframework/core-interfaces\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { AttachmentTreeEntry, BlobTreeEntry } from \"@fluidframework/protocol-base\";\nimport { ISnapshotTree, ITree, ITreeEntry } from \"@fluidframework/protocol-definitions\";\nimport { generateHandleContextPath } from \"@fluidframework/runtime-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\nimport { IContainerRuntime } from \"@fluidframework/container-runtime-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\n\n/**\n * This class represents blob (long string)\n * This object is used only when creating (writing) new blob and serialization purposes.\n * De-serialization process goes through FluidObjectHandle and request flow:\n * DataObject.request() recognizes requests in the form of `/blobs/<id>`\n * and loads blob.\n */\nexport class BlobHandle implements IFluidHandle<ArrayBufferLike> {\n private attached: boolean = false;\n\n public get IFluidHandle(): IFluidHandle { return this; }\n\n public get isAttached(): boolean {\n return this.attached;\n }\n\n public readonly absolutePath: string;\n\n constructor(\n public readonly path: string,\n public readonly routeContext: IFluidHandleContext,\n public get: () => Promise<any>,\n ) {\n this.absolutePath = generateHandleContextPath(path, this.routeContext);\n }\n\n public attachGraph() {\n this.attached = true;\n }\n\n public bind(handle: IFluidHandle) {\n throw new Error(\"Cannot bind to blob handle\");\n }\n}\n\n/**\n * Information from a snapshot needed to load BlobManager\n */\nexport interface IBlobManagerLoadInfo {\n ids?: string[],\n redirectTable?: [string, string][],\n}\n\nexport class BlobManager {\n public static readonly basePath = \"_blobs\";\n private static readonly redirectTableBlobName = \".redirectTable\";\n // uploaded blob IDs\n private readonly blobIds: Set<string> = new Set();\n // blobs for which upload is pending. maps to a promise that will resolve once the blob has been uploaded and a\n // BlobAttach op has round-tripped.\n private readonly pendingBlobIds: Map<string, Deferred<void>> = new Map();\n // blobs uploaded while detached; cleared upon attach\n private readonly detachedBlobIds: Set<string> = new Set();\n // map of detached blob IDs to IDs used by storage. used to support blob handles given out while detached\n private redirectTable: Map<string, string> | undefined;\n\n constructor(\n private readonly routeContext: IFluidHandleContext,\n snapshot: IBlobManagerLoadInfo,\n private readonly getStorage: () => IDocumentStorageService,\n private readonly attachBlobCallback: (blobId: string) => void,\n private readonly runtime: IContainerRuntime,\n private readonly logger: ITelemetryLogger,\n ) {\n this.runtime.once(\"dispose\", () => {\n for (const promise of this.pendingBlobIds.values()) {\n promise.reject(new Error(\"runtime disposed while blobAttach op in flight\"));\n }\n });\n this.load(snapshot);\n }\n\n private hasBlob(id: string): boolean {\n return this.blobIds.has(id) || this.detachedBlobIds.has(id);\n }\n\n public async getBlob(blobId: string): Promise<IFluidHandle<ArrayBufferLike>> {\n const storageId = this.redirectTable?.get(blobId) ?? blobId;\n assert(this.hasBlob(storageId), 0x11f /* \"requesting unknown blobs\" */);\n\n return new BlobHandle(\n `${BlobManager.basePath}/${storageId}`,\n this.routeContext,\n async () => {\n return this.getStorage().readBlob(storageId).catch((error) => {\n this.logger.sendErrorEvent(\n {\n eventName:\"AttachmentReadBlobError\",\n id: storageId,\n },\n error,\n );\n throw error;\n });\n },\n );\n }\n\n public async createBlob(blob: ArrayBufferLike): Promise<IFluidHandle<ArrayBufferLike>> {\n if (this.runtime.attachState === AttachState.Attaching) {\n // blob upload is not supported in \"Attaching\" state\n this.logger.sendTelemetryEvent({ eventName: \"CreateBlobWhileAttaching\" });\n await new Promise<void>((resolve) => this.runtime.once(\"attached\", resolve));\n }\n\n const response = await this.getStorage().createBlob(blob);\n const handle = new BlobHandle(\n `${BlobManager.basePath}/${response.id}`,\n this.routeContext,\n // get() should go through BlobManager.getBlob() so handles created while detached can be redirected\n // to the correct storage id after they are uploaded\n async () => this.getBlob(response.id).then(async (h) => h.get()),\n );\n\n if (this.runtime.attachState === AttachState.Detached) {\n this.detachedBlobIds.add(response.id);\n return handle;\n }\n\n // Note - server will de-dup blobs, so we might get existing blobId!\n if (this.pendingBlobIds.has(response.id)) {\n await this.pendingBlobIds.get(response.id)?.promise;\n } else if (!this.blobIds.has(response.id)) {\n this.pendingBlobIds.set(response.id, new Deferred<void>());\n\n // send blob attach op and wait until we see it to return the handle\n this.attachBlobCallback(response.id);\n await this.pendingBlobIds.get(response.id)?.promise;\n }\n\n return handle;\n }\n\n public processBlobAttachOp(blobId: string, local: boolean) {\n assert(!local || this.pendingBlobIds.has(blobId), 0x1f8 /* \"local BlobAttach op with no pending blob\" */);\n this.pendingBlobIds.get(blobId)?.resolve();\n this.pendingBlobIds.delete(blobId);\n this.blobIds.add(blobId);\n }\n\n /**\n * Reads blobs needed to load BlobManager from storage.\n */\n public static async load(\n blobsTree: ISnapshotTree | undefined,\n tryFetchBlob: (id: string) => Promise<[string, string][]>,\n ): Promise<IBlobManagerLoadInfo> {\n if (!blobsTree) {\n return {};\n }\n let redirectTable;\n const tableId = blobsTree.blobs[this.redirectTableBlobName];\n if (tableId) {\n redirectTable = await tryFetchBlob(tableId);\n }\n const ids = Object.entries(blobsTree.blobs)\n .filter(([k, _]) => k !== this.redirectTableBlobName).map(([_, v]) => v);\n return { ids, redirectTable };\n }\n\n /**\n * Load a set of previously attached blob IDs from a previous snapshot. Note\n * that BlobManager tracking and reporting attached blobs is a temporary\n * solution since storage expects attached blobs to be reported and any that\n * are not reported as attached may be GCed. In the future attached blob\n * IDs will be collected at summarization time, and runtime will not care\n * about the existence or specific formatting of this tree in returned\n * snapshots.\n *\n * @param blobsTree - Tree containing IDs of previously attached blobs. This\n * corresponds to snapshot() below. We look for the IDs in the blob entries\n * of the tree since the both the r11s and SPO drivers replace the\n * attachment types returned in snapshot() with blobs.\n */\n private load(snapshot: IBlobManagerLoadInfo): void {\n if (snapshot.ids) {\n const detached = this.runtime.attachState === AttachState.Detached;\n snapshot.ids.map((entry) => detached ? this.detachedBlobIds.add(entry) : this.blobIds.add(entry));\n }\n if (snapshot.redirectTable) {\n this.redirectTable = new Map(snapshot.redirectTable);\n }\n this.logger.sendTelemetryEvent({\n eventName: \"AttachmentBlobsLoaded\",\n count: snapshot.ids?.length ?? 0,\n redirectTable: snapshot.redirectTable?.length,\n });\n }\n\n public snapshot(): ITree {\n // If we have a redirect table it means the container is about to transition to \"Attaching\" state, so we need\n // to return an actual snapshot containing all the real storage IDs we know about.\n const attachingOrAttached = !!this.redirectTable || this.runtime.attachState !== AttachState.Detached;\n const blobIds = attachingOrAttached ? this.blobIds : this.detachedBlobIds;\n const entries: ITreeEntry[] = [...blobIds].map((id) => new AttachmentTreeEntry(id, id));\n if (this.redirectTable && this.redirectTable.size > 0) {\n entries.push(new BlobTreeEntry(\n BlobManager.redirectTableBlobName,\n JSON.stringify(Array.from(this.redirectTable.entries()))),\n );\n }\n return { entries };\n }\n\n public setRedirectTable(table: Map<string, string>) {\n assert(this.runtime.attachState === AttachState.Detached,\n 0x252 /* \"redirect table can only be set in detached container\" */);\n assert(!this.redirectTable, 0x253 /* \"redirect table already exists\" */);\n for (const [localId, storageId] of table) {\n assert(this.detachedBlobIds.delete(localId), 0x254 /* \"unrecognized id in redirect table\" */);\n this.blobIds.add(storageId);\n }\n assert(this.detachedBlobIds.size === 0, 0x255 /* \"detached blob id absent in redirect table\" */);\n this.redirectTable = table;\n }\n}\n"]}
1
+ {"version":3,"file":"blobManager.js","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAE9F,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAGpE;;;;;;GAMG;AACH,MAAM,OAAO,UAAU;IAWnB,YACoB,IAAY,EACZ,YAAiC,EAC1C,GAAuB;QAFd,SAAI,GAAJ,IAAI,CAAQ;QACZ,iBAAY,GAAZ,YAAY,CAAqB;QAC1C,QAAG,GAAH,GAAG,CAAoB;QAb1B,aAAQ,GAAY,KAAK,CAAC;QAe9B,IAAI,CAAC,YAAY,GAAG,yBAAyB,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3E,CAAC;IAdD,IAAW,YAAY,KAAmB,OAAO,IAAI,CAAC,CAAC,CAAC;IAExD,IAAW,UAAU;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAYM,WAAW;QACd,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACzB,CAAC;IAEM,IAAI,CAAC,MAAoB;QAC5B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAClD,CAAC;CACJ;AAUD,MAAM,OAAO,WAAW;IAapB,YACqB,YAAiC,EAClD,QAA8B,EACb,UAAyC,EACzC,kBAA4C,EAC5C,OAA0B,EAC1B,MAAwB;QALxB,iBAAY,GAAZ,YAAY,CAAqB;QAEjC,eAAU,GAAV,UAAU,CAA+B;QACzC,uBAAkB,GAAlB,kBAAkB,CAA0B;QAC5C,YAAO,GAAP,OAAO,CAAmB;QAC1B,WAAM,GAAN,MAAM,CAAkB;QAhB7C,oBAAoB;QACH,YAAO,GAAgB,IAAI,GAAG,EAAE,CAAC;QAClD,+GAA+G;QAC/G,mCAAmC;QAClB,mBAAc,GAAgC,IAAI,GAAG,EAAE,CAAC;QACzE,qDAAqD;QACpC,oBAAe,GAAgB,IAAI,GAAG,EAAE,CAAC;QAYtD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;YAC9B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE;gBAChD,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC,CAAC;aAC/E;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IAEO,OAAO,CAAC,EAAU;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,MAAc;;QAC/B,MAAM,SAAS,eAAG,IAAI,CAAC,aAAa,0CAAE,GAAG,CAAC,MAAM,oCAAK,MAAM,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAExE,OAAO,IAAI,UAAU,CACjB,GAAG,WAAW,CAAC,QAAQ,IAAI,SAAS,EAAE,EACtC,IAAI,CAAC,YAAY,EACjB,KAAK,IAAI,EAAE;YACP,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;gBACzD,IAAI,CAAC,MAAM,CAAC,cAAc,CACtB;oBACI,SAAS,EAAC,yBAAyB;oBACnC,EAAE,EAAE,SAAS;iBAChB,EACD,KAAK,CACR,CAAC;gBACF,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,CAAC;QACP,CAAC,CACJ,CAAC;IACN,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,IAAqB;;QACzC,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,WAAW,CAAC,SAAS,EAAE;YACpD,oDAAoD;YACpD,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,SAAS,EAAE,0BAA0B,EAAE,CAAC,CAAC;YAC1E,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;SAChF;QAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,UAAU,CACzB,GAAG,WAAW,CAAC,QAAQ,IAAI,QAAQ,CAAC,EAAE,EAAE,EACxC,IAAI,CAAC,YAAY;QACjB,oGAAoG;QACpG,oDAAoD;QACpD,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CACnE,CAAC;QAEF,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,WAAW,CAAC,QAAQ,EAAE;YACnD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACtC,OAAO,MAAM,CAAC;SACjB;QAED,oEAAoE;QACpE,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;YACtC,aAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,0CAAE,OAAO,CAAA,CAAC;SACvD;aAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;YACvC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,QAAQ,EAAQ,CAAC,CAAC;YAE3D,oEAAoE;YACpE,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACrC,aAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,0CAAE,OAAO,CAAA,CAAC;SACvD;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAEM,mBAAmB,CAAC,MAAc,EAAE,KAAc;QACrD,IAAI,KAAK,EAAE;YACP,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACrD,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,KAAK,CAAC,gDAAgD,CAAC,CAAC;YAC3F,YAAY,CAAC,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;SACtC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,IAAI,CACpB,SAAoC,EACpC,YAAyD;QAEzD,IAAI,CAAC,SAAS,EAAE;YACZ,OAAO,EAAE,CAAC;SACb;QACD,IAAI,aAAa,CAAC;QAClB,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC5D,IAAI,OAAO,EAAE;YACT,aAAa,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;SAC/C;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC;aACtC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,qBAAqB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7E,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC;IAClC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACK,IAAI,CAAC,QAA8B;;QACvC,IAAI,QAAQ,CAAC,GAAG,EAAE;YACd,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,WAAW,CAAC,QAAQ,CAAC;YACnE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;SACrG;QACD,IAAI,QAAQ,CAAC,aAAa,EAAE;YACxB,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;SACxD;QACD,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC3B,SAAS,EAAE,uBAAuB;YAClC,KAAK,cAAE,QAAQ,CAAC,GAAG,0CAAE,MAAM,mCAAI,CAAC;YAChC,aAAa,QAAE,QAAQ,CAAC,aAAa,0CAAE,MAAM;SAChD,CAAC,CAAC;IACP,CAAC;IAEM,SAAS;QACZ,6GAA6G;QAC7G,kFAAkF;QAClF,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,WAAW,CAAC,QAAQ,CAAC;QACtG,MAAM,OAAO,GAAG,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC;QAC1E,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACzC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACvB,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE;YACnD,OAAO,CAAC,OAAO,CACX,WAAW,CAAC,qBAAqB,EACjC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAC3D,CAAC;SACL;QAED,OAAO,OAAO,CAAC,cAAc,EAAE,CAAC;IACpC,CAAC;IAEM,gBAAgB,CAAC,KAA0B;QAC9C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,WAAW,CAAC,QAAQ,EACpD,KAAK,CAAC,4DAA4D,CAAC,CAAC;QACxE,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzE,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,KAAK,EAAE;YACtC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,yCAAyC,CAAC,CAAC;YAC9F,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;SAC/B;QACD,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC,EAAE,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjG,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;IAC/B,CAAC;;AAlLsB,oBAAQ,GAAG,QAAQ,CAAC;AACnB,iCAAqB,GAAG,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidHandle, IFluidHandleContext } from \"@fluidframework/core-interfaces\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { generateHandleContextPath, SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, Deferred } from \"@fluidframework/common-utils\";\nimport { IContainerRuntime } from \"@fluidframework/container-runtime-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\n\n/**\n * This class represents blob (long string)\n * This object is used only when creating (writing) new blob and serialization purposes.\n * De-serialization process goes through FluidObjectHandle and request flow:\n * DataObject.request() recognizes requests in the form of `/blobs/<id>`\n * and loads blob.\n */\nexport class BlobHandle implements IFluidHandle<ArrayBufferLike> {\n private attached: boolean = false;\n\n public get IFluidHandle(): IFluidHandle { return this; }\n\n public get isAttached(): boolean {\n return this.attached;\n }\n\n public readonly absolutePath: string;\n\n constructor(\n public readonly path: string,\n public readonly routeContext: IFluidHandleContext,\n public get: () => Promise<any>,\n ) {\n this.absolutePath = generateHandleContextPath(path, this.routeContext);\n }\n\n public attachGraph() {\n this.attached = true;\n }\n\n public bind(handle: IFluidHandle) {\n throw new Error(\"Cannot bind to blob handle\");\n }\n}\n\n/**\n * Information from a snapshot needed to load BlobManager\n */\nexport interface IBlobManagerLoadInfo {\n ids?: string[],\n redirectTable?: [string, string][],\n}\n\nexport class BlobManager {\n public static readonly basePath = \"_blobs\";\n private static readonly redirectTableBlobName = \".redirectTable\";\n // uploaded blob IDs\n private readonly blobIds: Set<string> = new Set();\n // blobs for which upload is pending. maps to a promise that will resolve once the blob has been uploaded and a\n // BlobAttach op has round-tripped.\n private readonly pendingBlobIds: Map<string, Deferred<void>> = new Map();\n // blobs uploaded while detached; cleared upon attach\n private readonly detachedBlobIds: Set<string> = new Set();\n // map of detached blob IDs to IDs used by storage. used to support blob handles given out while detached\n private redirectTable: Map<string, string> | undefined;\n\n constructor(\n private readonly routeContext: IFluidHandleContext,\n snapshot: IBlobManagerLoadInfo,\n private readonly getStorage: () => IDocumentStorageService,\n private readonly attachBlobCallback: (blobId: string) => void,\n private readonly runtime: IContainerRuntime,\n private readonly logger: ITelemetryLogger,\n ) {\n this.runtime.once(\"dispose\", () => {\n for (const promise of this.pendingBlobIds.values()) {\n promise.reject(new Error(\"runtime disposed while blobAttach op in flight\"));\n }\n });\n this.load(snapshot);\n }\n\n private hasBlob(id: string): boolean {\n return this.blobIds.has(id) || this.detachedBlobIds.has(id);\n }\n\n public async getBlob(blobId: string): Promise<IFluidHandle<ArrayBufferLike>> {\n const storageId = this.redirectTable?.get(blobId) ?? blobId;\n assert(this.hasBlob(storageId), 0x11f /* \"requesting unknown blobs\" */);\n\n return new BlobHandle(\n `${BlobManager.basePath}/${storageId}`,\n this.routeContext,\n async () => {\n return this.getStorage().readBlob(storageId).catch((error) => {\n this.logger.sendErrorEvent(\n {\n eventName:\"AttachmentReadBlobError\",\n id: storageId,\n },\n error,\n );\n throw error;\n });\n },\n );\n }\n\n public async createBlob(blob: ArrayBufferLike): Promise<IFluidHandle<ArrayBufferLike>> {\n if (this.runtime.attachState === AttachState.Attaching) {\n // blob upload is not supported in \"Attaching\" state\n this.logger.sendTelemetryEvent({ eventName: \"CreateBlobWhileAttaching\" });\n await new Promise<void>((resolve) => this.runtime.once(\"attached\", resolve));\n }\n\n const response = await this.getStorage().createBlob(blob);\n const handle = new BlobHandle(\n `${BlobManager.basePath}/${response.id}`,\n this.routeContext,\n // get() should go through BlobManager.getBlob() so handles created while detached can be redirected\n // to the correct storage id after they are uploaded\n async () => this.getBlob(response.id).then(async (h) => h.get()),\n );\n\n if (this.runtime.attachState === AttachState.Detached) {\n this.detachedBlobIds.add(response.id);\n return handle;\n }\n\n // Note - server will de-dup blobs, so we might get existing blobId!\n if (this.pendingBlobIds.has(response.id)) {\n await this.pendingBlobIds.get(response.id)?.promise;\n } else if (!this.blobIds.has(response.id)) {\n this.pendingBlobIds.set(response.id, new Deferred<void>());\n\n // send blob attach op and wait until we see it to return the handle\n this.attachBlobCallback(response.id);\n await this.pendingBlobIds.get(response.id)?.promise;\n }\n\n return handle;\n }\n\n public processBlobAttachOp(blobId: string, local: boolean) {\n if (local) {\n const pendingBlobP = this.pendingBlobIds.get(blobId);\n assert(pendingBlobP !== undefined, 0x1f8 /* \"local BlobAttach op with no pending blob\" */);\n pendingBlobP.resolve();\n this.pendingBlobIds.delete(blobId);\n }\n this.blobIds.add(blobId);\n }\n\n /**\n * Reads blobs needed to load BlobManager from storage.\n */\n public static async load(\n blobsTree: ISnapshotTree | undefined,\n tryFetchBlob: (id: string) => Promise<[string, string][]>,\n ): Promise<IBlobManagerLoadInfo> {\n if (!blobsTree) {\n return {};\n }\n let redirectTable;\n const tableId = blobsTree.blobs[this.redirectTableBlobName];\n if (tableId) {\n redirectTable = await tryFetchBlob(tableId);\n }\n const ids = Object.entries(blobsTree.blobs)\n .filter(([k, _]) => k !== this.redirectTableBlobName).map(([_, v]) => v);\n return { ids, redirectTable };\n }\n\n /**\n * Load a set of previously attached blob IDs from a previous snapshot. Note\n * that BlobManager tracking and reporting attached blobs is a temporary\n * solution since storage expects attached blobs to be reported and any that\n * are not reported as attached may be GCed. In the future attached blob\n * IDs will be collected at summarization time, and runtime will not care\n * about the existence or specific formatting of this tree in returned\n * snapshots.\n *\n * @param blobsTree - Tree containing IDs of previously attached blobs. This\n * corresponds to snapshot() below. We look for the IDs in the blob entries\n * of the tree since the both the r11s and SPO drivers replace the\n * attachment types returned in snapshot() with blobs.\n */\n private load(snapshot: IBlobManagerLoadInfo): void {\n if (snapshot.ids) {\n const detached = this.runtime.attachState === AttachState.Detached;\n snapshot.ids.map((entry) => detached ? this.detachedBlobIds.add(entry) : this.blobIds.add(entry));\n }\n if (snapshot.redirectTable) {\n this.redirectTable = new Map(snapshot.redirectTable);\n }\n this.logger.sendTelemetryEvent({\n eventName: \"AttachmentBlobsLoaded\",\n count: snapshot.ids?.length ?? 0,\n redirectTable: snapshot.redirectTable?.length,\n });\n }\n\n public summarize(): ISummaryTreeWithStats {\n // If we have a redirect table it means the container is about to transition to \"Attaching\" state, so we need\n // to return an actual snapshot containing all the real storage IDs we know about.\n const attachingOrAttached = !!this.redirectTable || this.runtime.attachState !== AttachState.Detached;\n const blobIds = attachingOrAttached ? this.blobIds : this.detachedBlobIds;\n const builder = new SummaryTreeBuilder();\n blobIds.forEach((blobId) => {\n builder.addAttachment(blobId);\n });\n\n if (this.redirectTable && this.redirectTable.size > 0) {\n builder.addBlob(\n BlobManager.redirectTableBlobName,\n JSON.stringify(Array.from(this.redirectTable.entries())),\n );\n }\n\n return builder.getSummaryTree();\n }\n\n public setRedirectTable(table: Map<string, string>) {\n assert(this.runtime.attachState === AttachState.Detached,\n 0x252 /* \"redirect table can only be set in detached container\" */);\n assert(!this.redirectTable, 0x253 /* \"redirect table already exists\" */);\n for (const [localId, storageId] of table) {\n assert(this.detachedBlobIds.delete(localId), 0x254 /* \"unrecognized id in redirect table\" */);\n this.blobIds.add(storageId);\n }\n assert(this.detachedBlobIds.size === 0, 0x255 /* \"detached blob id absent in redirect table\" */);\n this.redirectTable = table;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"connectionTelemetry.d.ts","sourceRoot":"","sources":["../src/connectionTelemetry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EACH,gBAAgB,EAChB,yBAAyB,EAC5B,MAAM,sCAAsC,CAAC;AAG9C;;GAEG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAyJrC,wBAAgB,qBAAqB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,EACxE,MAAM,EAAE,gBAAgB,QAE3B"}
1
+ {"version":3,"file":"connectionTelemetry.d.ts","sourceRoot":"","sources":["../src/connectionTelemetry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AACtE,OAAO,EACH,gBAAgB,EAChB,yBAAyB,EAE5B,MAAM,sCAAsC,CAAC;AAG9C;;GAEG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAmPrC,wBAAgB,qBAAqB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,EACxE,MAAM,EAAE,gBAAgB,QAE3B"}
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ChildLogger, TelemetryLogger } from "@fluidframework/telemetry-utils";
6
+ import { MessageType, } from "@fluidframework/protocol-definitions";
6
7
  import { assert, performance } from "@fluidframework/common-utils";
7
8
  /**
8
9
  * We report various latency-related errors when waiting for op roundtrip takes longer than that amout of time.
@@ -13,6 +14,10 @@ class OpPerfTelemetry {
13
14
  this.clientId = clientId;
14
15
  this.deltaManager = deltaManager;
15
16
  this.pongCount = 0;
17
+ this.msnTrackingTimestamp = 0;
18
+ this.opProcessingTimes = {};
19
+ // Performance Data to be reported for ops round trips and processing.
20
+ this.opPerfData = {};
16
21
  this.firstConnection = true;
17
22
  this.bootTime = performance.now();
18
23
  this.connectionStartTime = 0;
@@ -34,11 +39,39 @@ class OpPerfTelemetry {
34
39
  }
35
40
  });
36
41
  this.deltaManager.on("disconnect", () => {
37
- this.opSendTimeForLatencyStatisticsForMsnStatistics = undefined;
42
+ this.sequenceNumberForMsnTracking = undefined;
38
43
  this.clientSequenceNumberForLatencyStatistics = undefined;
44
+ this.opProcessingTimes = {};
45
+ this.opPerfData = {};
39
46
  this.connectionOpSeqNumber = undefined;
40
47
  this.firstConnection = false;
41
48
  });
49
+ this.deltaManager.outbound.on("push", (messages) => {
50
+ for (const msg of messages) {
51
+ if (msg.type === MessageType.Operation &&
52
+ this.clientSequenceNumberForLatencyStatistics === msg.clientSequenceNumber) {
53
+ assert(this.opProcessingTimes.opStartTimeSittingInboundQueue === undefined, "opStartTimeSittingInboundQueue should be undefined");
54
+ assert(this.opPerfData.durationInboundQueue === undefined, "durationInboundQueue should be undefined");
55
+ this.opProcessingTimes.opStartTimeSittingInboundQueue = Date.now();
56
+ assert(this.opPerfData.durationOutboundQueue === undefined, "durationOutboundQueue should be undefined");
57
+ assert(this.opProcessingTimes.opStartTimeForLatencyStatistics !== undefined, "opStartTimeForLatencyStatistics should be undefined");
58
+ this.opPerfData.durationOutboundQueue = this.opProcessingTimes.opStartTimeSittingInboundQueue
59
+ - this.opProcessingTimes.opStartTimeForLatencyStatistics;
60
+ }
61
+ }
62
+ });
63
+ this.deltaManager.inbound.on("push", (message) => {
64
+ if (this.clientId === message.clientId &&
65
+ message.type === MessageType.Operation &&
66
+ this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber &&
67
+ this.opProcessingTimes.opStartTimeSittingInboundQueue !== undefined) {
68
+ this.opProcessingTimes.opStartTimeInboundPushEvent = Date.now();
69
+ this.opPerfData.durationInboundQueue = this.opProcessingTimes.opStartTimeInboundPushEvent
70
+ - this.opProcessingTimes.opStartTimeSittingInboundQueue;
71
+ this.opProcessingTimes.opStartTimeSittingInboundQueue = undefined;
72
+ this.opPerfData.lenghtInboundQueue = this.deltaManager.inbound.length;
73
+ }
74
+ });
42
75
  this.deltaManager.inbound.on("idle", (count, duration) => {
43
76
  // Do not want to log zero for sure.
44
77
  // We are more interested in aggregates, so logging only if we are processing some number of ops
@@ -82,8 +115,11 @@ class OpPerfTelemetry {
82
115
  }
83
116
  beforeOpSubmit(message) {
84
117
  // start with first client op and measure latency every 500 client ops
85
- if (this.clientSequenceNumberForLatencyStatistics === undefined && message.clientSequenceNumber % 500 === 1) {
86
- this.opSendTimeForLatencyStatistics = Date.now();
118
+ if (this.clientSequenceNumberForLatencyStatistics === undefined &&
119
+ message.clientSequenceNumber % 500 === 1) {
120
+ assert(this.opProcessingTimes.opStartTimeSittingInboundQueue === undefined, "OpTimeSittingInboundQueue should be undefined");
121
+ assert(this.opPerfData.durationInboundQueue === undefined, "durationInboundQueue should be undefined");
122
+ this.opProcessingTimes.opStartTimeForLatencyStatistics = Date.now();
87
123
  this.clientSequenceNumberForLatencyStatistics = message.clientSequenceNumber;
88
124
  }
89
125
  }
@@ -93,21 +129,30 @@ class OpPerfTelemetry {
93
129
  this.reportGettingUpToDate();
94
130
  }
95
131
  // Record collab window max size after every 1000th op.
96
- if (sequenceNumber % 1000 === 0) {
97
- if (this.opSendTimeForLatencyStatisticsForMsnStatistics !== undefined) {
98
- this.logger.sendPerformanceEvent({
99
- eventName: "MsnStatistics",
100
- sequenceNumber,
101
- msnDistance: this.deltaManager.lastSequenceNumber - this.deltaManager.minimumSequenceNumber,
102
- duration: message.timestamp - this.opSendTimeForLatencyStatisticsForMsnStatistics,
103
- });
104
- }
105
- this.opSendTimeForLatencyStatisticsForMsnStatistics = message.timestamp;
132
+ if (this.sequenceNumberForMsnTracking === undefined && sequenceNumber % 1000 === 0) {
133
+ this.sequenceNumberForMsnTracking = sequenceNumber;
134
+ this.msnTrackingTimestamp = message.timestamp;
135
+ }
136
+ if (this.sequenceNumberForMsnTracking !== undefined &&
137
+ message.minimumSequenceNumber >= this.sequenceNumberForMsnTracking) {
138
+ assert(this.msnTrackingTimestamp !== undefined, "msnTrackingTimestamp should not be undefined");
139
+ this.logger.sendPerformanceEvent({
140
+ eventName: "MsnStatistics",
141
+ sequenceNumber,
142
+ msnDistance: sequenceNumber - this.sequenceNumberForMsnTracking,
143
+ duration: message.timestamp - this.msnTrackingTimestamp,
144
+ });
145
+ this.sequenceNumberForMsnTracking = undefined;
106
146
  }
107
147
  if (this.clientId === message.clientId &&
108
148
  this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber) {
109
- assert(this.opSendTimeForLatencyStatistics !== undefined, 0x120 /* "Undefined latency statistics (op send time)" */);
110
- const duration = Date.now() - this.opSendTimeForLatencyStatistics;
149
+ assert(this.opProcessingTimes.opStartTimeForLatencyStatistics !== undefined, 0x120 /* "Undefined latency statistics (op send time)" */);
150
+ const currentTime = Date.now();
151
+ if (this.opProcessingTimes.opStartTimeInboundPushEvent !== undefined) {
152
+ this.opPerfData.durationInboundToProcessing = currentTime
153
+ - this.opProcessingTimes.opStartTimeInboundPushEvent;
154
+ }
155
+ const duration = currentTime - this.opProcessingTimes.opStartTimeForLatencyStatistics;
111
156
  // One of the core expectations for Fluid service is to be fast.
112
157
  // When it's not the case, we want to learn about it and be able to investigate, so
113
158
  // raise awareness.
@@ -116,15 +161,10 @@ class OpPerfTelemetry {
116
161
  // The threshold could be adjusted, but ideally it stays workload-agnostic, as service
117
162
  // performance impacts all workloads relying on service.
118
163
  const category = duration > latencyThreshold ? "error" : "performance";
119
- this.logger.sendPerformanceEvent({
120
- eventName: "OpRoundtripTime",
121
- sequenceNumber,
122
- referenceSequenceNumber: message.referenceSequenceNumber,
123
- duration,
124
- category,
125
- pingLatency: this.pingLatency,
126
- });
164
+ this.logger.sendPerformanceEvent(Object.assign({ eventName: "OpRoundtripTime", sequenceNumber, referenceSequenceNumber: message.referenceSequenceNumber, duration,
165
+ category, pingLatency: this.pingLatency, msnDistance: this.deltaManager.lastSequenceNumber - this.deltaManager.minimumSequenceNumber }, this.opPerfData));
127
166
  this.clientSequenceNumberForLatencyStatistics = undefined;
167
+ this.opPerfData = {};
128
168
  }
129
169
  }
130
170
  }
@@ -1 +1 @@
1
- {"version":3,"file":"connectionTelemetry.js","sourceRoot":"","sources":["../src/connectionTelemetry.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ChildLogger, TelemetryLogger } from \"@fluidframework/telemetry-utils\";\nimport { IDeltaManager } from \"@fluidframework/container-definitions\";\nimport {\n IDocumentMessage,\n ISequencedDocumentMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport { assert, performance } from \"@fluidframework/common-utils\";\n\n/**\n * We report various latency-related errors when waiting for op roundtrip takes longer than that amout of time.\n */\nexport const latencyThreshold = 5000;\n\nclass OpPerfTelemetry {\n private pongCount: number = 0;\n private pingLatency: number | undefined;\n\n // Collab window tracking. This is timestamp of %1000 message.\n private opSendTimeForLatencyStatisticsForMsnStatistics: number | undefined;\n\n // To track round trip time for every %1000 client message.\n private opSendTimeForLatencyStatistics: number | undefined;\n private clientSequenceNumberForLatencyStatistics: number | undefined;\n\n private firstConnection = true;\n private connectionOpSeqNumber: number | undefined;\n private readonly bootTime = performance.now();\n private connectionStartTime = 0;\n private gap = 0;\n\n private readonly logger: ITelemetryLogger;\n\n public constructor(\n private clientId: string | undefined,\n private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n logger: ITelemetryLogger) {\n this.logger = ChildLogger.create(logger, \"OpPerf\");\n\n this.deltaManager.on(\"pong\", (latency) => this.recordPingTime(latency));\n this.deltaManager.on(\"submitOp\", (message) => this.beforeOpSubmit(message));\n\n this.deltaManager.on(\"op\", (message) => this.afterProcessingOp(message));\n\n this.deltaManager.on(\"connect\", (details, opsBehind) => {\n this.clientId = details.clientId;\n if (opsBehind !== undefined) {\n this.connectionOpSeqNumber = this.deltaManager.lastKnownSeqNumber;\n this.gap = opsBehind;\n this.connectionStartTime = performance.now();\n\n // We might be already up-today. If so, report it right away.\n if (this.gap <= 0) {\n this.reportGettingUpToDate();\n }\n }\n });\n this.deltaManager.on(\"disconnect\", () => {\n this.opSendTimeForLatencyStatisticsForMsnStatistics = undefined;\n this.clientSequenceNumberForLatencyStatistics = undefined;\n this.connectionOpSeqNumber = undefined;\n this.firstConnection = false;\n });\n\n this.deltaManager.inbound.on(\"idle\", (count: number, duration: number) => {\n // Do not want to log zero for sure.\n // We are more interested in aggregates, so logging only if we are processing some number of ops\n // Cut-off is arbitrary - can be increased or decreased based on amount of data collected and questions we\n // want to get answered\n // back-compat: Once 0.36 loader version saturates (count & duration args were added there),\n // we can remove typeof check.\n if (typeof count === \"number\" && count >= 100) {\n this.logger.sendPerformanceEvent({\n eventName: \"GetDeltas_OpProcessing\",\n count,\n duration,\n });\n }\n });\n }\n\n private reportGettingUpToDate() {\n this.connectionOpSeqNumber = undefined;\n this.logger.sendPerformanceEvent({\n eventName: \"ConnectionSpeed\",\n duration: performance.now() - this.connectionStartTime,\n ops: this.gap,\n // track time to connect only for first connection.\n timeToConnect: this.firstConnection ?\n TelemetryLogger.formatTick(this.connectionStartTime - this.bootTime) :\n undefined,\n firstConnection: this.firstConnection,\n });\n }\n\n private recordPingTime(latency: number) {\n this.pongCount++;\n this.pingLatency = latency;\n // logging one in every 100 pongs\n if (this.pongCount === 100) {\n this.logger.sendPerformanceEvent({\n eventName: \"DeltaLatency\",\n duration: latency,\n });\n this.pongCount = 0;\n }\n }\n\n private beforeOpSubmit(message: IDocumentMessage) {\n // start with first client op and measure latency every 500 client ops\n if (this.clientSequenceNumberForLatencyStatistics === undefined && message.clientSequenceNumber % 500 === 1) {\n this.opSendTimeForLatencyStatistics = Date.now();\n this.clientSequenceNumberForLatencyStatistics = message.clientSequenceNumber;\n }\n }\n\n private afterProcessingOp(message: ISequencedDocumentMessage) {\n const sequenceNumber = message.sequenceNumber;\n\n if (sequenceNumber === this.connectionOpSeqNumber) {\n this.reportGettingUpToDate();\n }\n\n // Record collab window max size after every 1000th op.\n if (sequenceNumber % 1000 === 0) {\n if (this.opSendTimeForLatencyStatisticsForMsnStatistics !== undefined) {\n this.logger.sendPerformanceEvent({\n eventName: \"MsnStatistics\",\n sequenceNumber,\n msnDistance: this.deltaManager.lastSequenceNumber - this.deltaManager.minimumSequenceNumber,\n duration: message.timestamp - this.opSendTimeForLatencyStatisticsForMsnStatistics,\n });\n }\n this.opSendTimeForLatencyStatisticsForMsnStatistics = message.timestamp;\n }\n\n if (this.clientId === message.clientId &&\n this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber) {\n assert(this.opSendTimeForLatencyStatistics !== undefined,\n 0x120 /* \"Undefined latency statistics (op send time)\" */);\n\n const duration = Date.now() - this.opSendTimeForLatencyStatistics;\n\n // One of the core expectations for Fluid service is to be fast.\n // When it's not the case, we want to learn about it and be able to investigate, so\n // raise awareness.\n // This also helps identify cases where it's due to client behavior (sending too many ops)\n // that results in overwhelming ordering service and thus starting to see long latencies.\n // The threshold could be adjusted, but ideally it stays workload-agnostic, as service\n // performance impacts all workloads relying on service.\n const category = duration > latencyThreshold ? \"error\" : \"performance\";\n\n this.logger.sendPerformanceEvent({\n eventName: \"OpRoundtripTime\",\n sequenceNumber,\n referenceSequenceNumber: message.referenceSequenceNumber,\n duration,\n category,\n pingLatency: this.pingLatency,\n });\n this.clientSequenceNumberForLatencyStatistics = undefined;\n }\n }\n}\n\nexport function ReportOpPerfTelemetry(\n clientId: string | undefined,\n deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n logger: ITelemetryLogger) {\n new OpPerfTelemetry(clientId, deltaManager, logger);\n}\n"]}
1
+ {"version":3,"file":"connectionTelemetry.js","sourceRoot":"","sources":["../src/connectionTelemetry.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ChildLogger, TelemetryLogger } from \"@fluidframework/telemetry-utils\";\nimport { IDeltaManager } from \"@fluidframework/container-definitions\";\nimport {\n IDocumentMessage,\n ISequencedDocumentMessage,\n MessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport { assert, performance } from \"@fluidframework/common-utils\";\n\n/**\n * We report various latency-related errors when waiting for op roundtrip takes longer than that amout of time.\n */\nexport const latencyThreshold = 5000;\n\n// Phases in OpPerfTelemetry:\n// 1.\tOp sits in a buffer in DeltaManager (DM) queue, then in outbound queue for some time.\n// \t - Note: We do not differentiate these two today in telemetry, but first one is due to batches,\n// second one might happen due to outbound queue being paused.\n// 2.\tOp is sent to service and back.\n// 3.\tOp sits in inbound queue.\n// 4.\tOp is processed.\ninterface IOpPerfTelemetryProperties {\n /** Measure time between (1) and (2) - Measure time outbound op is sitting in queue due to active batch */\n durationOutboundQueue: number;\n /** Measure time between (2) and (3) - Track how long op is sitting in inbound queue until it is processed */\n durationInboundQueue: number;\n /** Measure time between (3) and (4) - Time between DM's inbound \"push\" event until DM's \"op\" event */\n durationInboundToProcessing: number;\n /** Length of the DeltaManager's inbound queue at the time of the DM's inbound \"push\" event (3) */\n lenghtInboundQueue: number;\n}\n\n/**\n * Timings collected at various moments during the op processing.\n */\n interface IOpPerfTimings {\n /** Starting time for (1) */\n opStartTimeForLatencyStatistics: number;\n /** Starting time for (2) */\n opStartTimeSittingInboundQueue: number;\n /** Starting time for (3) */\n opStartTimeInboundPushEvent: number;\n}\n\nclass OpPerfTelemetry {\n private pongCount: number = 0;\n private pingLatency: number | undefined;\n\n // Collab window tracking. This is timestamp of %1000 message.\n private sequenceNumberForMsnTracking: number | undefined;\n private msnTrackingTimestamp: number = 0;\n // To track round trip time for every %500 client message.\n private clientSequenceNumberForLatencyStatistics: number | undefined;\n\n private opProcessingTimes: Partial<IOpPerfTimings> = {};\n\n // Performance Data to be reported for ops round trips and processing.\n private opPerfData: Partial<IOpPerfTelemetryProperties> = {};\n\n private firstConnection = true;\n private connectionOpSeqNumber: number | undefined;\n private readonly bootTime = performance.now();\n private connectionStartTime = 0;\n private gap = 0;\n\n private readonly logger: ITelemetryLogger;\n\n public constructor(\n private clientId: string | undefined,\n private readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n logger: ITelemetryLogger) {\n this.logger = ChildLogger.create(logger, \"OpPerf\");\n\n this.deltaManager.on(\"pong\", (latency) => this.recordPingTime(latency));\n this.deltaManager.on(\"submitOp\", (message) => this.beforeOpSubmit(message));\n\n this.deltaManager.on(\"op\", (message) => this.afterProcessingOp(message));\n\n this.deltaManager.on(\"connect\", (details, opsBehind) => {\n this.clientId = details.clientId;\n if (opsBehind !== undefined) {\n this.connectionOpSeqNumber = this.deltaManager.lastKnownSeqNumber;\n this.gap = opsBehind;\n this.connectionStartTime = performance.now();\n\n // We might be already up-today. If so, report it right away.\n if (this.gap <= 0) {\n this.reportGettingUpToDate();\n }\n }\n });\n this.deltaManager.on(\"disconnect\", () => {\n this.sequenceNumberForMsnTracking = undefined;\n this.clientSequenceNumberForLatencyStatistics = undefined;\n this.opProcessingTimes = {};\n this.opPerfData = {};\n this.connectionOpSeqNumber = undefined;\n this.firstConnection = false;\n });\n\n this.deltaManager.outbound.on(\"push\", (messages) => {\n for (const msg of messages) {\n if (msg.type === MessageType.Operation &&\n this.clientSequenceNumberForLatencyStatistics === msg.clientSequenceNumber) {\n assert(this.opProcessingTimes.opStartTimeSittingInboundQueue === undefined,\n \"opStartTimeSittingInboundQueue should be undefined\");\n assert(this.opPerfData.durationInboundQueue === undefined,\n \"durationInboundQueue should be undefined\");\n this.opProcessingTimes.opStartTimeSittingInboundQueue = Date.now();\n\n assert(this.opPerfData.durationOutboundQueue === undefined,\n \"durationOutboundQueue should be undefined\");\n\n assert(this.opProcessingTimes.opStartTimeForLatencyStatistics !== undefined,\n \"opStartTimeForLatencyStatistics should be undefined\");\n\n this.opPerfData.durationOutboundQueue = this.opProcessingTimes.opStartTimeSittingInboundQueue\n - this.opProcessingTimes.opStartTimeForLatencyStatistics;\n }\n }\n });\n\n this.deltaManager.inbound.on(\"push\", (message: ISequencedDocumentMessage) => {\n if (this.clientId === message.clientId &&\n message.type === MessageType.Operation &&\n this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber &&\n this.opProcessingTimes.opStartTimeSittingInboundQueue !== undefined) {\n this.opProcessingTimes.opStartTimeInboundPushEvent = Date.now();\n this.opPerfData.durationInboundQueue = this.opProcessingTimes.opStartTimeInboundPushEvent\n - this.opProcessingTimes.opStartTimeSittingInboundQueue;\n this.opProcessingTimes.opStartTimeSittingInboundQueue = undefined;\n this.opPerfData.lenghtInboundQueue = this.deltaManager.inbound.length;\n }\n });\n\n this.deltaManager.inbound.on(\"idle\", (count: number, duration: number) => {\n // Do not want to log zero for sure.\n // We are more interested in aggregates, so logging only if we are processing some number of ops\n // Cut-off is arbitrary - can be increased or decreased based on amount of data collected and questions we\n // want to get answered\n // back-compat: Once 0.36 loader version saturates (count & duration args were added there),\n // we can remove typeof check.\n if (typeof count === \"number\" && count >= 100) {\n this.logger.sendPerformanceEvent({\n eventName: \"GetDeltas_OpProcessing\",\n count,\n duration,\n });\n }\n });\n }\n\n private reportGettingUpToDate() {\n this.connectionOpSeqNumber = undefined;\n this.logger.sendPerformanceEvent({\n eventName: \"ConnectionSpeed\",\n duration: performance.now() - this.connectionStartTime,\n ops: this.gap,\n // track time to connect only for first connection.\n timeToConnect: this.firstConnection ?\n TelemetryLogger.formatTick(this.connectionStartTime - this.bootTime) :\n undefined,\n firstConnection: this.firstConnection,\n });\n }\n\n private recordPingTime(latency: number) {\n this.pongCount++;\n this.pingLatency = latency;\n // logging one in every 100 pongs\n if (this.pongCount === 100) {\n this.logger.sendPerformanceEvent({\n eventName: \"DeltaLatency\",\n duration: latency,\n });\n this.pongCount = 0;\n }\n }\n\n private beforeOpSubmit(message: IDocumentMessage) {\n // start with first client op and measure latency every 500 client ops\n if (this.clientSequenceNumberForLatencyStatistics === undefined &&\n message.clientSequenceNumber % 500 === 1) {\n assert(this.opProcessingTimes.opStartTimeSittingInboundQueue === undefined,\n \"OpTimeSittingInboundQueue should be undefined\");\n assert(this.opPerfData.durationInboundQueue === undefined,\n \"durationInboundQueue should be undefined\");\n this.opProcessingTimes.opStartTimeForLatencyStatistics = Date.now();\n this.clientSequenceNumberForLatencyStatistics = message.clientSequenceNumber;\n }\n }\n\n private afterProcessingOp(message: ISequencedDocumentMessage) {\n const sequenceNumber = message.sequenceNumber;\n\n if (sequenceNumber === this.connectionOpSeqNumber) {\n this.reportGettingUpToDate();\n }\n\n // Record collab window max size after every 1000th op.\n if (this.sequenceNumberForMsnTracking === undefined && sequenceNumber % 1000 === 0) {\n this.sequenceNumberForMsnTracking = sequenceNumber;\n this.msnTrackingTimestamp = message.timestamp;\n }\n if (this.sequenceNumberForMsnTracking !== undefined &&\n message.minimumSequenceNumber >= this.sequenceNumberForMsnTracking) {\n assert(this.msnTrackingTimestamp !== undefined,\n \"msnTrackingTimestamp should not be undefined\");\n this.logger.sendPerformanceEvent({\n eventName: \"MsnStatistics\",\n sequenceNumber,\n msnDistance: sequenceNumber - this.sequenceNumberForMsnTracking,\n duration: message.timestamp - this.msnTrackingTimestamp,\n });\n this.sequenceNumberForMsnTracking = undefined;\n }\n\n if (this.clientId === message.clientId &&\n this.clientSequenceNumberForLatencyStatistics === message.clientSequenceNumber) {\n assert(this.opProcessingTimes.opStartTimeForLatencyStatistics !== undefined,\n 0x120 /* \"Undefined latency statistics (op send time)\" */);\n const currentTime = Date.now();\n\n if (this.opProcessingTimes.opStartTimeInboundPushEvent !== undefined) {\n this.opPerfData.durationInboundToProcessing = currentTime\n - this.opProcessingTimes.opStartTimeInboundPushEvent;\n }\n\n const duration = currentTime - this.opProcessingTimes.opStartTimeForLatencyStatistics;\n\n // One of the core expectations for Fluid service is to be fast.\n // When it's not the case, we want to learn about it and be able to investigate, so\n // raise awareness.\n // This also helps identify cases where it's due to client behavior (sending too many ops)\n // that results in overwhelming ordering service and thus starting to see long latencies.\n // The threshold could be adjusted, but ideally it stays workload-agnostic, as service\n // performance impacts all workloads relying on service.\n const category = duration > latencyThreshold ? \"error\" : \"performance\";\n\n this.logger.sendPerformanceEvent({\n eventName: \"OpRoundtripTime\",\n sequenceNumber,\n referenceSequenceNumber: message.referenceSequenceNumber,\n duration,\n category,\n pingLatency: this.pingLatency,\n msnDistance: this.deltaManager.lastSequenceNumber - this.deltaManager.minimumSequenceNumber,\n ...this.opPerfData,\n });\n this.clientSequenceNumberForLatencyStatistics = undefined;\n this.opPerfData = {};\n }\n }\n}\n\nexport function ReportOpPerfTelemetry(\n clientId: string | undefined,\n deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n logger: ITelemetryLogger) {\n new OpPerfTelemetry(clientId, deltaManager, logger);\n}\n"]}
@@ -86,8 +86,8 @@ export interface ISummaryRuntimeOptions {
86
86
  * Options for container runtime.
87
87
  */
88
88
  export interface IContainerRuntimeOptions {
89
- summaryOptions?: ISummaryRuntimeOptions;
90
- gcOptions?: IGCRuntimeOptions;
89
+ readonly summaryOptions?: ISummaryRuntimeOptions;
90
+ readonly gcOptions?: IGCRuntimeOptions;
91
91
  /**
92
92
  * Affects the behavior while loading the runtime when the data verification check which
93
93
  * compares the DeltaManager sequence number (obtained from protocol in summary) to the
@@ -96,13 +96,20 @@ export interface IContainerRuntimeOptions {
96
96
  * 2. "log" will log an error event to telemetry, but still continue to load.
97
97
  * 3. "bypass" will skip the check entirely. This is not recommended.
98
98
  */
99
- loadSequenceNumberVerification?: "close" | "log" | "bypass";
99
+ readonly loadSequenceNumberVerification?: "close" | "log" | "bypass";
100
100
  /**
101
101
  * Should the runtime use data store aliasing for creating root datastores.
102
102
  * In case of aliasing conflicts, the runtime will raise an exception which does
103
103
  * not effect the status of the container.
104
104
  */
105
- useDataStoreAliasing?: boolean;
105
+ readonly useDataStoreAliasing?: boolean;
106
+ /**
107
+ * Sets the flush mode for the runtime. In Immediate flush mode the runtime will immediately
108
+ * send all operations to the driver layer, while in TurnBased the operations will be buffered
109
+ * and then sent them as a single batch at the end of the turn.
110
+ * By default, flush mode is TurnBased.
111
+ */
112
+ readonly flushMode?: FlushMode;
106
113
  }
107
114
  /**
108
115
  * The summary tree returned by the root node. It adds state relevant to the root of the tree.
@@ -257,6 +264,7 @@ export declare class ContainerRuntime extends TypedEventEmitter<IContainerRuntim
257
264
  private get summariesDisabled();
258
265
  private readonly createContainerMetadata;
259
266
  private summaryCount;
267
+ private readonly opTracker;
260
268
  private constructor();
261
269
  dispose(error?: Error): void;
262
270
  get IFluidTokenProvider(): IFluidTokenProvider | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"containerRuntime.d.ts","sourceRoot":"","sources":["../src/containerRuntime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"containerRuntime.d.ts","sourceRoot":"","sources":["../src/containerRuntime.ts"],"names":[],"mappings":"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"}