@fluidframework/container-runtime 2.0.0-internal.2.3.0 → 2.0.0-internal.2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/blobManager.d.ts +4 -2
  2. package/dist/blobManager.d.ts.map +1 -1
  3. package/dist/blobManager.js +43 -10
  4. package/dist/blobManager.js.map +1 -1
  5. package/dist/containerRuntime.d.ts +15 -0
  6. package/dist/containerRuntime.d.ts.map +1 -1
  7. package/dist/containerRuntime.js +28 -13
  8. package/dist/containerRuntime.js.map +1 -1
  9. package/dist/dataStoreContext.d.ts.map +1 -1
  10. package/dist/dataStoreContext.js +5 -8
  11. package/dist/dataStoreContext.js.map +1 -1
  12. package/dist/dataStores.d.ts +3 -3
  13. package/dist/dataStores.d.ts.map +1 -1
  14. package/dist/dataStores.js +14 -14
  15. package/dist/dataStores.js.map +1 -1
  16. package/dist/garbageCollection.d.ts +15 -7
  17. package/dist/garbageCollection.d.ts.map +1 -1
  18. package/dist/garbageCollection.js +101 -40
  19. package/dist/garbageCollection.js.map +1 -1
  20. package/dist/garbageCollectionConstants.d.ts +1 -0
  21. package/dist/garbageCollectionConstants.d.ts.map +1 -1
  22. package/dist/garbageCollectionConstants.js +4 -2
  23. package/dist/garbageCollectionConstants.js.map +1 -1
  24. package/dist/garbageCollectionTombstoneUtils.d.ts +5 -4
  25. package/dist/garbageCollectionTombstoneUtils.d.ts.map +1 -1
  26. package/dist/garbageCollectionTombstoneUtils.js +8 -13
  27. package/dist/garbageCollectionTombstoneUtils.js.map +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +3 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/packageVersion.d.ts +1 -1
  33. package/dist/packageVersion.js +1 -1
  34. package/dist/packageVersion.js.map +1 -1
  35. package/dist/summarizer.js.map +1 -1
  36. package/lib/blobManager.d.ts +4 -2
  37. package/lib/blobManager.d.ts.map +1 -1
  38. package/lib/blobManager.js +44 -11
  39. package/lib/blobManager.js.map +1 -1
  40. package/lib/containerRuntime.d.ts +15 -0
  41. package/lib/containerRuntime.d.ts.map +1 -1
  42. package/lib/containerRuntime.js +27 -12
  43. package/lib/containerRuntime.js.map +1 -1
  44. package/lib/dataStoreContext.d.ts.map +1 -1
  45. package/lib/dataStoreContext.js +5 -8
  46. package/lib/dataStoreContext.js.map +1 -1
  47. package/lib/dataStores.d.ts +3 -3
  48. package/lib/dataStores.d.ts.map +1 -1
  49. package/lib/dataStores.js +15 -15
  50. package/lib/dataStores.js.map +1 -1
  51. package/lib/garbageCollection.d.ts +15 -7
  52. package/lib/garbageCollection.d.ts.map +1 -1
  53. package/lib/garbageCollection.js +103 -42
  54. package/lib/garbageCollection.js.map +1 -1
  55. package/lib/garbageCollectionConstants.d.ts +1 -0
  56. package/lib/garbageCollectionConstants.d.ts.map +1 -1
  57. package/lib/garbageCollectionConstants.js +3 -1
  58. package/lib/garbageCollectionConstants.js.map +1 -1
  59. package/lib/garbageCollectionTombstoneUtils.d.ts +5 -4
  60. package/lib/garbageCollectionTombstoneUtils.d.ts.map +1 -1
  61. package/lib/garbageCollectionTombstoneUtils.js +9 -14
  62. package/lib/garbageCollectionTombstoneUtils.js.map +1 -1
  63. package/lib/index.d.ts +1 -1
  64. package/lib/index.d.ts.map +1 -1
  65. package/lib/index.js +1 -1
  66. package/lib/index.js.map +1 -1
  67. package/lib/packageVersion.d.ts +1 -1
  68. package/lib/packageVersion.js +1 -1
  69. package/lib/packageVersion.js.map +1 -1
  70. package/lib/summarizer.js.map +1 -1
  71. package/package.json +16 -16
  72. package/src/blobManager.ts +57 -13
  73. package/src/containerRuntime.ts +38 -9
  74. package/src/dataStoreContext.ts +13 -14
  75. package/src/dataStores.ts +25 -19
  76. package/src/garbageCollection.ts +115 -42
  77. package/src/garbageCollectionConstants.ts +3 -1
  78. package/src/garbageCollectionTombstoneUtils.ts +11 -14
  79. package/src/index.ts +2 -0
  80. package/src/packageVersion.ts +1 -1
  81. package/src/summarizer.ts +1 -1
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.defaultSessionExpiryDurationMs = exports.defaultInactiveTimeoutMs = exports.oneDayMs = exports.gcVersionUpgradeToV2Key = exports.throwOnTombstoneUsageKey = exports.disableTombstoneKey = exports.disableSweepLogKey = exports.trackGCStateKey = exports.runSessionExpiryKey = exports.gcTestModeKey = exports.runSweepKey = exports.runGCKey = exports.currentGCVersion = exports.stableGCVersion = void 0;
7
+ exports.defaultSessionExpiryDurationMs = exports.defaultInactiveTimeoutMs = exports.oneDayMs = exports.gcVersionUpgradeToV2Key = exports.throwOnTombstoneUsageKey = exports.throwOnTombstoneLoadKey = exports.disableTombstoneKey = exports.disableSweepLogKey = exports.trackGCStateKey = exports.runSessionExpiryKey = exports.gcTestModeKey = exports.runSweepKey = exports.runGCKey = exports.currentGCVersion = exports.stableGCVersion = void 0;
8
8
  /** The stable version of garbage collection in production. */
9
9
  exports.stableGCVersion = 1;
10
10
  /** The current version of garbage collection. */
@@ -23,7 +23,9 @@ exports.trackGCStateKey = "Fluid.GarbageCollection.TrackGCState";
23
23
  exports.disableSweepLogKey = "Fluid.GarbageCollection.DisableSweepLog";
24
24
  // Feature gate key to disable the tombstone feature, i.e., tombstone information is not read / written into summary.
25
25
  exports.disableTombstoneKey = "Fluid.GarbageCollection.DisableTombstone";
26
- // Feature gate to enable throwing an error when tombstone object is used.
26
+ // Feature gate to enable throwing an error when tombstone object is loaded (requested).
27
+ exports.throwOnTombstoneLoadKey = "Fluid.GarbageCollection.ThrowOnTombstoneLoad";
28
+ // Feature gate to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops).
27
29
  exports.throwOnTombstoneUsageKey = "Fluid.GarbageCollection.ThrowOnTombstoneUsage";
28
30
  // Feature gate to enable GC version upgrade.
29
31
  exports.gcVersionUpgradeToV2Key = "Fluid.GarbageCollection.GCVersionUpgradeToV2";
