@fluidframework/container-runtime 2.0.0-internal.7.0.0 → 2.0.0-internal.7.2.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 (248) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/api-extractor.json +1 -1
  3. package/api-report/container-runtime.api.md +864 -0
  4. package/dist/blobManager.d.ts +4 -6
  5. package/dist/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager.js +42 -56
  7. package/dist/blobManager.js.map +1 -1
  8. package/dist/connectionTelemetry.d.ts.map +1 -1
  9. package/dist/connectionTelemetry.js +75 -42
  10. package/dist/connectionTelemetry.js.map +1 -1
  11. package/dist/containerRuntime.d.ts +90 -36
  12. package/dist/containerRuntime.d.ts.map +1 -1
  13. package/dist/containerRuntime.js +125 -59
  14. package/dist/containerRuntime.js.map +1 -1
  15. package/dist/dataStore.js +2 -2
  16. package/dist/dataStore.js.map +1 -1
  17. package/dist/dataStoreContext.d.ts +8 -2
  18. package/dist/dataStoreContext.d.ts.map +1 -1
  19. package/dist/dataStoreContext.js +15 -8
  20. package/dist/dataStoreContext.js.map +1 -1
  21. package/dist/dataStoreRegistry.d.ts +3 -0
  22. package/dist/dataStoreRegistry.d.ts.map +1 -1
  23. package/dist/dataStoreRegistry.js +3 -0
  24. package/dist/dataStoreRegistry.js.map +1 -1
  25. package/dist/dataStores.d.ts +0 -2
  26. package/dist/dataStores.d.ts.map +1 -1
  27. package/dist/dataStores.js +2 -7
  28. package/dist/dataStores.js.map +1 -1
  29. package/dist/deltaManagerProxyBase.d.ts +1 -1
  30. package/dist/deltaManagerProxyBase.d.ts.map +1 -1
  31. package/dist/deltaManagerProxyBase.js +2 -2
  32. package/dist/deltaManagerProxyBase.js.map +1 -1
  33. package/dist/error.d.ts.map +1 -1
  34. package/dist/error.js.map +1 -1
  35. package/dist/gc/garbageCollection.d.ts +6 -0
  36. package/dist/gc/garbageCollection.d.ts.map +1 -1
  37. package/dist/gc/garbageCollection.js +16 -3
  38. package/dist/gc/garbageCollection.js.map +1 -1
  39. package/dist/gc/gcConfigs.d.ts +1 -0
  40. package/dist/gc/gcConfigs.d.ts.map +1 -1
  41. package/dist/gc/gcConfigs.js +12 -2
  42. package/dist/gc/gcConfigs.js.map +1 -1
  43. package/dist/gc/gcDefinitions.d.ts +42 -11
  44. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  45. package/dist/gc/gcDefinitions.js +4 -1
  46. package/dist/gc/gcDefinitions.js.map +1 -1
  47. package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
  48. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  49. package/dist/gc/gcTelemetry.d.ts +2 -3
  50. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  51. package/dist/gc/gcTelemetry.js +7 -8
  52. package/dist/gc/gcTelemetry.js.map +1 -1
  53. package/dist/gc/index.d.ts +2 -2
  54. package/dist/gc/index.d.ts.map +1 -1
  55. package/dist/gc/index.js +1 -5
  56. package/dist/gc/index.js.map +1 -1
  57. package/dist/id-compressor/utilities.d.ts +3 -0
  58. package/dist/id-compressor/utilities.d.ts.map +1 -1
  59. package/dist/id-compressor/utilities.js +3 -0
  60. package/dist/id-compressor/utilities.js.map +1 -1
  61. package/dist/index.d.ts +4 -3
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +4 -1
  64. package/dist/index.js.map +1 -1
  65. package/dist/messageTypes.d.ts +4 -1
  66. package/dist/messageTypes.d.ts.map +1 -1
  67. package/dist/messageTypes.js +3 -0
  68. package/dist/messageTypes.js.map +1 -1
  69. package/dist/opLifecycle/definitions.d.ts +3 -0
  70. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  71. package/dist/opLifecycle/definitions.js.map +1 -1
  72. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  73. package/dist/opLifecycle/outbox.js +7 -2
  74. package/dist/opLifecycle/outbox.js.map +1 -1
  75. package/dist/packageVersion.d.ts +1 -1
  76. package/dist/packageVersion.js +1 -1
  77. package/dist/packageVersion.js.map +1 -1
  78. package/dist/pendingStateManager.d.ts.map +1 -1
  79. package/dist/pendingStateManager.js +3 -1
  80. package/dist/pendingStateManager.js.map +1 -1
  81. package/dist/scheduleManager.js +6 -2
  82. package/dist/scheduleManager.js.map +1 -1
  83. package/dist/summary/orderedClientElection.d.ts +4 -1
  84. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  85. package/dist/summary/orderedClientElection.js.map +1 -1
  86. package/dist/summary/runWhileConnectedCoordinator.d.ts +5 -0
  87. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  88. package/dist/summary/runWhileConnectedCoordinator.js +1 -0
  89. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  90. package/dist/summary/summarizer.d.ts +2 -0
  91. package/dist/summary/summarizer.d.ts.map +1 -1
  92. package/dist/summary/summarizer.js +15 -7
  93. package/dist/summary/summarizer.js.map +1 -1
  94. package/dist/summary/summarizerTypes.d.ts +94 -10
  95. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  96. package/dist/summary/summarizerTypes.js.map +1 -1
  97. package/dist/summary/summaryCollection.d.ts +16 -0
  98. package/dist/summary/summaryCollection.d.ts.map +1 -1
  99. package/dist/summary/summaryCollection.js +2 -0
  100. package/dist/summary/summaryCollection.js.map +1 -1
  101. package/dist/summary/summaryFormat.d.ts +10 -1
  102. package/dist/summary/summaryFormat.d.ts.map +1 -1
  103. package/dist/summary/summaryFormat.js.map +1 -1
  104. package/dist/summary/summaryGenerator.js.map +1 -1
  105. package/dist/summary/summaryManager.d.ts +2 -2
  106. package/dist/summary/summaryManager.d.ts.map +1 -1
  107. package/dist/summary/summaryManager.js +3 -3
  108. package/dist/summary/summaryManager.js.map +1 -1
  109. package/dist/tsdoc-metadata.json +1 -1
  110. package/lib/blobManager.d.ts +4 -6
  111. package/lib/blobManager.d.ts.map +1 -1
  112. package/lib/blobManager.js +44 -58
  113. package/lib/blobManager.js.map +1 -1
  114. package/lib/connectionTelemetry.d.ts.map +1 -1
  115. package/lib/connectionTelemetry.js +76 -43
  116. package/lib/connectionTelemetry.js.map +1 -1
  117. package/lib/containerRuntime.d.ts +90 -36
  118. package/lib/containerRuntime.d.ts.map +1 -1
  119. package/lib/containerRuntime.js +125 -62
  120. package/lib/containerRuntime.js.map +1 -1
  121. package/lib/dataStore.js +2 -2
  122. package/lib/dataStore.js.map +1 -1
  123. package/lib/dataStoreContext.d.ts +8 -2
  124. package/lib/dataStoreContext.d.ts.map +1 -1
  125. package/lib/dataStoreContext.js +16 -9
  126. package/lib/dataStoreContext.js.map +1 -1
  127. package/lib/dataStoreRegistry.d.ts +3 -0
  128. package/lib/dataStoreRegistry.d.ts.map +1 -1
  129. package/lib/dataStoreRegistry.js +3 -0
  130. package/lib/dataStoreRegistry.js.map +1 -1
  131. package/lib/dataStores.d.ts +0 -2
  132. package/lib/dataStores.d.ts.map +1 -1
  133. package/lib/dataStores.js +3 -8
  134. package/lib/dataStores.js.map +1 -1
  135. package/lib/deltaManagerProxyBase.d.ts +1 -1
  136. package/lib/deltaManagerProxyBase.d.ts.map +1 -1
  137. package/lib/deltaManagerProxyBase.js +2 -2
  138. package/lib/deltaManagerProxyBase.js.map +1 -1
  139. package/lib/error.d.ts.map +1 -1
  140. package/lib/error.js.map +1 -1
  141. package/lib/gc/garbageCollection.d.ts +6 -0
  142. package/lib/gc/garbageCollection.d.ts.map +1 -1
  143. package/lib/gc/garbageCollection.js +16 -3
  144. package/lib/gc/garbageCollection.js.map +1 -1
  145. package/lib/gc/gcConfigs.d.ts +1 -0
  146. package/lib/gc/gcConfigs.d.ts.map +1 -1
  147. package/lib/gc/gcConfigs.js +14 -4
  148. package/lib/gc/gcConfigs.js.map +1 -1
  149. package/lib/gc/gcDefinitions.d.ts +42 -11
  150. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  151. package/lib/gc/gcDefinitions.js +4 -1
  152. package/lib/gc/gcDefinitions.js.map +1 -1
  153. package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
  154. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  155. package/lib/gc/gcTelemetry.d.ts +2 -3
  156. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  157. package/lib/gc/gcTelemetry.js +7 -8
  158. package/lib/gc/gcTelemetry.js.map +1 -1
  159. package/lib/gc/index.d.ts +2 -2
  160. package/lib/gc/index.d.ts.map +1 -1
  161. package/lib/gc/index.js +2 -2
  162. package/lib/gc/index.js.map +1 -1
  163. package/lib/id-compressor/utilities.d.ts +3 -0
  164. package/lib/id-compressor/utilities.d.ts.map +1 -1
  165. package/lib/id-compressor/utilities.js +3 -0
  166. package/lib/id-compressor/utilities.js.map +1 -1
  167. package/lib/index.d.ts +4 -3
  168. package/lib/index.d.ts.map +1 -1
  169. package/lib/index.js +2 -1
  170. package/lib/index.js.map +1 -1
  171. package/lib/messageTypes.d.ts +4 -1
  172. package/lib/messageTypes.d.ts.map +1 -1
  173. package/lib/messageTypes.js +3 -0
  174. package/lib/messageTypes.js.map +1 -1
  175. package/lib/opLifecycle/definitions.d.ts +3 -0
  176. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  177. package/lib/opLifecycle/definitions.js.map +1 -1
  178. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  179. package/lib/opLifecycle/outbox.js +7 -2
  180. package/lib/opLifecycle/outbox.js.map +1 -1
  181. package/lib/packageVersion.d.ts +1 -1
  182. package/lib/packageVersion.js +1 -1
  183. package/lib/packageVersion.js.map +1 -1
  184. package/lib/pendingStateManager.d.ts.map +1 -1
  185. package/lib/pendingStateManager.js +3 -1
  186. package/lib/pendingStateManager.js.map +1 -1
  187. package/lib/scheduleManager.js +6 -2
  188. package/lib/scheduleManager.js.map +1 -1
  189. package/lib/summary/orderedClientElection.d.ts +4 -1
  190. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  191. package/lib/summary/orderedClientElection.js.map +1 -1
  192. package/lib/summary/runWhileConnectedCoordinator.d.ts +5 -0
  193. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  194. package/lib/summary/runWhileConnectedCoordinator.js +1 -0
  195. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  196. package/lib/summary/summarizer.d.ts +2 -0
  197. package/lib/summary/summarizer.d.ts.map +1 -1
  198. package/lib/summary/summarizer.js +16 -8
  199. package/lib/summary/summarizer.js.map +1 -1
  200. package/lib/summary/summarizerTypes.d.ts +94 -10
  201. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  202. package/lib/summary/summarizerTypes.js.map +1 -1
  203. package/lib/summary/summaryCollection.d.ts +16 -0
  204. package/lib/summary/summaryCollection.d.ts.map +1 -1
  205. package/lib/summary/summaryCollection.js +2 -0
  206. package/lib/summary/summaryCollection.js.map +1 -1
  207. package/lib/summary/summaryFormat.d.ts +10 -1
  208. package/lib/summary/summaryFormat.d.ts.map +1 -1
  209. package/lib/summary/summaryFormat.js.map +1 -1
  210. package/lib/summary/summaryGenerator.js.map +1 -1
  211. package/lib/summary/summaryManager.d.ts +2 -2
  212. package/lib/summary/summaryManager.d.ts.map +1 -1
  213. package/lib/summary/summaryManager.js +3 -3
  214. package/lib/summary/summaryManager.js.map +1 -1
  215. package/package.json +26 -58
  216. package/src/blobManager.ts +61 -74
  217. package/src/connectionTelemetry.ts +97 -52
  218. package/src/containerRuntime.ts +173 -93
  219. package/src/dataStore.ts +2 -2
  220. package/src/dataStoreContext.ts +16 -9
  221. package/src/dataStoreRegistry.ts +3 -0
  222. package/src/dataStores.ts +4 -16
  223. package/src/deltaManagerProxyBase.ts +2 -2
  224. package/src/error.ts +4 -1
  225. package/src/gc/garbageCollection.ts +18 -3
  226. package/src/gc/gcConfigs.ts +22 -4
  227. package/src/gc/gcDefinitions.ts +43 -11
  228. package/src/gc/gcSummaryDefinitions.ts +1 -1
  229. package/src/gc/gcTelemetry.ts +8 -8
  230. package/src/gc/index.ts +0 -4
  231. package/src/id-compressor/utilities.ts +3 -0
  232. package/src/index.ts +14 -1
  233. package/src/messageTypes.ts +4 -1
  234. package/src/opLifecycle/README.md +53 -28
  235. package/src/opLifecycle/definitions.ts +3 -0
  236. package/src/opLifecycle/outbox.ts +3 -0
  237. package/src/packageVersion.ts +1 -1
  238. package/src/pendingStateManager.ts +1 -0
  239. package/src/scheduleManager.ts +2 -0
  240. package/src/summary/orderedClientElection.ts +4 -1
  241. package/src/summary/runWhileConnectedCoordinator.ts +5 -1
  242. package/src/summary/summarizer.ts +21 -9
  243. package/src/summary/summarizerTypes.ts +95 -11
  244. package/src/summary/summaryCollection.ts +19 -1
  245. package/src/summary/summaryFormat.ts +11 -1
  246. package/src/summary/summaryGenerator.ts +3 -3
  247. package/src/summary/summaryManager.ts +2 -2
  248. package/src/gc/gcEarlyAdoption.md +0 -145