@@ -1 +1 @@
1
- {"version":3,"file":"garbageCollectionConstants.js","sourceRoot":"","sources":["../src/garbageCollectionConstants.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,8DAA8D;AACjD,QAAA,eAAe,GAAc,CAAC,CAAC;AAC5C,iDAAiD;AACpC,QAAA,gBAAgB,GAAc,CAAC,CAAC;AAE7C,wCAAwC;AAC3B,QAAA,QAAQ,GAAG,+BAA+B,CAAC;AACxD,8CAA8C;AACjC,QAAA,WAAW,GAAG,kCAAkC,CAAC;AAC9D,kDAAkD;AACrC,QAAA,aAAa,GAAG,oCAAoC,CAAC;AAClE,mEAAmE;AACtD,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,6EAA6E;AAChE,QAAA,eAAe,GAAG,sCAAsC,CAAC;AACtE,6CAA6C;AAChC,QAAA,kBAAkB,GAAG,yCAAyC,CAAC;AAC5E,qHAAqH;AACxG,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,0EAA0E;AAC7D,QAAA,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,6CAA6C;AAChC,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AAEtF,2BAA2B;AACd,QAAA,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC,QAAA,wBAAwB,GAAG,CAAC,GAAG,gBAAQ,CAAC,CAAC,SAAS;AAClD,QAAA,8BAA8B,GAAG,EAAE,GAAG,gBAAQ,CAAC,CAAC,UAAU","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { GCVersion } from \"./summaryFormat\";\n\n/** The stable version of garbage collection in production. */\nexport const stableGCVersion: GCVersion = 1;\n/** The current version of garbage collection. */\nexport const currentGCVersion: GCVersion = 2;\n\n// Feature gate key to turn GC on / off.\nexport const runGCKey = \"Fluid.GarbageCollection.RunGC\";\n// Feature gate key to turn GC sweep on / off.\nexport const runSweepKey = \"Fluid.GarbageCollection.RunSweep\";\n// Feature gate key to turn GC test mode on / off.\nexport const gcTestModeKey = \"Fluid.GarbageCollection.GCTestMode\";\n// Feature gate key to expire a session after a set period of time.\nexport const runSessionExpiryKey = \"Fluid.GarbageCollection.RunSessionExpiry\";\n// Feature gate key to write the gc blob as a handle if the data is the same.\nexport const trackGCStateKey = \"Fluid.GarbageCollection.TrackGCState\";\n// Feature gate key to turn GC sweep log off.\nexport const disableSweepLogKey = \"Fluid.GarbageCollection.DisableSweepLog\";\n// Feature gate key to disable the tombstone feature, i.e., tombstone information is not read / written into summary.\nexport const disableTombstoneKey = \"Fluid.GarbageCollection.DisableTombstone\";\n// Feature gate to enable throwing an error when tombstone object is used.\nexport const throwOnTombstoneUsageKey = \"Fluid.GarbageCollection.ThrowOnTombstoneUsage\";\n// Feature gate to enable GC version upgrade.\nexport const gcVersionUpgradeToV2Key = \"Fluid.GarbageCollection.GCVersionUpgradeToV2\";\n\n// One day in milliseconds.\nexport const oneDayMs = 1 * 24 * 60 * 60 * 1000;\n\nexport const defaultInactiveTimeoutMs = 7 * oneDayMs; // 7 days\nexport const defaultSessionExpiryDurationMs = 30 * oneDayMs; // 30 days\n"]}
1
+ {"version":3,"file":"garbageCollectionConstants.js","sourceRoot":"","sources":["../src/garbageCollectionConstants.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,8DAA8D;AACjD,QAAA,eAAe,GAAc,CAAC,CAAC;AAC5C,iDAAiD;AACpC,QAAA,gBAAgB,GAAc,CAAC,CAAC;AAE7C,wCAAwC;AAC3B,QAAA,QAAQ,GAAG,+BAA+B,CAAC;AACxD,8CAA8C;AACjC,QAAA,WAAW,GAAG,kCAAkC,CAAC;AAC9D,kDAAkD;AACrC,QAAA,aAAa,GAAG,oCAAoC,CAAC;AAClE,mEAAmE;AACtD,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,6EAA6E;AAChE,QAAA,eAAe,GAAG,sCAAsC,CAAC;AACtE,6CAA6C;AAChC,QAAA,kBAAkB,GAAG,yCAAyC,CAAC;AAC5E,qHAAqH;AACxG,QAAA,mBAAmB,GAAG,0CAA0C,CAAC;AAC9E,wFAAwF;AAC3E,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AACtF,0GAA0G;AAC7F,QAAA,wBAAwB,GAAG,+CAA+C,CAAC;AACxF,6CAA6C;AAChC,QAAA,uBAAuB,GAAG,8CAA8C,CAAC;AAEtF,2BAA2B;AACd,QAAA,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC,QAAA,wBAAwB,GAAG,CAAC,GAAG,gBAAQ,CAAC,CAAC,SAAS;AAClD,QAAA,8BAA8B,GAAG,EAAE,GAAG,gBAAQ,CAAC,CAAC,UAAU","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { GCVersion } from \"./summaryFormat\";\n\n/** The stable version of garbage collection in production. */\nexport const stableGCVersion: GCVersion = 1;\n/** The current version of garbage collection. */\nexport const currentGCVersion: GCVersion = 2;\n\n// Feature gate key to turn GC on / off.\nexport const runGCKey = \"Fluid.GarbageCollection.RunGC\";\n// Feature gate key to turn GC sweep on / off.\nexport const runSweepKey = \"Fluid.GarbageCollection.RunSweep\";\n// Feature gate key to turn GC test mode on / off.\nexport const gcTestModeKey = \"Fluid.GarbageCollection.GCTestMode\";\n// Feature gate key to expire a session after a set period of time.\nexport const runSessionExpiryKey = \"Fluid.GarbageCollection.RunSessionExpiry\";\n// Feature gate key to write the gc blob as a handle if the data is the same.\nexport const trackGCStateKey = \"Fluid.GarbageCollection.TrackGCState\";\n// Feature gate key to turn GC sweep log off.\nexport const disableSweepLogKey = \"Fluid.GarbageCollection.DisableSweepLog\";\n// Feature gate key to disable the tombstone feature, i.e., tombstone information is not read / written into summary.\nexport const disableTombstoneKey = \"Fluid.GarbageCollection.DisableTombstone\";\n// Feature gate to enable throwing an error when tombstone object is loaded (requested).\nexport const throwOnTombstoneLoadKey = \"Fluid.GarbageCollection.ThrowOnTombstoneLoad\";\n// Feature gate to enable throwing an error when tombstone object is used (e.g. outgoing or incoming ops).\nexport const throwOnTombstoneUsageKey = \"Fluid.GarbageCollection.ThrowOnTombstoneUsage\";\n// Feature gate to enable GC version upgrade.\nexport const gcVersionUpgradeToV2Key = \"Fluid.GarbageCollection.GCVersionUpgradeToV2\";\n\n// One day in milliseconds.\nexport const oneDayMs = 1 * 24 * 60 * 60 * 1000;\n\nexport const defaultInactiveTimeoutMs = 7 * oneDayMs; // 7 days\nexport const defaultSessionExpiryDurationMs = 30 * oneDayMs; // 30 days\n"]}
@@ -5,9 +5,10 @@
5
5
  import { ITelemetryGenericEvent } from "@fluidframework/common-definitions";
6
6
  import { MonitoringContext } from "@fluidframework/telemetry-utils";
7
7
  /**
8
- * Decides whether or not to send an error event or a generic event for gc tombstone scenarios
9
- *
10
- * Adds isSummarizerClient, packagePath, and error to telemetry properties.
8
+ * Consolidates info / logic for logging when we encounter a Tombstone
11
9
  */
12
- export declare function sendGCTombstoneEvent(mc: MonitoringContext, event: ITelemetryGenericEvent, isSummarizerClient: boolean, packagePath: readonly string[] | undefined, error?: any): void;
10
+ export declare function sendGCTombstoneEvent(mc: MonitoringContext, event: ITelemetryGenericEvent & {
11
+ category: "error" | "generic";
12
+ isSummarizerClient: boolean;
13
+ }, packagePath: readonly string[] | undefined, error?: unknown): void;
13
14
  //# sourceMappingURL=garbageCollectionTombstoneUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"garbageCollectionTombstoneUtils.d.ts","sourceRoot":"","sources":["../src/garbageCollectionTombstoneUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,iBAAiB,EACrB,KAAK,EAAE,sBAAsB,EAC7B,kBAAkB,EAAE,OAAO,EAC3B,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC1C,KAAK,CAAC,EAAE,GAAG,QAUd"}
1
+ {"version":3,"file":"garbageCollectionTombstoneUtils.d.ts","sourceRoot":"","sources":["../src/garbageCollectionTombstoneUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGpE;;GAEG;AACH,wBAAgB,oBAAoB,CAChC,EAAE,EAAE,iBAAiB,EACrB,KAAK,EAAE,sBAAsB,GAAG;IAAE,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAAC,kBAAkB,EAAE,OAAO,CAAA;CAAE,EAC9F,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAC1C,KAAK,CAAC,EAAE,OAAO,QAUlB"}
@@ -8,21 +8,16 @@ exports.sendGCTombstoneEvent = void 0;
8
8
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
9
9
  const garbageCollectionConstants_1 = require("./garbageCollectionConstants");
10
10
  /**
11
- * Decides whether or not to send an error event or a generic event for gc tombstone scenarios
12
- *
13
- * Adds isSummarizerClient, packagePath, and error to telemetry properties.
11
+ * Consolidates info / logic for logging when we encounter a Tombstone
14
12
  */
15
- function sendGCTombstoneEvent(mc, event, isSummarizerClient, packagePath, error) {
16
- var _a;
17
- const throwOnTombstoneUsage = event.throwOnTombstoneUsage = (_a = mc.config.getBoolean(garbageCollectionConstants_1.throwOnTombstoneUsageKey)) !== null && _a !== void 0 ? _a : false;
13
+ function sendGCTombstoneEvent(mc, event, packagePath, error) {
18
14
  event.pkg = (0, runtime_utils_1.packagePathToTelemetryProperty)(packagePath);
19
- event.isSummarizerClient = isSummarizerClient;
20
- if (throwOnTombstoneUsage) {
21
- mc.logger.sendErrorEvent(event, error);
22
- }
23
- else {
24
- mc.logger.sendTelemetryEvent(event, error);
25
- }
15
+ event.tombstoneFlags = JSON.stringify({
16
+ DisableTombstone: mc.config.getBoolean(garbageCollectionConstants_1.disableTombstoneKey),
17
+ ThrowOnTombstoneUsage: mc.config.getBoolean(garbageCollectionConstants_1.throwOnTombstoneUsageKey),
18
+ ThrowOnTombstoneLoad: mc.config.getBoolean(garbageCollectionConstants_1.throwOnTombstoneLoadKey),
19
+ });
20
+ mc.logger.sendTelemetryEvent(event, error);
26
21
  }
27
22
  exports.sendGCTombstoneEvent = sendGCTombstoneEvent;
28
23
  //# sourceMappingURL=garbageCollectionTombstoneUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"garbageCollectionTombstoneUtils.js","sourceRoot":"","sources":["../src/garbageCollectionTombstoneUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iEAA+E;AAE/E,6EAAwE;AAExE;;;;GAIG;AACH,SAAgB,oBAAoB,CAChC,EAAqB,EACrB,KAA6B,EAC7B,kBAA2B,EAC3B,WAA0C,EAC1C,KAAW;;IAEX,MAAM,qBAAqB,GAAG,KAAK,CAAC,qBAAqB,GAAG,MAAA,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,qDAAwB,CAAC,mCAAI,KAAK,CAAC;IACpH,KAAK,CAAC,GAAG,GAAG,IAAA,8CAA8B,EAAC,WAAW,CAAC,CAAC;IACxD,KAAK,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAC9C,IAAG,qBAAqB,EAAE;QACtB,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;KAC1C;SAAM;QACH,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;KAC9C;AACL,CAAC;AAfD,oDAeC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryGenericEvent } from \"@fluidframework/common-definitions\";\nimport { packagePathToTelemetryProperty } from \"@fluidframework/runtime-utils\";\nimport { MonitoringContext } from \"@fluidframework/telemetry-utils\";\nimport { throwOnTombstoneUsageKey } from \"./garbageCollectionConstants\";\n\n/**\n * Decides whether or not to send an error event or a generic event for gc tombstone scenarios\n *\n * Adds isSummarizerClient, packagePath, and error to telemetry properties.\n */\nexport function sendGCTombstoneEvent(\n mc: MonitoringContext,\n event: ITelemetryGenericEvent,\n isSummarizerClient: boolean,\n packagePath: readonly string[] | undefined,\n error?: any,\n) {\n const throwOnTombstoneUsage = event.throwOnTombstoneUsage = mc.config.getBoolean(throwOnTombstoneUsageKey) ?? false;\n event.pkg = packagePathToTelemetryProperty(packagePath);\n event.isSummarizerClient = isSummarizerClient;\n if(throwOnTombstoneUsage) {\n mc.logger.sendErrorEvent(event, error);\n } else {\n mc.logger.sendTelemetryEvent(event, error);\n }\n}\n"]}
1
+ {"version":3,"file":"garbageCollectionTombstoneUtils.js","sourceRoot":"","sources":["../src/garbageCollectionTombstoneUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iEAA+E;AAE/E,6EAAsH;AAEtH;;GAEG;AACH,SAAgB,oBAAoB,CAChC,EAAqB,EACrB,KAA8F,EAC9F,WAA0C,EAC1C,KAAe;IAEf,KAAK,CAAC,GAAG,GAAG,IAAA,8CAA8B,EAAC,WAAW,CAAC,CAAC;IACxD,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC;QAClC,gBAAgB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,gDAAmB,CAAC;QAC3D,qBAAqB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,qDAAwB,CAAC;QACrE,oBAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,oDAAuB,CAAC;KACtE,CAAC,CAAC;IAEH,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC/C,CAAC;AAdD,oDAcC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryGenericEvent } from \"@fluidframework/common-definitions\";\nimport { packagePathToTelemetryProperty } from \"@fluidframework/runtime-utils\";\nimport { MonitoringContext } from \"@fluidframework/telemetry-utils\";\nimport { disableTombstoneKey, throwOnTombstoneLoadKey, throwOnTombstoneUsageKey } from \"./garbageCollectionConstants\";\n\n/**\n * Consolidates info / logic for logging when we encounter a Tombstone\n */\nexport function sendGCTombstoneEvent(\n mc: MonitoringContext,\n event: ITelemetryGenericEvent & { category: \"error\" | \"generic\", isSummarizerClient: boolean },\n packagePath: readonly string[] | undefined,\n error?: unknown,\n) {\n event.pkg = packagePathToTelemetryProperty(packagePath);\n event.tombstoneFlags = JSON.stringify({\n DisableTombstone: mc.config.getBoolean(disableTombstoneKey),\n ThrowOnTombstoneUsage: mc.config.getBoolean(throwOnTombstoneUsageKey),\n ThrowOnTombstoneLoad: mc.config.getBoolean(throwOnTombstoneLoadKey),\n });\n\n mc.logger.sendTelemetryEvent(event, error);\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- export { ContainerMessageType, ContainerRuntimeMessage, IGCRuntimeOptions, ISummaryRuntimeOptions, ISummaryBaseConfiguration, ISummaryConfigurationHeuristics, ISummaryConfigurationDisableSummarizer, ISummaryConfigurationDisableHeuristics, IContainerRuntimeOptions, IRootSummaryTreeWithStats, isRuntimeMessage, RuntimeMessage, agentSchedulerId, ContainerRuntime, RuntimeHeaders, ISummaryConfiguration, DefaultSummaryConfiguration, ICompressionRuntimeOptions, CompressionAlgorithms, } from "./containerRuntime";
5
+ export { ContainerMessageType, ContainerRuntimeMessage, IGCRuntimeOptions, ISummaryRuntimeOptions, ISummaryBaseConfiguration, ISummaryConfigurationHeuristics, ISummaryConfigurationDisableSummarizer, ISummaryConfigurationDisableHeuristics, IContainerRuntimeOptions, IRootSummaryTreeWithStats, isRuntimeMessage, RuntimeMessage, agentSchedulerId, ContainerRuntime, RuntimeHeaders, AllowTombstoneRequestHeaderKey, TombstoneResponseHeaderKey, ISummaryConfiguration, DefaultSummaryConfiguration, ICompressionRuntimeOptions, CompressionAlgorithms, } from "./containerRuntime";
6
6
  export { FluidDataStoreRegistry } from "./dataStoreRegistry";
7
7
  export { IGCStats, } from "./garbageCollection";
8
8
  export { IPendingFlush, IPendingLocalState, IPendingMessage, IPendingState, } from "./pendingStateManager";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,yBAAyB,EACzB,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACH,QAAQ,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,aAAa,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACH,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EAClB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC9G,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,sBAAsB,EACtB,yBAAyB,EACzB,+BAA+B,EAC/B,sCAAsC,EACtC,sCAAsC,EACtC,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,8BAA8B,EAC9B,0BAA0B,EAC1B,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACH,QAAQ,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,aAAa,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EACH,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,0BAA0B,EAC1B,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,EACzB,kBAAkB,EAClB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,aAAa,EACb,qBAAqB,EACrB,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC9G,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.unpackRuntimeMessage = exports.neverCancelledSummaryToken = exports.SummaryCollection = exports.ISummarizer = exports.Summarizer = exports.FluidDataStoreRegistry = exports.CompressionAlgorithms = exports.DefaultSummaryConfiguration = exports.RuntimeHeaders = exports.ContainerRuntime = exports.agentSchedulerId = exports.RuntimeMessage = exports.isRuntimeMessage = exports.ContainerMessageType = void 0;
7
+ exports.unpackRuntimeMessage = exports.neverCancelledSummaryToken = exports.SummaryCollection = exports.ISummarizer = exports.Summarizer = exports.FluidDataStoreRegistry = exports.CompressionAlgorithms = exports.DefaultSummaryConfiguration = exports.TombstoneResponseHeaderKey = exports.AllowTombstoneRequestHeaderKey = exports.RuntimeHeaders = exports.ContainerRuntime = exports.agentSchedulerId = exports.RuntimeMessage = exports.isRuntimeMessage = exports.ContainerMessageType = void 0;
8
8
  var containerRuntime_1 = require("./containerRuntime");
9
9
  Object.defineProperty(exports, "ContainerMessageType", { enumerable: true, get: function () { return containerRuntime_1.ContainerMessageType; } });
10
10
  Object.defineProperty(exports, "isRuntimeMessage", { enumerable: true, get: function () { return containerRuntime_1.isRuntimeMessage; } });
@@ -12,6 +12,8 @@ Object.defineProperty(exports, "RuntimeMessage", { enumerable: true, get: functi
12
12
  Object.defineProperty(exports, "agentSchedulerId", { enumerable: true, get: function () { return containerRuntime_1.agentSchedulerId; } });
13
13
  Object.defineProperty(exports, "ContainerRuntime", { enumerable: true, get: function () { return containerRuntime_1.ContainerRuntime; } });
14
14
  Object.defineProperty(exports, "RuntimeHeaders", { enumerable: true, get: function () { return containerRuntime_1.RuntimeHeaders; } });
15
+ Object.defineProperty(exports, "AllowTombstoneRequestHeaderKey", { enumerable: true, get: function () { return containerRuntime_1.AllowTombstoneRequestHeaderKey; } });
16
+ Object.defineProperty(exports, "TombstoneResponseHeaderKey", { enumerable: true, get: function () { return containerRuntime_1.TombstoneResponseHeaderKey; } });
15
17
  Object.defineProperty(exports, "DefaultSummaryConfiguration", { enumerable: true, get: function () { return containerRuntime_1.DefaultSummaryConfiguration; } });
16
18
  Object.defineProperty(exports, "CompressionAlgorithms", { enumerable: true, get: function () { return containerRuntime_1.CompressionAlgorithms; } });
17
19
  var dataStoreRegistry_1 = require("./dataStoreRegistry");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,uDAoB4B;AAnBxB,wHAAA,oBAAoB,OAAA;AAUpB,oHAAA,gBAAgB,OAAA;AAChB,kHAAA,cAAc,OAAA;AACd,oHAAA,gBAAgB,OAAA;AAChB,oHAAA,gBAAgB,OAAA;AAChB,kHAAA,cAAc,OAAA;AAEd,+HAAA,2BAA2B,OAAA;AAE3B,yHAAA,qBAAqB,OAAA;AAEzB,yDAA6D;AAApD,2HAAA,sBAAsB,OAAA;AAU/B,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,qDA4B2B;AAVvB,8GAAA,WAAW,OAAA;AAWf,yDAW6B;AADzB,sHAAA,iBAAiB,OAAA;AAErB,+EAA8G;AAAnE,0IAAA,0BAA0B,OAAA;AACrE,6CAAiE;AAA5C,mHAAA,oBAAoB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n ContainerMessageType,\n ContainerRuntimeMessage,\n IGCRuntimeOptions,\n ISummaryRuntimeOptions,\n ISummaryBaseConfiguration,\n ISummaryConfigurationHeuristics,\n ISummaryConfigurationDisableSummarizer,\n ISummaryConfigurationDisableHeuristics,\n IContainerRuntimeOptions,\n IRootSummaryTreeWithStats,\n isRuntimeMessage,\n RuntimeMessage,\n agentSchedulerId,\n ContainerRuntime,\n RuntimeHeaders,\n ISummaryConfiguration,\n DefaultSummaryConfiguration,\n ICompressionRuntimeOptions,\n CompressionAlgorithms,\n} from \"./containerRuntime\";\nexport { FluidDataStoreRegistry } from \"./dataStoreRegistry\";\nexport {\n IGCStats,\n} from \"./garbageCollection\";\nexport {\n IPendingFlush,\n IPendingLocalState,\n IPendingMessage,\n IPendingState,\n} from \"./pendingStateManager\";\nexport { Summarizer } from \"./summarizer\";\nexport {\n EnqueueSummarizeResult,\n IAckSummaryResult,\n IBaseSummarizeResult,\n IBroadcastSummaryResult,\n ICancellationToken,\n IConnectableRuntime,\n IEnqueueSummarizeOptions,\n IGenerateSummaryTreeResult,\n IGeneratedSummaryStats,\n INackSummaryResult,\n IOnDemandSummarizeOptions,\n IProvideSummarizer,\n IRefreshSummaryAckOptions,\n ISubmitSummaryOpResult,\n ISubmitSummaryOptions,\n ISummarizeOptions,\n ISummarizeResults,\n ISummarizer,\n ISummarizerEvents,\n ISummarizerInternalsProvider,\n ISummarizerRuntime,\n ISummarizingWarning,\n ISummaryCancellationToken,\n IUploadSummaryResult,\n SubmitSummaryResult,\n SummarizeResultPart,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nexport {\n IAckedSummary,\n IClientSummaryWatcher,\n ISummary,\n ISummaryCollectionOpEvents,\n ISummaryAckMessage,\n ISummaryNackMessage,\n ISummaryOpMessage,\n OpActionEventListener,\n OpActionEventName,\n SummaryCollection,\n} from \"./summaryCollection\";\nexport { ICancellableSummarizerController, neverCancelledSummaryToken } from \"./runWhileConnectedCoordinator\";\nexport { IChunkedOp, unpackRuntimeMessage } from \"./opLifecycle\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,uDAsB4B;AArBxB,wHAAA,oBAAoB,OAAA;AAUpB,oHAAA,gBAAgB,OAAA;AAChB,kHAAA,cAAc,OAAA;AACd,oHAAA,gBAAgB,OAAA;AAChB,oHAAA,gBAAgB,OAAA;AAChB,kHAAA,cAAc,OAAA;AACd,kIAAA,8BAA8B,OAAA;AAC9B,8HAAA,0BAA0B,OAAA;AAE1B,+HAAA,2BAA2B,OAAA;AAE3B,yHAAA,qBAAqB,OAAA;AAEzB,yDAA6D;AAApD,2HAAA,sBAAsB,OAAA;AAU/B,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,qDA4B2B;AAVvB,8GAAA,WAAW,OAAA;AAWf,yDAW6B;AADzB,sHAAA,iBAAiB,OAAA;AAErB,+EAA8G;AAAnE,0IAAA,0BAA0B,OAAA;AACrE,6CAAiE;AAA5C,mHAAA,oBAAoB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n ContainerMessageType,\n ContainerRuntimeMessage,\n IGCRuntimeOptions,\n ISummaryRuntimeOptions,\n ISummaryBaseConfiguration,\n ISummaryConfigurationHeuristics,\n ISummaryConfigurationDisableSummarizer,\n ISummaryConfigurationDisableHeuristics,\n IContainerRuntimeOptions,\n IRootSummaryTreeWithStats,\n isRuntimeMessage,\n RuntimeMessage,\n agentSchedulerId,\n ContainerRuntime,\n RuntimeHeaders,\n AllowTombstoneRequestHeaderKey,\n TombstoneResponseHeaderKey,\n ISummaryConfiguration,\n DefaultSummaryConfiguration,\n ICompressionRuntimeOptions,\n CompressionAlgorithms,\n} from \"./containerRuntime\";\nexport { FluidDataStoreRegistry } from \"./dataStoreRegistry\";\nexport {\n IGCStats,\n} from \"./garbageCollection\";\nexport {\n IPendingFlush,\n IPendingLocalState,\n IPendingMessage,\n IPendingState,\n} from \"./pendingStateManager\";\nexport { Summarizer } from \"./summarizer\";\nexport {\n EnqueueSummarizeResult,\n IAckSummaryResult,\n IBaseSummarizeResult,\n IBroadcastSummaryResult,\n ICancellationToken,\n IConnectableRuntime,\n IEnqueueSummarizeOptions,\n IGenerateSummaryTreeResult,\n IGeneratedSummaryStats,\n INackSummaryResult,\n IOnDemandSummarizeOptions,\n IProvideSummarizer,\n IRefreshSummaryAckOptions,\n ISubmitSummaryOpResult,\n ISubmitSummaryOptions,\n ISummarizeOptions,\n ISummarizeResults,\n ISummarizer,\n ISummarizerEvents,\n ISummarizerInternalsProvider,\n ISummarizerRuntime,\n ISummarizingWarning,\n ISummaryCancellationToken,\n IUploadSummaryResult,\n SubmitSummaryResult,\n SummarizeResultPart,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nexport {\n IAckedSummary,\n IClientSummaryWatcher,\n ISummary,\n ISummaryCollectionOpEvents,\n ISummaryAckMessage,\n ISummaryNackMessage,\n ISummaryOpMessage,\n OpActionEventListener,\n OpActionEventName,\n SummaryCollection,\n} from \"./summaryCollection\";\nexport { ICancellableSummarizerController, neverCancelledSummaryToken } from \"./runWhileConnectedCoordinator\";\nexport { IChunkedOp, unpackRuntimeMessage } from \"./opLifecycle\";\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/container-runtime";
8
- export declare const pkgVersion = "2.0.0-internal.2.3.0";
8
+ export declare const pkgVersion = "2.0.0-internal.2.4.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/container-runtime";
11
- exports.pkgVersion = "2.0.0-internal.2.3.0";
11
+ exports.pkgVersion = "2.0.0-internal.2.4.0";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,mCAAmC,CAAC;AAC9C,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-internal.2.3.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,mCAAmC,CAAC;AAC9C,QAAA,UAAU,GAAG,sBAAsB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-internal.2.4.0\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../src/summarizer.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 { EventEmitter } from \"events\";\nimport { Deferred } from \"@fluidframework/common-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ILoader, LoaderHeader } from \"@fluidframework/container-definitions\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { DriverErrorType, DriverHeader } from \"@fluidframework/driver-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport {\n ChildLogger,\n IFluidErrorBase,\n isFluidError,\n LoggingError,\n wrapErrorAndLog,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n FluidObject,\n IFluidHandleContext,\n IFluidHandle,\n IRequest,\n} from \"@fluidframework/core-interfaces\";\nimport { ISummaryConfiguration } from \"./containerRuntime\";\nimport { ICancellableSummarizerController } from \"./runWhileConnectedCoordinator\";\nimport { summarizerClientType } from \"./summarizerClientElection\";\nimport { IAckedSummary, SummaryCollection } from \"./summaryCollection\";\nimport { SummarizerHandle } from \"./summarizerHandle\";\nimport { RunningSummarizer } from \"./runningSummarizer\";\nimport {\n ISummarizer,\n ISummarizerInternalsProvider,\n ISummarizerRuntime,\n ISummarizingWarning,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nimport { SummarizeHeuristicData } from \"./summarizerHeuristics\";\nimport { SummarizeResultBuilder } from \"./summaryGenerator\";\nimport { IConnectableRuntime } from \".\";\n\nconst summarizingError = \"summarizingError\";\n\nexport class SummarizingWarning extends LoggingError implements ISummarizingWarning, IFluidErrorBase {\n readonly errorType = summarizingError;\n readonly canRetry = true;\n\n constructor(\n errorMessage: string,\n readonly logged: boolean = false,\n ) {\n super(errorMessage);\n }\n\n static wrap(error: any, logged: boolean = false, logger: ITelemetryLogger) {\n const newErrorFn = (errMsg: string) => new SummarizingWarning(errMsg, logged);\n return wrapErrorAndLog<SummarizingWarning>(error, newErrorFn, logger);\n }\n}\n\nexport const createSummarizingWarning =\n (errorMessage: string, logged: boolean) => new SummarizingWarning(errorMessage, logged);\n\n/**\n * Summarizer is responsible for coordinating when to generate and send summaries.\n * It is the main entry point for summary work.\n * It is created only by summarizing container (i.e. one with clientType === \"summarizer\")\n */\nexport class Summarizer extends EventEmitter implements ISummarizer {\n public get IFluidLoadable() { return this; }\n public get ISummarizer() { return this; }\n\n private readonly logger: ITelemetryLogger;\n private runningSummarizer?: RunningSummarizer;\n private _disposed: boolean = false;\n private starting: boolean = false;\n\n private readonly innerHandle: IFluidHandle<this>;\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n private readonly stopDeferred = new Deferred<SummarizerStopReason>();\n\n constructor(\n url: string,\n /** Reference to runtime that created this object.\n * i.e. runtime with clientType === \"summarizer\"\n */\n private readonly runtime: ISummarizerRuntime,\n private readonly configurationGetter: () => ISummaryConfiguration,\n /** Represents an object that can generate summary.\n * In practical terms, it's same runtime (this.runtime) with clientType === \"summarizer\".\n */\n private readonly internalsProvider: ISummarizerInternalsProvider,\n handleContext: IFluidHandleContext,\n public readonly summaryCollection: SummaryCollection,\n private readonly runCoordinatorCreateFn:\n (runtime: IConnectableRuntime) => Promise<ICancellableSummarizerController>,\n ) {\n super();\n this.logger = ChildLogger.create(this.runtime.logger, \"Summarizer\");\n this.innerHandle = new SummarizerHandle(this, url, handleContext);\n }\n\n /**\n * Creates a Summarizer and its underlying client.\n * Note that different implementations of ILoader will handle the URL differently.\n * ILoader provided by a ContainerRuntime is a RelativeLoader, which will treat URL's\n * starting with \"/\" as relative to the Container. The general ILoader\n * interface will expect an absolute URL and will not handle \"/\".\n * @param loader - the loader that resolves the request\n * @param url - the URL used to resolve the container\n */\n public static async create(\n loader: ILoader,\n url: string): Promise<ISummarizer> {\n const request: IRequest = {\n headers: {\n [LoaderHeader.cache]: false,\n [LoaderHeader.clientDetails]: {\n capabilities: { interactive: false },\n type: summarizerClientType,\n },\n [DriverHeader.summarizingClient]: true,\n [LoaderHeader.reconnect]: false,\n },\n url,\n };\n\n const resolvedContainer = await loader.resolve(request);\n const fluidObject =\n await requestFluidObject<FluidObject<ISummarizer>>(resolvedContainer, { url: \"_summarizer\" });\n if (fluidObject.ISummarizer === undefined) {\n throw new UsageError(\"Fluid object does not implement ISummarizer\");\n }\n return fluidObject.ISummarizer;\n }\n\n public async run(onBehalfOf: string): Promise<SummarizerStopReason> {\n try {\n return await this.runCore(onBehalfOf);\n } catch (error) {\n this.stop(\"summarizerException\");\n throw SummarizingWarning.wrap(error, false /* logged */, this.logger);\n } finally {\n this.close();\n }\n }\n\n /**\n * Stops the summarizer from running. This will complete\n * the run promise, and also close the container.\n * @param reason - reason code for stopping\n */\n public stop(reason: SummarizerStopReason) {\n this.stopDeferred.resolve(reason);\n }\n\n public close() {\n // This will result in \"summarizerClientDisconnected\" stop reason recorded in telemetry,\n // unless stop() was called earlier\n this.dispose();\n (this.runtime.disposeFn ?? this.runtime.closeFn)()\n }\n\n private async runCore(onBehalfOf: string): Promise<SummarizerStopReason> {\n const runCoordinator: ICancellableSummarizerController = await this.runCoordinatorCreateFn(this.runtime);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopP = Promise.race([runCoordinator.waitCancelled, this.stopDeferred.promise]);\n void stopP.then((reason) => {\n this.logger.sendTelemetryEvent({\n eventName: \"StoppingSummarizer\",\n onBehalfOf,\n reason,\n });\n });\n\n if (runCoordinator.cancelled) {\n return runCoordinator.waitCancelled;\n }\n\n const runningSummarizer = await this.start(onBehalfOf, runCoordinator);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopReason = await stopP;\n\n // There are two possible approaches here:\n // 1. Propagate cancellation from this.stopDeferred to runCoordinator. This will ensure that we move to the exit\n // faster, including breaking out of the RunningSummarizer.trySummarize() faster.\n // We could create new coordinator and pass it to waitStop() -> trySummarizeOnce(\"lastSummary\") flow.\n // The con of this approach is that we might cancel active summary, and lastSummary will fail because it\n // did not wait for ack/nack from previous summary. Plus we disregard any 429 kind of info from service\n // that way (i.e. trySummarize() loop might have been waiting for 5 min because storage told us so).\n // In general, it's more wasted resources.\n // 2. We can not do it and make waitStop() do last summary only if there was no active summary. This ensures\n // that client behaves properly (from server POV) and we do not waste resources. But, it may mean we wait\n // substantially longer for trySummarize() retries to play out and thus this summary loop may run into\n // conflict with new summarizer client starting on different client.\n // As of now, #2 is implemented. It's more forward looking, as issue #7279 suggests changing design for new\n // summarizer client to not be created until current summarizer fully moves to exit, and that would reduce\n // cons of #2 substantially.\n\n // Cleanup after running\n await runningSummarizer.waitStop(\n !runCoordinator.cancelled && Summarizer.stopReasonCanRunLastSummary(stopReason));\n\n // Propagate reason and ensure that if someone is waiting for cancellation token, they are moving to exit\n runCoordinator.stop(stopReason);\n\n return stopReason;\n }\n\n /**\n * Should we try to run a last summary for the given stop reason?\n * Currently only allows \"parentNotConnected\"\n * @param stopReason - SummarizerStopReason\n * @returns - true if the stop reason can run a last summary\n */\n public static stopReasonCanRunLastSummary(stopReason: SummarizerStopReason): boolean {\n return stopReason === \"parentNotConnected\";\n }\n\n /**\n * Put the summarizer in a started state, including creating and initializing the RunningSummarizer.\n * The start request can come either from the SummaryManager (in the auto-summarize case) or from the user\n * (in the on-demand case).\n * @param onBehalfOf - ID of the client that requested that the summarizer start\n * @param runCoordinator - cancellation token\n * @param newConfig - Summary configuration to override the existing config when invoking the RunningSummarizer.\n * @returns - Promise that is fulfilled when the RunningSummarizer is ready\n */\n private async start(\n onBehalfOf: string,\n runCoordinator: ICancellableSummarizerController): Promise<RunningSummarizer> {\n if (this.runningSummarizer) {\n if (this.runningSummarizer.disposed) {\n throw new UsageError(\"Starting a disposed summarizer\");\n }\n return this.runningSummarizer;\n }\n if (this.starting) {\n throw new UsageError(\"Attempting to start a summarizer that is already starting\");\n }\n this.starting = true;\n // Initialize values and first ack (time is not exact)\n this.logger.sendTelemetryEvent({\n eventName: \"RunningSummarizer\",\n onBehalfOf,\n initSummarySeqNumber: this.runtime.deltaManager.initialSequenceNumber,\n config: JSON.stringify(this.configurationGetter()),\n });\n\n // Summarizing container ID (with clientType === \"summarizer\")\n const clientId = this.runtime.clientId;\n if (clientId === undefined) {\n throw new UsageError(\"clientId should be defined if connected.\");\n }\n\n const runningSummarizer = await RunningSummarizer.start(\n this.logger,\n this.summaryCollection.createWatcher(clientId),\n this.configurationGetter(),\n async (...args) => this.internalsProvider.submitSummary(...args), // submitSummaryCallback\n new SummarizeHeuristicData(\n this.runtime.deltaManager.lastSequenceNumber,\n { /** summary attempt baseline for heuristics */\n refSequenceNumber: this.runtime.deltaManager.initialSequenceNumber,\n summaryTime: Date.now(),\n } as const,\n ),\n (errorMessage: string) => {\n if (!this._disposed) {\n this.logger.sendErrorEvent({ eventName: \"summarizingError\" },\n createSummarizingWarning(errorMessage, true));\n }\n },\n this.summaryCollection,\n runCoordinator /* cancellationToken */,\n (reason) => runCoordinator.stop(reason), /* stopSummarizerCallback */\n this.runtime,\n );\n this.runningSummarizer = runningSummarizer;\n this.starting = false;\n\n // Handle summary acks\n // Note: no exceptions are thrown from handleSummaryAcks handler as it handles all exceptions\n this.handleSummaryAcks().catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"HandleSummaryAckFatalError\" }, error);\n });\n\n return runningSummarizer;\n }\n\n /**\n * Disposes of resources after running. This cleanup will\n * clear any outstanding timers and reset some of the state\n * properties.\n * Called by ContainerRuntime when it is disposed, as well as at the end the run().\n */\n public dispose() {\n // Given that the call can come from own ContainerRuntime, ensure that we stop all the processes.\n this.stop(\"summarizerClientDisconnected\");\n\n this._disposed = true;\n if (this.runningSummarizer) {\n this.runningSummarizer.dispose();\n this.runningSummarizer = undefined;\n }\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n try {\n if (this._disposed || this.runningSummarizer?.disposed) {\n throw new UsageError(\"Summarizer is already disposed.\");\n }\n if (this.runtime.summarizerClientId !== undefined &&\n this.runtime.summarizerClientId !== this.runtime.clientId) {\n // If there is an elected summarizer, and it's not this one, don't allow on-demand summary.\n // This is to prevent the on-demand summary and heuristic-based summary from stepping on\n // each other.\n throw new UsageError(\"On-demand summary attempted while an elected summarizer is present\");\n }\n const builder = new SummarizeResultBuilder();\n if (this.runningSummarizer) {\n // Summarizer is already running. Go ahead and start.\n return this.runningSummarizer.summarizeOnDemand(builder, ...args);\n }\n\n // Summarizer isn't running, so we need to start it, which is an async operation.\n // Manage the promise related to creating the cancellation token here.\n // The promises related to starting, summarizing,\n // and submitting are communicated to the caller through the results builder.\n const coordinatorCreateP = this.runCoordinatorCreateFn(this.runtime);\n\n coordinatorCreateP.then((runCoordinator) => {\n // Successfully created the cancellation token. Start the summarizer.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const startP = this.start(this.runtime.clientId!, runCoordinator);\n startP.then(async (runningSummarizer) => {\n // Successfully started the summarizer. Run it.\n runningSummarizer.summarizeOnDemand(builder, ...args);\n // Wait for a command to stop or loss of connectivity before tearing down the summarizer and client.\n const stopReason = await Promise.race([this.stopDeferred.promise, runCoordinator.waitCancelled]);\n await runningSummarizer.waitStop(false);\n runCoordinator.stop(stopReason);\n this.close();\n }).catch((reason) => {\n builder.fail(\"Failed to start summarizer\", reason);\n });\n }).catch((reason) => {\n builder.fail(\"Failed to create cancellation token\", reason);\n });\n\n return builder.build();\n } catch (error) {\n throw SummarizingWarning.wrap(error, false /* logged */, this.logger);\n }\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this._disposed || this.runningSummarizer === undefined || this.runningSummarizer.disposed) {\n throw new UsageError(\"Summarizer is not running or already disposed.\");\n }\n return this.runningSummarizer.enqueueSummarize(...args);\n };\n\n private async handleSummaryAcks() {\n let refSequenceNumber = this.runtime.deltaManager.initialSequenceNumber;\n let ack: IAckedSummary | undefined;\n while (this.runningSummarizer) {\n const summaryLogger = this.runningSummarizer.tryGetCorrelatedLogger(refSequenceNumber) ?? this.logger;\n try {\n // Initialize ack with undefined if exception happens inside of waitSummaryAck on second iteration,\n // we record undefined, not previous handles.\n ack = undefined;\n ack = await this.summaryCollection.waitSummaryAck(refSequenceNumber);\n refSequenceNumber = ack.summaryOp.referenceSequenceNumber;\n const summaryOpHandle = ack.summaryOp.contents.handle;\n const summaryAckHandle = ack.summaryAck.contents.handle;\n // Make sure we block any summarizer from being executed/enqueued while\n // executing the refreshLatestSummaryAck.\n // https://dev.azure.com/fluidframework/internal/_workitems/edit/779\n await this.runningSummarizer.lockedRefreshSummaryAckAction(async () =>\n this.internalsProvider.refreshLatestSummaryAck({\n proposalHandle: summaryOpHandle,\n ackHandle: summaryAckHandle,\n summaryRefSeq: refSequenceNumber,\n summaryLogger },\n ).catch(async (error) => {\n // If the error is 404, so maybe the fetched version no longer exists on server. We just\n // ignore this error in that case, as that means we will have another summaryAck for the\n // latest version with which we will refresh the state. However in case of single commit\n // summary, we might me missing a summary ack, so in that case we are still fine as the\n // code in `submitSummary` function in container runtime, will refresh the latest state\n // by calling `refreshLatestSummaryAckFromServer` and we will be fine.\n if (isFluidError(error)\n && error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError) {\n summaryLogger.sendTelemetryEvent({\n eventName: \"HandleSummaryAckErrorIgnored\",\n referenceSequenceNumber: refSequenceNumber,\n proposalHandle: summaryOpHandle,\n ackHandle: summaryAckHandle,\n }, error);\n } else {\n throw error;\n }\n }),\n );\n } catch (error) {\n summaryLogger.sendErrorEvent({\n eventName: \"HandleSummaryAckError\",\n referenceSequenceNumber: refSequenceNumber,\n handle: ack?.summaryOp?.contents?.handle,\n ackHandle: ack?.summaryAck?.contents?.handle,\n }, error);\n }\n refSequenceNumber++;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../src/summarizer.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 { EventEmitter } from \"events\";\nimport { Deferred } from \"@fluidframework/common-utils\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { ILoader, LoaderHeader } from \"@fluidframework/container-definitions\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { DriverErrorType, DriverHeader } from \"@fluidframework/driver-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport {\n ChildLogger,\n IFluidErrorBase,\n isFluidError,\n LoggingError,\n wrapErrorAndLog,\n} from \"@fluidframework/telemetry-utils\";\nimport {\n FluidObject,\n IFluidHandleContext,\n IFluidHandle,\n IRequest,\n} from \"@fluidframework/core-interfaces\";\nimport { ISummaryConfiguration } from \"./containerRuntime\";\nimport { ICancellableSummarizerController } from \"./runWhileConnectedCoordinator\";\nimport { summarizerClientType } from \"./summarizerClientElection\";\nimport { IAckedSummary, SummaryCollection } from \"./summaryCollection\";\nimport { SummarizerHandle } from \"./summarizerHandle\";\nimport { RunningSummarizer } from \"./runningSummarizer\";\nimport {\n ISummarizer,\n ISummarizerInternalsProvider,\n ISummarizerRuntime,\n ISummarizingWarning,\n SummarizerStopReason,\n} from \"./summarizerTypes\";\nimport { SummarizeHeuristicData } from \"./summarizerHeuristics\";\nimport { SummarizeResultBuilder } from \"./summaryGenerator\";\nimport { IConnectableRuntime } from \".\";\n\nconst summarizingError = \"summarizingError\";\n\nexport class SummarizingWarning extends LoggingError implements ISummarizingWarning, IFluidErrorBase {\n readonly errorType = summarizingError;\n readonly canRetry = true;\n\n constructor(\n errorMessage: string,\n readonly logged: boolean = false,\n ) {\n super(errorMessage);\n }\n\n static wrap(error: any, logged: boolean = false, logger: ITelemetryLogger) {\n const newErrorFn = (errMsg: string) => new SummarizingWarning(errMsg, logged);\n return wrapErrorAndLog<SummarizingWarning>(error, newErrorFn, logger);\n }\n}\n\nexport const createSummarizingWarning =\n (errorMessage: string, logged: boolean) => new SummarizingWarning(errorMessage, logged);\n\n/**\n * Summarizer is responsible for coordinating when to generate and send summaries.\n * It is the main entry point for summary work.\n * It is created only by summarizing container (i.e. one with clientType === \"summarizer\")\n */\nexport class Summarizer extends EventEmitter implements ISummarizer {\n public get IFluidLoadable() { return this; }\n public get ISummarizer() { return this; }\n\n private readonly logger: ITelemetryLogger;\n private runningSummarizer?: RunningSummarizer;\n private _disposed: boolean = false;\n private starting: boolean = false;\n\n private readonly innerHandle: IFluidHandle<this>;\n\n public get handle(): IFluidHandle<this> { return this.innerHandle; }\n private readonly stopDeferred = new Deferred<SummarizerStopReason>();\n\n constructor(\n url: string,\n /** Reference to runtime that created this object.\n * i.e. runtime with clientType === \"summarizer\"\n */\n private readonly runtime: ISummarizerRuntime,\n private readonly configurationGetter: () => ISummaryConfiguration,\n /** Represents an object that can generate summary.\n * In practical terms, it's same runtime (this.runtime) with clientType === \"summarizer\".\n */\n private readonly internalsProvider: ISummarizerInternalsProvider,\n handleContext: IFluidHandleContext,\n public readonly summaryCollection: SummaryCollection,\n private readonly runCoordinatorCreateFn:\n (runtime: IConnectableRuntime) => Promise<ICancellableSummarizerController>,\n ) {\n super();\n this.logger = ChildLogger.create(this.runtime.logger, \"Summarizer\");\n this.innerHandle = new SummarizerHandle(this, url, handleContext);\n }\n\n /**\n * Creates a Summarizer and its underlying client.\n * Note that different implementations of ILoader will handle the URL differently.\n * ILoader provided by a ContainerRuntime is a RelativeLoader, which will treat URL's\n * starting with \"/\" as relative to the Container. The general ILoader\n * interface will expect an absolute URL and will not handle \"/\".\n * @param loader - the loader that resolves the request\n * @param url - the URL used to resolve the container\n */\n public static async create(\n loader: ILoader,\n url: string): Promise<ISummarizer> {\n const request: IRequest = {\n headers: {\n [LoaderHeader.cache]: false,\n [LoaderHeader.clientDetails]: {\n capabilities: { interactive: false },\n type: summarizerClientType,\n },\n [DriverHeader.summarizingClient]: true,\n [LoaderHeader.reconnect]: false,\n },\n url,\n };\n\n const resolvedContainer = await loader.resolve(request);\n const fluidObject =\n await requestFluidObject<FluidObject<ISummarizer>>(resolvedContainer, { url: \"_summarizer\" });\n if (fluidObject.ISummarizer === undefined) {\n throw new UsageError(\"Fluid object does not implement ISummarizer\");\n }\n return fluidObject.ISummarizer;\n }\n\n public async run(onBehalfOf: string): Promise<SummarizerStopReason> {\n try {\n return await this.runCore(onBehalfOf);\n } catch (error) {\n this.stop(\"summarizerException\");\n throw SummarizingWarning.wrap(error, false /* logged */, this.logger);\n } finally {\n this.close();\n }\n }\n\n /**\n * Stops the summarizer from running. This will complete\n * the run promise, and also close the container.\n * @param reason - reason code for stopping\n */\n public stop(reason: SummarizerStopReason) {\n this.stopDeferred.resolve(reason);\n }\n\n public close() {\n // This will result in \"summarizerClientDisconnected\" stop reason recorded in telemetry,\n // unless stop() was called earlier\n this.dispose();\n (this.runtime.disposeFn ?? this.runtime.closeFn)();\n }\n\n private async runCore(onBehalfOf: string): Promise<SummarizerStopReason> {\n const runCoordinator: ICancellableSummarizerController = await this.runCoordinatorCreateFn(this.runtime);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopP = Promise.race([runCoordinator.waitCancelled, this.stopDeferred.promise]);\n void stopP.then((reason) => {\n this.logger.sendTelemetryEvent({\n eventName: \"StoppingSummarizer\",\n onBehalfOf,\n reason,\n });\n });\n\n if (runCoordinator.cancelled) {\n return runCoordinator.waitCancelled;\n }\n\n const runningSummarizer = await this.start(onBehalfOf, runCoordinator);\n\n // Wait for either external signal to cancel, or loss of connectivity.\n const stopReason = await stopP;\n\n // There are two possible approaches here:\n // 1. Propagate cancellation from this.stopDeferred to runCoordinator. This will ensure that we move to the exit\n // faster, including breaking out of the RunningSummarizer.trySummarize() faster.\n // We could create new coordinator and pass it to waitStop() -> trySummarizeOnce(\"lastSummary\") flow.\n // The con of this approach is that we might cancel active summary, and lastSummary will fail because it\n // did not wait for ack/nack from previous summary. Plus we disregard any 429 kind of info from service\n // that way (i.e. trySummarize() loop might have been waiting for 5 min because storage told us so).\n // In general, it's more wasted resources.\n // 2. We can not do it and make waitStop() do last summary only if there was no active summary. This ensures\n // that client behaves properly (from server POV) and we do not waste resources. But, it may mean we wait\n // substantially longer for trySummarize() retries to play out and thus this summary loop may run into\n // conflict with new summarizer client starting on different client.\n // As of now, #2 is implemented. It's more forward looking, as issue #7279 suggests changing design for new\n // summarizer client to not be created until current summarizer fully moves to exit, and that would reduce\n // cons of #2 substantially.\n\n // Cleanup after running\n await runningSummarizer.waitStop(\n !runCoordinator.cancelled && Summarizer.stopReasonCanRunLastSummary(stopReason));\n\n // Propagate reason and ensure that if someone is waiting for cancellation token, they are moving to exit\n runCoordinator.stop(stopReason);\n\n return stopReason;\n }\n\n /**\n * Should we try to run a last summary for the given stop reason?\n * Currently only allows \"parentNotConnected\"\n * @param stopReason - SummarizerStopReason\n * @returns - true if the stop reason can run a last summary\n */\n public static stopReasonCanRunLastSummary(stopReason: SummarizerStopReason): boolean {\n return stopReason === \"parentNotConnected\";\n }\n\n /**\n * Put the summarizer in a started state, including creating and initializing the RunningSummarizer.\n * The start request can come either from the SummaryManager (in the auto-summarize case) or from the user\n * (in the on-demand case).\n * @param onBehalfOf - ID of the client that requested that the summarizer start\n * @param runCoordinator - cancellation token\n * @param newConfig - Summary configuration to override the existing config when invoking the RunningSummarizer.\n * @returns - Promise that is fulfilled when the RunningSummarizer is ready\n */\n private async start(\n onBehalfOf: string,\n runCoordinator: ICancellableSummarizerController): Promise<RunningSummarizer> {\n if (this.runningSummarizer) {\n if (this.runningSummarizer.disposed) {\n throw new UsageError(\"Starting a disposed summarizer\");\n }\n return this.runningSummarizer;\n }\n if (this.starting) {\n throw new UsageError(\"Attempting to start a summarizer that is already starting\");\n }\n this.starting = true;\n // Initialize values and first ack (time is not exact)\n this.logger.sendTelemetryEvent({\n eventName: \"RunningSummarizer\",\n onBehalfOf,\n initSummarySeqNumber: this.runtime.deltaManager.initialSequenceNumber,\n config: JSON.stringify(this.configurationGetter()),\n });\n\n // Summarizing container ID (with clientType === \"summarizer\")\n const clientId = this.runtime.clientId;\n if (clientId === undefined) {\n throw new UsageError(\"clientId should be defined if connected.\");\n }\n\n const runningSummarizer = await RunningSummarizer.start(\n this.logger,\n this.summaryCollection.createWatcher(clientId),\n this.configurationGetter(),\n async (...args) => this.internalsProvider.submitSummary(...args), // submitSummaryCallback\n new SummarizeHeuristicData(\n this.runtime.deltaManager.lastSequenceNumber,\n { /** summary attempt baseline for heuristics */\n refSequenceNumber: this.runtime.deltaManager.initialSequenceNumber,\n summaryTime: Date.now(),\n } as const,\n ),\n (errorMessage: string) => {\n if (!this._disposed) {\n this.logger.sendErrorEvent({ eventName: \"summarizingError\" },\n createSummarizingWarning(errorMessage, true));\n }\n },\n this.summaryCollection,\n runCoordinator /* cancellationToken */,\n (reason) => runCoordinator.stop(reason), /* stopSummarizerCallback */\n this.runtime,\n );\n this.runningSummarizer = runningSummarizer;\n this.starting = false;\n\n // Handle summary acks\n // Note: no exceptions are thrown from handleSummaryAcks handler as it handles all exceptions\n this.handleSummaryAcks().catch((error) => {\n this.logger.sendErrorEvent({ eventName: \"HandleSummaryAckFatalError\" }, error);\n });\n\n return runningSummarizer;\n }\n\n /**\n * Disposes of resources after running. This cleanup will\n * clear any outstanding timers and reset some of the state\n * properties.\n * Called by ContainerRuntime when it is disposed, as well as at the end the run().\n */\n public dispose() {\n // Given that the call can come from own ContainerRuntime, ensure that we stop all the processes.\n this.stop(\"summarizerClientDisconnected\");\n\n this._disposed = true;\n if (this.runningSummarizer) {\n this.runningSummarizer.dispose();\n this.runningSummarizer = undefined;\n }\n }\n\n public readonly summarizeOnDemand: ISummarizer[\"summarizeOnDemand\"] = (...args) => {\n try {\n if (this._disposed || this.runningSummarizer?.disposed) {\n throw new UsageError(\"Summarizer is already disposed.\");\n }\n if (this.runtime.summarizerClientId !== undefined &&\n this.runtime.summarizerClientId !== this.runtime.clientId) {\n // If there is an elected summarizer, and it's not this one, don't allow on-demand summary.\n // This is to prevent the on-demand summary and heuristic-based summary from stepping on\n // each other.\n throw new UsageError(\"On-demand summary attempted while an elected summarizer is present\");\n }\n const builder = new SummarizeResultBuilder();\n if (this.runningSummarizer) {\n // Summarizer is already running. Go ahead and start.\n return this.runningSummarizer.summarizeOnDemand(builder, ...args);\n }\n\n // Summarizer isn't running, so we need to start it, which is an async operation.\n // Manage the promise related to creating the cancellation token here.\n // The promises related to starting, summarizing,\n // and submitting are communicated to the caller through the results builder.\n const coordinatorCreateP = this.runCoordinatorCreateFn(this.runtime);\n\n coordinatorCreateP.then((runCoordinator) => {\n // Successfully created the cancellation token. Start the summarizer.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const startP = this.start(this.runtime.clientId!, runCoordinator);\n startP.then(async (runningSummarizer) => {\n // Successfully started the summarizer. Run it.\n runningSummarizer.summarizeOnDemand(builder, ...args);\n // Wait for a command to stop or loss of connectivity before tearing down the summarizer and client.\n const stopReason = await Promise.race([this.stopDeferred.promise, runCoordinator.waitCancelled]);\n await runningSummarizer.waitStop(false);\n runCoordinator.stop(stopReason);\n this.close();\n }).catch((reason) => {\n builder.fail(\"Failed to start summarizer\", reason);\n });\n }).catch((reason) => {\n builder.fail(\"Failed to create cancellation token\", reason);\n });\n\n return builder.build();\n } catch (error) {\n throw SummarizingWarning.wrap(error, false /* logged */, this.logger);\n }\n };\n\n public readonly enqueueSummarize: ISummarizer[\"enqueueSummarize\"] = (...args) => {\n if (this._disposed || this.runningSummarizer === undefined || this.runningSummarizer.disposed) {\n throw new UsageError(\"Summarizer is not running or already disposed.\");\n }\n return this.runningSummarizer.enqueueSummarize(...args);\n };\n\n private async handleSummaryAcks() {\n let refSequenceNumber = this.runtime.deltaManager.initialSequenceNumber;\n let ack: IAckedSummary | undefined;\n while (this.runningSummarizer) {\n const summaryLogger = this.runningSummarizer.tryGetCorrelatedLogger(refSequenceNumber) ?? this.logger;\n try {\n // Initialize ack with undefined if exception happens inside of waitSummaryAck on second iteration,\n // we record undefined, not previous handles.\n ack = undefined;\n ack = await this.summaryCollection.waitSummaryAck(refSequenceNumber);\n refSequenceNumber = ack.summaryOp.referenceSequenceNumber;\n const summaryOpHandle = ack.summaryOp.contents.handle;\n const summaryAckHandle = ack.summaryAck.contents.handle;\n // Make sure we block any summarizer from being executed/enqueued while\n // executing the refreshLatestSummaryAck.\n // https://dev.azure.com/fluidframework/internal/_workitems/edit/779\n await this.runningSummarizer.lockedRefreshSummaryAckAction(async () =>\n this.internalsProvider.refreshLatestSummaryAck({\n proposalHandle: summaryOpHandle,\n ackHandle: summaryAckHandle,\n summaryRefSeq: refSequenceNumber,\n summaryLogger },\n ).catch(async (error) => {\n // If the error is 404, so maybe the fetched version no longer exists on server. We just\n // ignore this error in that case, as that means we will have another summaryAck for the\n // latest version with which we will refresh the state. However in case of single commit\n // summary, we might me missing a summary ack, so in that case we are still fine as the\n // code in `submitSummary` function in container runtime, will refresh the latest state\n // by calling `refreshLatestSummaryAckFromServer` and we will be fine.\n if (isFluidError(error)\n && error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError) {\n summaryLogger.sendTelemetryEvent({\n eventName: \"HandleSummaryAckErrorIgnored\",\n referenceSequenceNumber: refSequenceNumber,\n proposalHandle: summaryOpHandle,\n ackHandle: summaryAckHandle,\n }, error);\n } else {\n throw error;\n }\n }),\n );\n } catch (error) {\n summaryLogger.sendErrorEvent({\n eventName: \"HandleSummaryAckError\",\n referenceSequenceNumber: refSequenceNumber,\n handle: ack?.summaryOp?.contents?.handle,\n ackHandle: ack?.summaryAck?.contents?.handle,\n }, error);\n }\n refSequenceNumber++;\n }\n }\n}\n"]}
@@ -60,6 +60,7 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
60
60
  private readonly blobRequested;
61
61
  private readonly addedBlobReference;
62
62
  private readonly runtime;
63
+ private readonly getCurrentReferenceTimestampMs;
63
64
  static readonly basePath = "_blobs";
64
65
  private static readonly redirectTableBlobName;
65
66
  private readonly mc;
@@ -85,7 +86,7 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
85
86
  private readonly opsInFlight;
86
87
  private readonly retryThrottler;
87
88
  /** If true, throw an error when a tombstone attachment blob is retrieved. */
88
- private readonly throwOnTombstoneUsage;
89
+ private readonly throwOnTombstoneLoad;
89
90
  /**
90
91
  * This stores IDs of tombstoned blobs.
91
92
  * Tombstone is a temporary feature that imitates a blob getting swept by garbage collection.
@@ -102,7 +103,7 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
102
103
  * knowledge of which they cannot request the blob from storage. It's important that this op is sequenced
103
104
  * before any ops that reference the local ID, otherwise, an invalid handle could be added to the document.
104
105
  */
105
- sendBlobAttachOp: (localId: string, storageId?: string) => void, blobRequested: (blobPath: string) => void, addedBlobReference: (fromNodePath: string, toNodePath: string) => void, runtime: IBlobManagerRuntime, stashedBlobs?: IPendingBlobs);
106
+ sendBlobAttachOp: (localId: string, storageId?: string) => void, blobRequested: (blobPath: string) => void, addedBlobReference: (fromNodePath: string, toNodePath: string) => void, runtime: IBlobManagerRuntime, stashedBlobs: IPendingBlobs | undefined, getCurrentReferenceTimestampMs: () => number | undefined);
106
107
  private get pendingOfflineUploads();
107
108
  get hasPendingOfflineUploads(): boolean;
108
109
  get hasPendingBlobs(): boolean;
@@ -146,6 +147,7 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
146
147
  * @param metadata - op metadata containing storage and/or local IDs
147
148
  */
148
149
  reSubmit(metadata: Record<string, unknown> | undefined): void;
150
+ private logTimeInfo;
149
151
  processBlobAttachOp(message: ISequencedDocumentMessage, local: boolean): void;
150
152
  /**
151
153
  * Reads blobs needed to load BlobManager from storage.
@@ -1 +1 @@
1
- {"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@ import { AttachState } from "@fluidframework/container-definitions";
9
9
  import { ChildLogger, loggerToMonitoringContext, PerformanceEvent } from "@fluidframework/telemetry-utils";
10
10
  import { Throttler, formExponentialFn } from "./throttler";
11
11
  import { summarizerClientType } from "./summarizerClientElection";
12
- import { throwOnTombstoneUsageKey } from "./garbageCollectionConstants";
12
+ import { throwOnTombstoneLoadKey } from "./garbageCollectionConstants";
13
13
  import { sendGCTombstoneEvent } from "./garbageCollectionTombstoneUtils";
14
14
  /**
15
15
  * This class represents blob (long string)
@@ -77,7 +77,7 @@ export class BlobManager extends TypedEventEmitter {
77
77
  sendBlobAttachOp,
78
78
  // To be called when a blob node is requested. blobPath is the path of the blob's node in GC's graph. It's
79
79
  // of the format `/<BlobManager.basePath>/<blobId>`.
80
- blobRequested, addedBlobReference, runtime, stashedBlobs = {}) {
80
+ blobRequested, addedBlobReference, runtime, stashedBlobs = {}, getCurrentReferenceTimestampMs) {
81
81
  super();
82
82
  this.routeContext = routeContext;
83
83
  this.getStorage = getStorage;
@@ -85,6 +85,7 @@ export class BlobManager extends TypedEventEmitter {
85
85
  this.blobRequested = blobRequested;
86
86
  this.addedBlobReference = addedBlobReference;
87
87
  this.runtime = runtime;
88
+ this.getCurrentReferenceTimestampMs = getCurrentReferenceTimestampMs;
88
89
  /**
89
90
  * Blobs which have not been uploaded or for which we have not yet seen a BlobAttach op round-trip.
90
91
  * Until we see the op round-trip, there is a possibility we may need to re-upload the blob, so
@@ -108,8 +109,8 @@ export class BlobManager extends TypedEventEmitter {
108
109
  this.tombstonedBlobs = new Set();
109
110
  this.mc = loggerToMonitoringContext(ChildLogger.create(this.runtime.logger, "BlobManager"));
110
111
  // Read the feature flag that tells whether to throw when a tombstone blob is requested.
111
- this.throwOnTombstoneUsage =
112
- this.mc.config.getBoolean(throwOnTombstoneUsageKey) === true &&
112
+ this.throwOnTombstoneLoad =
113
+ this.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&
113
114
  this.runtime.clientDetails.type !== summarizerClientType;
114
115
  this.runtime.on("disconnected", () => this.onDisconnected());
115
116
  this.redirectTable = this.load(snapshot);
@@ -183,13 +184,13 @@ export class BlobManager extends TypedEventEmitter {
183
184
  async getBlob(blobId) {
184
185
  const request = { url: blobId };
185
186
  if (this.tombstonedBlobs.has(blobId)) {
186
- const error = responseToException(createResponseError(404, "Blob removed by gc", request), request);
187
- const event = {
187
+ const error = responseToException(createResponseError(404, "Blob was deleted", request), request);
188
+ sendGCTombstoneEvent(this.mc, {
188
189
  eventName: "GC_Tombstone_Blob_Requested",
189
- url: request.url,
190
- };
191
- sendGCTombstoneEvent(this.mc, event, this.runtime.clientDetails.type === summarizerClientType, [BlobManager.basePath], error);
192
- if (this.throwOnTombstoneUsage) {
190
+ category: this.throwOnTombstoneLoad ? "error" : "generic",
191
+ isSummarizerClient: this.runtime.clientDetails.type === summarizerClientType,
192
+ }, [BlobManager.basePath], error);
193
+ if (this.throwOnTombstoneLoad) {
193
194
  throw error;
194
195
  }
195
196
  }
@@ -277,6 +278,9 @@ export class BlobManager extends TypedEventEmitter {
277
278
  assert((entry === null || entry === void 0 ? void 0 : entry.status) === PendingBlobStatus.OnlinePendingUpload ||
278
279
  (entry === null || entry === void 0 ? void 0 : entry.status) === PendingBlobStatus.OfflinePendingUpload, 0x386 /* Must have pending blob entry for uploaded blob */);