@@ -23,7 +23,9 @@ import {
23
23
  ICriticalContainerError,
24
24
  AttachState,
25
25
  ILoaderOptions,
26
+ ILoader,
26
27
  LoaderHeader,
28
+ IGetPendingLocalStateProps,
27
29
  } from "@fluidframework/container-definitions";
28
30
  import {
29
31
  IContainerRuntime,
@@ -99,12 +101,11 @@ import {
99
101
  create404Response,
100
102
  exceptionToResponse,
101
103
  GCDataBuilder,
102
- // eslint-disable-next-line import/no-deprecated
103
- requestFluidObject,
104
104
  seqFromTree,
105
105
  calculateStats,
106
106
  TelemetryContext,
107
107
  ReadAndParseBlob,
108
+ responseToException,
108
109
  } from "@fluidframework/runtime-utils";
109
110
  import { v4 as uuid } from "uuid";
110
111
  import { ContainerFluidHandleContext } from "./containerHandleContext";
@@ -144,7 +145,6 @@ import {
144
145
  IConnectableRuntime,
145
146
  IGeneratedSummaryStats,
146
147
  ISubmitSummaryOptions,
147
- ISummarizer,
148
148
  ISummarizerInternalsProvider,
149
149
  ISummarizerRuntime,
150
150
  IRefreshSummaryAckOptions,
@@ -157,6 +157,7 @@ import {
157
157
  EnqueueSummarizeResult,
158
158
  ISummarizerEvents,
159
159
  IBaseSummarizeResult,
160
+ ISummarizer,
160
161
  } from "./summary";
161
162
  import { formExponentialFn, Throttler } from "./throttler";
162
163
  import {
@@ -166,7 +167,6 @@ import {
166
167
  IGarbageCollector,
167
168
  IGCRuntimeOptions,
168
169
  IGCStats,
169
- shouldAllowGcTombstoneEnforcement,
170
170
  trimLeadingAndTrailingSlashes,
171
171
  } from "./gc";
172
172
  import { channelToDataStore, IDataStoreAliasMessage, isDataStoreAliasMessage } from "./dataStore";
@@ -222,6 +222,9 @@ function prepareLocalContainerRuntimeIdAllocationMessageForTransit(
222
222
  }
223
223
  }
224
224
 
225
+ /**
226
+ * @public
227
+ */
225
228
  export interface ISummaryBaseConfiguration {
226
229
  /**
227
230
  * Delay before first attempt to spawn summarizing container.
@@ -241,6 +244,9 @@ export interface ISummaryBaseConfiguration {
241
244
  maxOpsSinceLastSummary: number;
242
245
  }
243
246
 
247
+ /**
248
+ * @public
249
+ */
244
250
  export interface ISummaryConfigurationHeuristics extends ISummaryBaseConfiguration {
245
251
  state: "enabled";
246
252
  /**
@@ -301,19 +307,31 @@ export interface ISummaryConfigurationHeuristics extends ISummaryBaseConfigurati
301
307
  nonRuntimeHeuristicThreshold?: number;
302
308
  }
303
309
 
310
+ /**
311
+ * @public
312
+ */
304
313
  export interface ISummaryConfigurationDisableSummarizer {
305
314
  state: "disabled";
306
315
  }
307
316
 
317
+ /**
318
+ * @public
319
+ */
308
320
  export interface ISummaryConfigurationDisableHeuristics extends ISummaryBaseConfiguration {
309
321
  state: "disableHeuristics";
310
322
  }
311
323
 
324
+ /**
325
+ * @public
326
+ */
312
327
  export type ISummaryConfiguration =
313
328
  | ISummaryConfigurationDisableSummarizer
314
329
  | ISummaryConfigurationDisableHeuristics
315
330
  | ISummaryConfigurationHeuristics;
316
331
 
332
+ /**
333
+ * @public
334
+ */
317
335
  export const DefaultSummaryConfiguration: ISummaryConfiguration = {
318
336
  state: "enabled",
319
337
 
@@ -340,6 +358,9 @@ export const DefaultSummaryConfiguration: ISummaryConfiguration = {
340
358
  nonRuntimeHeuristicThreshold: 20,
341
359
  };
342
360
 
361
+ /**
362
+ * @public
363
+ */
343
364
  export interface ISummaryRuntimeOptions {
344
365
  /** Override summary configurations set by the server. */
345
366
  summaryConfigOverrides?: ISummaryConfiguration;
@@ -355,22 +376,25 @@ export interface ISummaryRuntimeOptions {
355
376
 
356
377
  /**
357
378
  * Options for op compression.
358
- * @experimental - Not ready for use
379
+ * @public
359
380
  */
360
381
  export interface ICompressionRuntimeOptions {
361
382
  /**
362
- * The minimum size the batch's payload must exceed before the batch's contents will be compressed.
383
+ * The value the batch's content size must exceed for the batch to be compressed.
384
+ * By default the value is 600 * 1024 = 614400 bytes. If the value is set to `Infinity`, compression will be disabled.
363
385
  */
364
386
  readonly minimumBatchSizeInBytes: number;
365
387
 
366
388
  /**
367
389
  * The compression algorithm that will be used to compress the op.
390
+ * By default the value is `lz4` which is the only compression algorithm currently supported.
368
391
  */
369
392
  readonly compressionAlgorithm: CompressionAlgorithms;
370
393
  }
371
394
 
372
395
  /**
373
396
  * Options for container runtime.
397
+ * @public
374
398
  */
375
399
  export interface IContainerRuntimeOptions {
376
400
  readonly summaryOptions?: ISummaryRuntimeOptions;
@@ -392,8 +416,7 @@ export interface IContainerRuntimeOptions {
392
416
  */
393
417
  readonly flushMode?: FlushMode;
394
418
  /**
395
- * Enables the runtime to compress ops. Compression is disabled when undefined.
396
- * @experimental Not ready for use.
419
+ * Enables the runtime to compress ops. See {@link ICompressionRuntimeOptions}.
397
420
  */
398
421
  readonly compressionOptions?: ICompressionRuntimeOptions;
399
422
  /**
@@ -410,12 +433,15 @@ export interface IContainerRuntimeOptions {
410
433
  /**
411
434
  * If the op payload needs to be chunked in order to work around the maximum size of the batch, this value represents
412
435
  * how large the individual chunks will be. This is only supported when compression is enabled. If after compression, the
413
- * batch size exceeds this value, it will be chunked into smaller ops of this size.
436
+ * batch content size exceeds this value, it will be chunked into smaller ops of this exact size.
414
437
  *
415
- * If unspecified, if a batch exceeds `maxBatchSizeInBytes` after compression, the container will close with an instance
416
- * of `GenericError` with the `BatchTooLarge` message.
438
+ * This value is a trade-off between having many small chunks vs fewer larger chunks and by default, the runtime is configured to use
439
+ * 200 * 1024 = 204800 bytes. This default value ensures that no compressed payload's content is able to exceed {@link IContainerRuntimeOptions.maxBatchSizeInBytes}
440
+ * regardless of the overhead of an individual op.
417
441
  *
418
- * @experimental Not ready for use.
442
+ * Any value of `chunkSizeInBytes` exceeding {@link IContainerRuntimeOptions.maxBatchSizeInBytes} will disable this feature, therefore if a compressed batch's content
443
+ * size exceeds {@link IContainerRuntimeOptions.maxBatchSizeInBytes} after compression, the container will close with an instance of `GenericError` with
444
+ * the `BatchTooLarge` message.
419
445
  */
420
446
  readonly chunkSizeInBytes?: number;
421
447
 
@@ -450,6 +476,7 @@ export interface IContainerRuntimeOptions {
450
476
 
451
477
  /**
452
478
  * Accepted header keys for requests coming to the runtime.
479
+ * @public
453
480
  */
454
481
  export enum RuntimeHeaders {
455
482
  /** True to wait for a data store to be created and loaded before returning it. */
@@ -458,14 +485,25 @@ export enum RuntimeHeaders {
458
485
  viaHandle = "viaHandle",
459
486
  }
460
487
 
461
- /** True if a tombstoned object should be returned without erroring */
488
+ /** True if a tombstoned object should be returned without erroring
489
+ * @public
490
+ */
462
491
  export const AllowTombstoneRequestHeaderKey = "allowTombstone"; // Belongs in the enum above, but avoiding the breaking change
463
- /** [IRRELEVANT IF throwOnInactiveLoad OPTION NOT SET] True if an inactive object should be returned without erroring */
492
+ /**
493
+ * [IRRELEVANT IF throwOnInactiveLoad OPTION NOT SET] True if an inactive object should be returned without erroring
494
+ * @public
495
+ */
464
496
  export const AllowInactiveRequestHeaderKey = "allowInactive"; // Belongs in the enum above, but avoiding the breaking change
465
497
 
466
- /** Tombstone error responses will have this header set to true */
498
+ /**
499
+ * Tombstone error responses will have this header set to true
500
+ * @public
501
+ */
467
502
  export const TombstoneResponseHeaderKey = "isTombstoned";
468
- /** Inactive error responses will have this header set to true */
503
+ /**
504
+ * Inactive error responses will have this header set to true
505
+ * @public
506
+ */
469
507
  export const InactiveResponseHeaderKey = "isInactive";
470
508
 
471
509
  /**
@@ -486,6 +524,7 @@ export const defaultRuntimeHeaderData: Required<RuntimeHeaderData> = {
486
524
 
487
525
  /**
488
526
  * Available compression algorithms for op compression.
527
+ * @public
489
528
  */
490
529
  export enum CompressionAlgorithms {
491
530
  lz4 = "lz4",
@@ -549,7 +588,8 @@ export const defaultPendingOpsRetryDelayMs = 1000;
549
588
  const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
550
589
 
551
590
  /**
552
- * @deprecated - use ContainerRuntimeMessageType instead
591
+ * @deprecated use ContainerRuntimeMessageType instead
592
+ * @public
553
593
  */
554
594
  export enum RuntimeMessage {
555
595
  FluidDataStoreOp = "component",
@@ -562,7 +602,8 @@ export enum RuntimeMessage {
562
602
  }
563
603
 
564
604
  /**
565
- * @deprecated - please use version in driver-utils
605
+ * @deprecated please use version in driver-utils
606
+ * @public
566
607
  */
567
608
  export function isRuntimeMessage(message: ISequencedDocumentMessage): boolean {
568
609
  return (Object.values(RuntimeMessage) as string[]).includes(message.type);
@@ -572,6 +613,7 @@ export function isRuntimeMessage(message: ISequencedDocumentMessage): boolean {
572
613
  * Legacy ID for the built-in AgentScheduler. To minimize disruption while removing it, retaining this as a
573
614
  * special-case for document dirty state. Ultimately we should have no special-cases from the
574
615
  * ContainerRuntime's perspective.
616
+ * @public
575
617
  */
576
618
  export const agentSchedulerId = "_scheduler";
577
619
 
@@ -629,9 +671,58 @@ type MessageWithContext =
629
671
  local: boolean;
630
672
  };
631
673
 
674
+ const summarizerRequestUrl = "_summarizer";
675
+
676
+ /**
677
+ * Create and retrieve the summmarizer
678
+ */
679
+ async function createSummarizer(loader: ILoader, url: string): Promise<ISummarizer> {
680
+ const request: IRequest = {
681
+ headers: {
682
+ [LoaderHeader.cache]: false,
683
+ [LoaderHeader.clientDetails]: {
684
+ capabilities: { interactive: false },
685
+ type: summarizerClientType,
686
+ },
687
+ [DriverHeader.summarizingClient]: true,
688
+ [LoaderHeader.reconnect]: false,
689
+ },
690
+ url,
691
+ };
692
+
693
+ const resolvedContainer = await loader.resolve(request);
694
+ let fluidObject: FluidObject<ISummarizer> | undefined;
695
+
696
+ // Older containers may not have the "getEntryPoint" API
697
+ // ! This check will need to stay until LTS of loader moves past 2.0.0-internal.7.0.0
698
+ if (resolvedContainer.getEntryPoint !== undefined) {
699
+ fluidObject = await resolvedContainer.getEntryPoint();
700
+ } else {
701
+ const response = await resolvedContainer.request({ url: `/${summarizerRequestUrl}` });
702
+ if (response.status !== 200 || response.mimeType !== "fluid/object") {
703
+ throw responseToException(response, request);
704
+ }
705
+ fluidObject = response.value;
706
+ }
707
+
708
+ if (fluidObject?.ISummarizer === undefined) {
709
+ throw new UsageError("Fluid object does not implement ISummarizer");
710
+ }
711
+ return fluidObject.ISummarizer;
712
+ }
713
+
714
+ /**
715
+ * This function is not supported publicly and exists for e2e testing
716
+ * @internal
717
+ */
718
+ export async function TEST_requestSummarizer(loader: ILoader, url: string): Promise<ISummarizer> {
719
+ return createSummarizer(loader, url);
720
+ }
721
+
632
722
  /**
633
723
  * Represents the runtime of the container. Contains helper functions/state of the container.
634
724
  * It will define the store level mappings.
725
+ * @public
635
726
  */
636
727
  export class ContainerRuntime
637
728
  extends TypedEventEmitter<IContainerRuntimeEvents & ISummarizerEvents>
@@ -643,14 +734,14 @@ export class ContainerRuntime
643
734
  IProvideFluidHandleContext
644
735
  {
645
736
  /**
646
- * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
737
+ * @deprecated Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
647
738
  */
648
739
  public get IFluidRouter() {
649
740
  return this;
650
741
  }
651
742
 
652
743
  /**
653
- * @deprecated - use loadRuntime instead.
744
+ * @deprecated use loadRuntime instead.
654
745
  * Load the stores from a snapshot and returns the runtime.
655
746
  * @param context - Context of the container.
656
747
  * @param registryEntries - Mapping to the stores.
@@ -898,7 +989,7 @@ export class ContainerRuntime
898
989
  summaryOp: ISummaryContent,
899
990
  referenceSequenceNumber?: number,
900
991
  ) => number;
901
- private readonly submitSignalFn: (contents: any) => void;
992
+ private readonly submitSignalFn: (content: any, targetClientId?: string) => void;
902
993
  public readonly disposeFn: (error?: ICriticalContainerError) => void;
903
994
  public readonly closeFn: (error?: ICriticalContainerError) => void;
904
995
 
@@ -1090,10 +1181,20 @@ export class ContainerRuntime
1090
1181
  */
1091
1182
  private nextSummaryNumber: number;
1092
1183
 
1093
- /**
1094
- * If false, loading or using a Tombstoned object should merely log, not fail
1095
- */
1096
- public readonly gcTombstoneEnforcementAllowed: boolean;
1184
+ /** If false, loading or using a Tombstoned object should merely log, not fail */
1185
+ public get gcTombstoneEnforcementAllowed(): boolean {
1186
+ return this.garbageCollector.tombstoneEnforcementAllowed;
1187
+ }
1188
+
1189
+ /** If true, throw an error when a tombstone data store is retrieved */
1190
+ public get gcThrowOnTombstoneLoad(): boolean {
1191
+ return this.garbageCollector.throwOnTombstoneLoad;
1192
+ }
1193
+
1194
+ /** If true, throw an error when a tombstone data store is used. */
1195
+ public get gcThrowOnTombstoneUsage(): boolean {
1196
+ return this.garbageCollector.throwOnTombstoneUsage;
1197
+ }
1097
1198
 
1098
1199
  /**
1099
1200
  * GUID to identify a document in telemetry
@@ -1240,11 +1341,6 @@ export class ContainerRuntime
1240
1341
  // Later updates come through calls to setConnectionState.
1241
1342
  this._connected = connected;
1242
1343
 
1243
- this.gcTombstoneEnforcementAllowed = shouldAllowGcTombstoneEnforcement(
1244
- metadata?.gcFeatureMatrix?.tombstoneGeneration /* persisted */,
1245
- this.runtimeOptions.gcOptions[gcTombstoneGenerationOptionName] /* current */,
1246
- );
1247
-
1248
1344
  this.mc.logger.sendTelemetryEvent({
1249
1345
  eventName: "GCFeatureMatrix",
1250
1346
  metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
@@ -1577,7 +1673,7 @@ export class ContainerRuntime
1577
1673
  this, // IConnectedState
1578
1674
  this.summaryCollection,
1579
1675
  this.logger,
1580
- this.formRequestSummarizerFn(loader),
1676
+ this.formCreateSummarizerFn(loader),
1581
1677
  new Throttler(
1582
1678
  60 * 1000, // 60 sec delay window
1583
1679
  30 * 1000, // 30 sec max delay
@@ -1676,14 +1772,14 @@ export class ContainerRuntime
1676
1772
  /**
1677
1773
  * Notifies this object about the request made to the container.
1678
1774
  * @param request - Request made to the handler.
1679
- * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
1775
+ * @deprecated Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
1680
1776
  */
1681
1777
  public async request(request: IRequest): Promise<IResponse> {
1682
1778
  try {
1683
1779
  const parser = RequestParser.create(request);
1684
1780
  const id = parser.pathParts[0];
1685
1781
 
1686
- if (id === "_summarizer" && parser.pathParts.length === 1) {
1782
+ if (id === summarizerRequestUrl && parser.pathParts.length === 1) {
1687
1783
  if (this._summarizer !== undefined) {
1688
1784
  return {
1689
1785
  status: 200,
@@ -1694,6 +1790,7 @@ export class ContainerRuntime
1694
1790
  return create404Response(request);
1695
1791
  }
1696
1792
  if (this.requestHandler !== undefined) {
1793
+ // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
1697
1794
  return this.requestHandler(parser, this);
1698
1795
  }
1699
1796
 
@@ -1713,6 +1810,7 @@ export class ContainerRuntime
1713
1810
  const id = requestParser.pathParts[0];
1714
1811
 
1715
1812
  if (id === "_channels") {
1813
+ // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
1716
1814
  return this.resolveHandle(requestParser.createSubRequest(1));
1717
1815
  }
1718
1816
 
@@ -1726,7 +1824,10 @@ export class ContainerRuntime
1726
1824
  }
1727
1825
  : create404Response(request);
1728
1826
  } else if (requestParser.pathParts.length > 0) {
1729
- const dataStore = await this.getDataStoreFromRequest(id, request);
1827
+ // Differentiate between requesting the dataStore directly, or one of its children
1828
+ const requestForChild = !requestParser.isLeaf(1);
1829
+ const dataStore = await this.getDataStoreFromRequest(id, request, requestForChild);
1830
+
1730
1831
  const subRequest = requestParser.createSubRequest(1);
1731
1832
  // We always expect createSubRequest to include a leading slash, but asserting here to protect against
1732
1833
  // unintentionally modifying the url if that changes.
@@ -1734,6 +1835,7 @@ export class ContainerRuntime
1734
1835
  subRequest.url.startsWith("/"),
1735
1836
  0x126 /* "Expected createSubRequest url to include a leading slash" */,
1736
1837
  );
1838
+ // eslint-disable-next-line @typescript-eslint/return-await -- Adding an await here causes test failures
1737
1839
  return dataStore.request(subRequest);
1738
1840
  }
1739
1841
 
@@ -1758,6 +1860,7 @@ export class ContainerRuntime
1758
1860
  private async getDataStoreFromRequest(
1759
1861
  id: string,
1760
1862
  request: IRequest,
1863
+ requestForChild: boolean,
1761
1864
  ): Promise<IFluidDataStoreChannel> {
1762
1865
  const headerData: RuntimeHeaderData = {};
1763
1866
  if (typeof request.headers?.[RuntimeHeaders.wait] === "boolean") {
@@ -1770,6 +1873,11 @@ export class ContainerRuntime
1770
1873
  headerData.allowTombstone = request.headers[AllowTombstoneRequestHeaderKey];
1771
1874
  }
1772
1875
 
1876
+ // We allow Tombstone requests for sub-DataStore objects
1877
+ if (requestForChild) {
1878
+ headerData.allowTombstone = true;
1879
+ }
1880
+
1773
1881
  await this.dataStores.waitIfPendingAlias(id);
1774
1882
  const internalId = this.internalId(id);
1775
1883
  const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
@@ -2329,7 +2437,7 @@ export class ContainerRuntime
2329
2437
  * Returns the runtime of the data store.
2330
2438
  * @param id - Id supplied during creating the data store.
2331
2439
  * @param wait - True if you want to wait for it.
2332
- * @deprecated - Use getAliasedDataStoreEntryPoint instead to get an aliased data store's entry point.
2440
+ * @deprecated Use getAliasedDataStoreEntryPoint instead to get an aliased data store's entry point.
2333
2441
  */
2334
2442
  // eslint-disable-next-line import/no-deprecated
2335
2443
  public async getRootDataStore(id: string, wait = true): Promise<IFluidRouter> {
@@ -2556,16 +2664,28 @@ export class ContainerRuntime
2556
2664
  * Submits the signal to be sent to other clients.
2557
2665
  * @param type - Type of the signal.
2558
2666
  * @param content - Content of the signal.
2667
+ * @param targetClientId - When specified, the signal is only sent to the provided client id.
2559
2668
  */
2560
- public submitSignal(type: string, content: any) {
2669
+ public submitSignal(type: string, content: any, targetClientId?: string) {
2561
2670
  this.verifyNotClosed();
2562
2671
  const envelope = this.createNewSignalEnvelope(undefined /* address */, type, content);
2563
- return this.submitSignalFn(envelope);
2672
+ return this.submitSignalFn(envelope, targetClientId);
2564
2673
  }
2565
2674
 
2566
- public submitDataStoreSignal(address: string, type: string, content: any) {
2675
+ /**
2676
+ * Submits the signal to be sent to other clients.
2677
+ * @param type - Type of the signal.
2678
+ * @param content - Content of the signal.
2679
+ * @param targetClientId - When specified, the signal is only sent to the provided client id.
2680
+ */
2681
+ public submitDataStoreSignal(
2682
+ address: string,
2683
+ type: string,
2684
+ content: any,
2685
+ targetClientId?: string,
2686
+ ) {
2567
2687
  const envelope = this.createNewSignalEnvelope(address, type, content);
2568
- return this.submitSignalFn(envelope);
2688
+ return this.submitSignalFn(envelope, targetClientId);
2569
2689
  }
2570
2690
 
2571
2691
  public setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {
@@ -2764,7 +2884,7 @@ export class ContainerRuntime
2764
2884
  }
2765
2885
 
2766
2886
  /**
2767
- * @deprecated - Replaced by deleteSweepReadyNodes.
2887
+ * @deprecated Replaced by deleteSweepReadyNodes.
2768
2888
  */
2769
2889
  public deleteUnusedNodes(unusedRoutes: string[]): string[] {
2770
2890
  throw new Error("deleteUnusedRoutes should not be called");
@@ -3684,7 +3804,7 @@ export class ContainerRuntime
3684
3804
  * and then close as the current main client is likely to be re-elected as the parent summarizer again.
3685
3805
  */
3686
3806
  if (!result.isSummaryTracked && result.isSummaryNewer) {
3687
- const fetchResult = await this.fetchSnapshotFromStorage(
3807
+ const fetchResult = await this.fetchLatestSnapshotFromStorage(
3688
3808
  summaryLogger,
3689
3809
  {
3690
3810
  eventName: "RefreshLatestSummaryAckFetch",
@@ -3692,7 +3812,6 @@ export class ContainerRuntime
3692
3812
  targetSequenceNumber: summaryRefSeq,
3693
3813
  },
3694
3814
  readAndParseBlob,
3695
- null,
3696
3815
  );
3697
3816
 
3698
3817
  /**
@@ -3741,13 +3860,12 @@ export class ContainerRuntime
3741
3860
 
3742
3861
  // This is a performance optimization as the same parent is likely to be elected again, and would use its
3743
3862
  // cache to fetch the snapshot instead of the network.
3744
- await this.fetchSnapshotFromStorage(
3863
+ await this.fetchLatestSnapshotFromStorage(
3745
3864
  summaryLogger,
3746
3865
  {
3747
3866
  eventName: "RefreshLatestSummaryFromServerFetch",
3748
3867
  },
3749
3868
  readAndParseBlob,
3750
- null,
3751
3869
  );
3752
3870
 
3753
3871
  await this.closeStaleSummarizer("RefreshLatestSummaryFromServerFetch");
@@ -3761,16 +3879,6 @@ export class ContainerRuntime
3761
3879
  }
3762
3880
 
3763
3881
  private async closeStaleSummarizer(codePath: string): Promise<void> {
3764
- this.mc.logger.sendTelemetryEvent(
3765
- {
3766
- eventName: "ClosingSummarizerOnSummaryStale",
3767
- codePath,
3768
- message: "Stopping fetch from storage",
3769
- closeSummarizerDelayMs: this.closeSummarizerDelayMs,
3770
- },
3771
- new GenericError("Restarting summarizer instead of refreshing"),
3772
- );
3773
-
3774
3882
  // Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
3775
3883
  await delay(this.closeSummarizerDelayMs);
3776
3884
  this._summarizer?.stop("latestSummaryStateStale");
@@ -3778,15 +3886,14 @@ export class ContainerRuntime
3778
3886
  }
3779
3887
 
3780
3888
  /**
3781
- * Downloads snapshot from storage with the given versionId or latest if versionId is null.
3889
+ * Downloads the latest snapshot from storage.
3782
3890
  * By default, it also closes the container after downloading the snapshot. However, this may be
3783
3891
  * overridden via options.
3784
3892
  */
3785
- private async fetchSnapshotFromStorage(
3893
+ private async fetchLatestSnapshotFromStorage(
3786
3894
  logger: ITelemetryLoggerExt,
3787
3895
  event: ITelemetryGenericEvent,
3788
3896
  readAndParseBlob: ReadAndParseBlob,
3789
- versionId: string | null,
3790
3897
  ): Promise<{ snapshotTree: ISnapshotTree; versionId: string; latestSnapshotRefSeq: number }> {
3791
3898
  return PerformanceEvent.timedExecAsync(
3792
3899
  logger,
@@ -3808,10 +3915,10 @@ export class ContainerRuntime
3808
3915
  const trace = Trace.start();
3809
3916
 
3810
3917
  const versions = await this.storage.getVersions(
3811
- versionId,
3918
+ null,
3812
3919
  1,
3813
3920
  "prefetchLatestSummaryBeforeClose",
3814
- versionId === null ? FetchSource.noCache : undefined,
3921
+ FetchSource.noCache,
3815
3922
  );
3816
3923
  assert(
3817
3924
  !!versions && !!versions[0],
@@ -3838,9 +3945,7 @@ export class ContainerRuntime
3838
3945
 
3839
3946
  public notifyAttaching() {} // do nothing (deprecated method)
3840
3947
 
3841
- public async getPendingLocalState(props?: {
3842
- notifyImminentClosure: boolean;
3843
- }): Promise<unknown> {
3948
+ public async getPendingLocalState(props?: IGetPendingLocalStateProps): Promise<unknown> {
3844
3949
  return PerformanceEvent.timedExecAsync(
3845
3950
  this.mc.logger,
3846
3951
  {
@@ -3850,6 +3955,7 @@ export class ContainerRuntime
3850
3955
  async (event) => {
3851
3956
  this.verifyNotClosed();
3852
3957
  const waitBlobsToAttach = props?.notifyImminentClosure;
3958
+ const stopBlobAttachingSignal = props?.stopBlobAttachingSignal;
3853
3959
  if (this._orderSequentiallyCalls !== 0) {
3854
3960
  throw new UsageError("can't get state during orderSequentially");
3855
3961
  }
@@ -3858,7 +3964,7 @@ export class ContainerRuntime
3858
3964
  // to close current batch.
3859
3965
  this.flush();
3860
3966
  const pendingAttachmentBlobs = waitBlobsToAttach
3861
- ? await this.blobManager.attachAndGetPendingBlobs()
3967
+ ? await this.blobManager.attachAndGetPendingBlobs(stopBlobAttachingSignal)
3862
3968
  : undefined;
3863
3969
  const pending = this.pendingStateManager.getLocalState();
3864
3970
  if (!pendingAttachmentBlobs && !this.hasPendingMessages()) {
@@ -3905,37 +4011,11 @@ export class ContainerRuntime
3905
4011
  }
3906
4012
 
3907
4013
  /**
3908
- * * Forms a function that will request a Summarizer.
3909
- * @param loaderRouter - the loader acting as an IFluidRouter
3910
- * */
3911
- // eslint-disable-next-line import/no-deprecated
3912
- private formRequestSummarizerFn(loaderRouter: IFluidRouter) {
4014
+ * Forms a function that will create and retrieve a Summarizer.
4015
+ */
4016
+ private formCreateSummarizerFn(loader: ILoader) {
3913
4017
  return async () => {
3914
- const request: IRequest = {
3915
- headers: {
3916
- [LoaderHeader.cache]: false,
3917
- [LoaderHeader.clientDetails]: {
3918
- capabilities: { interactive: false },
3919
- type: summarizerClientType,
3920
- },
3921
- [DriverHeader.summarizingClient]: true,
3922
- [LoaderHeader.reconnect]: false,
3923
- },
3924
- url: "/_summarizer",
3925
- };
3926
-
3927
- // eslint-disable-next-line import/no-deprecated
3928
- const fluidObject = await requestFluidObject<FluidObject<ISummarizer>>(
3929
- loaderRouter,
3930
- request,
3931
- );
3932
- const summarizer = fluidObject.ISummarizer;
3933
-
3934
- if (!summarizer) {
3935
- throw new UsageError("Fluid object does not implement ISummarizer");
3936
- }
3937
-
3938
- return summarizer;
4018
+ return createSummarizer(loader, `/${summarizerRequestUrl}`);
3939
4019
  };
3940
4020
  }
3941
4021
 
package/src/dataStore.ts CHANGED
@@ -161,7 +161,7 @@ class DataStore implements IDataStore {
161
161
  }
162
162
 
163
163
  /**
164
- * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
164
+ * @deprecated Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
165
165
  */
166
166
  public async request(request: IRequest): Promise<IResponse> {
167
167
  return this.fluidDataStoreChannel.request(request);
@@ -185,7 +185,7 @@ class DataStore implements IDataStore {
185
185
  }
186
186
 
187
187
  /**
188
- * @deprecated - Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
188
+ * @deprecated Will be removed in future major release. Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
189
189
  */
190
190
  public get IFluidRouter() {
191
191
  return this.fluidDataStoreChannel;