279
280
  entry.storageId = response.id;
281
+ entry.localUploadTime = Date.now();
282
+ entry.minTTLInSeconds = response.minTTLInSeconds;
283
+ entry.serverUploadTime = this.getCurrentReferenceTimestampMs();
280
284
  if (this.runtime.connected) {
281
285
  if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
282
286
  // Send a blob attach op. This serves two purposes:
@@ -284,6 +288,7 @@ export class BlobManager extends TypedEventEmitter {
284
288
  // until its storage ID is added to the next summary.
285
289
  // 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
286
290
  // blob from the server via the storage ID.
291
+ this.logTimeInfo(entry, "sendBlobAttachResolveTTL");
287
292
  this.sendBlobAttachOp(localId, response.id);
288
293
  if (this.storageIds.has(response.id)) {
289
294
  // The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
@@ -345,6 +350,7 @@ export class BlobManager extends TypedEventEmitter {
345
350
  * is called on reconnection.
346
351
  */
347
352
  if (entry.status !== PendingBlobStatus.OnlinePendingOp) {
353
+ this.logTimeInfo(entry, "sendBlobAttachTransitionOfflineTTL");
348
354
  this.sendBlobAttachOp(localId, entry.storageId);
349
355
  }
350
356
  entry.status = entry.status === PendingBlobStatus.OnlinePendingUpload
@@ -361,15 +367,42 @@ export class BlobManager extends TypedEventEmitter {
361
367
  assert(!!metadata, 0x38b /* Resubmitted ops must have metadata */);
362
368
  const { localId, blobId } = metadata;
363
369
  assert(localId !== undefined, 0x50d /* local ID not available on reSubmit */);
370
+ const pendingEntry = this.pendingBlobs.get(localId);
371
+ if (pendingEntry) {
372
+ this.logTimeInfo(pendingEntry, "sendBlobAttachResubmitTTL");
373
+ }
364
374
  if (!blobId) {
365
375
  // We submitted this op while offline. The blob should have been uploaded by now.
366
- const pendingEntry = this.pendingBlobs.get(localId);
367
376
  assert((pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.status) === PendingBlobStatus.OfflinePendingOp &&
368
377
  !!(pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.storageId), 0x38d /* blob must be uploaded before resubmitting BlobAttach op */);
369
378
  return this.sendBlobAttachOp(localId, pendingEntry.storageId);
370
379
  }
371
380
  return this.sendBlobAttachOp(localId, blobId);
372
381
  }
382
+ logTimeInfo(pendingEntry, eventName) {
383
+ var _a, _b;
384
+ let timeLapseSinceLocalUpload = 0;
385
+ let timeLapseSinceServerUpload = 0;
386
+ let expiredUsingLocalTime;
387
+ let expiredUsingServerTime;
388
+ if (pendingEntry.localUploadTime) {
389
+ timeLapseSinceLocalUpload = (Date.now() - pendingEntry.localUploadTime) / 1000;
390
+ expiredUsingLocalTime = ((_a = pendingEntry.minTTLInSeconds) !== null && _a !== void 0 ? _a : 0) - timeLapseSinceLocalUpload < 0 ? true : false;
391
+ }
392
+ if (pendingEntry.serverUploadTime) {
393
+ timeLapseSinceServerUpload = (Date.now() - pendingEntry.serverUploadTime) / 1000;
394
+ expiredUsingServerTime = ((_b = pendingEntry.minTTLInSeconds) !== null && _b !== void 0 ? _b : 0) - timeLapseSinceServerUpload < 0 ? true : false;
395
+ }
396
+ this.mc.logger.sendTelemetryEvent({
397
+ eventName,
398
+ entryStatus: pendingEntry.status,
399
+ timeLapseSinceLocalUpload,
400
+ timeLapseSinceServerUpload,
401
+ minTTLInSeconds: pendingEntry.minTTLInSeconds,
402
+ expiredUsingLocalTime,
403
+ expiredUsingServerTime,
404
+ });
405
+ }
373
406
  processBlobAttachOp(message, local) {
374
407
  var _a, _b;
375
408
  const localId = (_a = message.metadata) === null || _a === void 0 ? void 0 : _a.localId;