@fluidframework/container-runtime 2.0.0-internal.7.1.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 (207) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/api-extractor.json +1 -13
  3. package/api-report/container-runtime.api.md +75 -10
  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/containerRuntime.d.ts +71 -23
  9. package/dist/containerRuntime.d.ts.map +1 -1
  10. package/dist/containerRuntime.js +72 -32
  11. package/dist/containerRuntime.js.map +1 -1
  12. package/dist/dataStore.js +2 -2
  13. package/dist/dataStore.js.map +1 -1
  14. package/dist/dataStoreContext.d.ts +8 -2
  15. package/dist/dataStoreContext.d.ts.map +1 -1
  16. package/dist/dataStoreContext.js +15 -8
  17. package/dist/dataStoreContext.js.map +1 -1
  18. package/dist/dataStoreRegistry.d.ts +3 -0
  19. package/dist/dataStoreRegistry.d.ts.map +1 -1
  20. package/dist/dataStoreRegistry.js +3 -0
  21. package/dist/dataStoreRegistry.js.map +1 -1
  22. package/dist/dataStores.d.ts +0 -2
  23. package/dist/dataStores.d.ts.map +1 -1
  24. package/dist/dataStores.js +2 -7
  25. package/dist/dataStores.js.map +1 -1
  26. package/dist/deltaManagerProxyBase.d.ts +1 -1
  27. package/dist/deltaManagerProxyBase.d.ts.map +1 -1
  28. package/dist/deltaManagerProxyBase.js +2 -2
  29. package/dist/deltaManagerProxyBase.js.map +1 -1
  30. package/dist/gc/garbageCollection.d.ts +6 -0
  31. package/dist/gc/garbageCollection.d.ts.map +1 -1
  32. package/dist/gc/garbageCollection.js +16 -3
  33. package/dist/gc/garbageCollection.js.map +1 -1
  34. package/dist/gc/gcConfigs.d.ts +1 -0
  35. package/dist/gc/gcConfigs.d.ts.map +1 -1
  36. package/dist/gc/gcConfigs.js +12 -2
  37. package/dist/gc/gcConfigs.js.map +1 -1
  38. package/dist/gc/gcDefinitions.d.ts +40 -9
  39. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  40. package/dist/gc/gcDefinitions.js +4 -1
  41. package/dist/gc/gcDefinitions.js.map +1 -1
  42. package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
  43. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  44. package/dist/gc/gcTelemetry.d.ts +2 -3
  45. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  46. package/dist/gc/gcTelemetry.js +7 -8
  47. package/dist/gc/gcTelemetry.js.map +1 -1
  48. package/dist/gc/index.d.ts +2 -2
  49. package/dist/gc/index.d.ts.map +1 -1
  50. package/dist/gc/index.js +1 -5
  51. package/dist/gc/index.js.map +1 -1
  52. package/dist/id-compressor/utilities.d.ts +3 -0
  53. package/dist/id-compressor/utilities.d.ts.map +1 -1
  54. package/dist/id-compressor/utilities.js +3 -0
  55. package/dist/id-compressor/utilities.js.map +1 -1
  56. package/dist/index.d.ts +3 -2
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +3 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/messageTypes.d.ts +4 -1
  61. package/dist/messageTypes.d.ts.map +1 -1
  62. package/dist/messageTypes.js +3 -0
  63. package/dist/messageTypes.js.map +1 -1
  64. package/dist/opLifecycle/definitions.d.ts +3 -0
  65. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  66. package/dist/opLifecycle/definitions.js.map +1 -1
  67. package/dist/packageVersion.d.ts +1 -1
  68. package/dist/packageVersion.js +1 -1
  69. package/dist/packageVersion.js.map +1 -1
  70. package/dist/summary/orderedClientElection.d.ts +4 -1
  71. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  72. package/dist/summary/orderedClientElection.js.map +1 -1
  73. package/dist/summary/runWhileConnectedCoordinator.d.ts +5 -0
  74. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  75. package/dist/summary/runWhileConnectedCoordinator.js +1 -0
  76. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  77. package/dist/summary/summarizer.d.ts +1 -0
  78. package/dist/summary/summarizer.d.ts.map +1 -1
  79. package/dist/summary/summarizer.js +1 -0
  80. package/dist/summary/summarizer.js.map +1 -1
  81. package/dist/summary/summarizerTypes.d.ts +94 -10
  82. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  83. package/dist/summary/summarizerTypes.js.map +1 -1
  84. package/dist/summary/summaryCollection.d.ts +16 -0
  85. package/dist/summary/summaryCollection.d.ts.map +1 -1
  86. package/dist/summary/summaryCollection.js +1 -0
  87. package/dist/summary/summaryCollection.js.map +1 -1
  88. package/dist/summary/summaryFormat.d.ts +10 -1
  89. package/dist/summary/summaryFormat.d.ts.map +1 -1
  90. package/dist/summary/summaryFormat.js.map +1 -1
  91. package/lib/blobManager.d.ts +4 -6
  92. package/lib/blobManager.d.ts.map +1 -1
  93. package/lib/blobManager.js +44 -58
  94. package/lib/blobManager.js.map +1 -1
  95. package/lib/containerRuntime.d.ts +71 -23
  96. package/lib/containerRuntime.d.ts.map +1 -1
  97. package/lib/containerRuntime.js +73 -33
  98. package/lib/containerRuntime.js.map +1 -1
  99. package/lib/dataStore.js +2 -2
  100. package/lib/dataStore.js.map +1 -1
  101. package/lib/dataStoreContext.d.ts +8 -2
  102. package/lib/dataStoreContext.d.ts.map +1 -1
  103. package/lib/dataStoreContext.js +16 -9
  104. package/lib/dataStoreContext.js.map +1 -1
  105. package/lib/dataStoreRegistry.d.ts +3 -0
  106. package/lib/dataStoreRegistry.d.ts.map +1 -1
  107. package/lib/dataStoreRegistry.js +3 -0
  108. package/lib/dataStoreRegistry.js.map +1 -1
  109. package/lib/dataStores.d.ts +0 -2
  110. package/lib/dataStores.d.ts.map +1 -1
  111. package/lib/dataStores.js +3 -8
  112. package/lib/dataStores.js.map +1 -1
  113. package/lib/deltaManagerProxyBase.d.ts +1 -1
  114. package/lib/deltaManagerProxyBase.d.ts.map +1 -1
  115. package/lib/deltaManagerProxyBase.js +2 -2
  116. package/lib/deltaManagerProxyBase.js.map +1 -1
  117. package/lib/gc/garbageCollection.d.ts +6 -0
  118. package/lib/gc/garbageCollection.d.ts.map +1 -1
  119. package/lib/gc/garbageCollection.js +16 -3
  120. package/lib/gc/garbageCollection.js.map +1 -1
  121. package/lib/gc/gcConfigs.d.ts +1 -0
  122. package/lib/gc/gcConfigs.d.ts.map +1 -1
  123. package/lib/gc/gcConfigs.js +14 -4
  124. package/lib/gc/gcConfigs.js.map +1 -1
  125. package/lib/gc/gcDefinitions.d.ts +40 -9
  126. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  127. package/lib/gc/gcDefinitions.js +4 -1
  128. package/lib/gc/gcDefinitions.js.map +1 -1
  129. package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
  130. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  131. package/lib/gc/gcTelemetry.d.ts +2 -3
  132. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  133. package/lib/gc/gcTelemetry.js +7 -8
  134. package/lib/gc/gcTelemetry.js.map +1 -1
  135. package/lib/gc/index.d.ts +2 -2
  136. package/lib/gc/index.d.ts.map +1 -1
  137. package/lib/gc/index.js +2 -2
  138. package/lib/gc/index.js.map +1 -1
  139. package/lib/id-compressor/utilities.d.ts +3 -0
  140. package/lib/id-compressor/utilities.d.ts.map +1 -1
  141. package/lib/id-compressor/utilities.js +3 -0
  142. package/lib/id-compressor/utilities.js.map +1 -1
  143. package/lib/index.d.ts +3 -2
  144. package/lib/index.d.ts.map +1 -1
  145. package/lib/index.js +1 -0
  146. package/lib/index.js.map +1 -1
  147. package/lib/messageTypes.d.ts +4 -1
  148. package/lib/messageTypes.d.ts.map +1 -1
  149. package/lib/messageTypes.js +3 -0
  150. package/lib/messageTypes.js.map +1 -1
  151. package/lib/opLifecycle/definitions.d.ts +3 -0
  152. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  153. package/lib/opLifecycle/definitions.js.map +1 -1
  154. package/lib/packageVersion.d.ts +1 -1
  155. package/lib/packageVersion.js +1 -1
  156. package/lib/packageVersion.js.map +1 -1
  157. package/lib/summary/orderedClientElection.d.ts +4 -1
  158. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  159. package/lib/summary/orderedClientElection.js.map +1 -1
  160. package/lib/summary/runWhileConnectedCoordinator.d.ts +5 -0
  161. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  162. package/lib/summary/runWhileConnectedCoordinator.js +1 -0
  163. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  164. package/lib/summary/summarizer.d.ts +1 -0
  165. package/lib/summary/summarizer.d.ts.map +1 -1
  166. package/lib/summary/summarizer.js +1 -0
  167. package/lib/summary/summarizer.js.map +1 -1
  168. package/lib/summary/summarizerTypes.d.ts +94 -10
  169. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  170. package/lib/summary/summarizerTypes.js.map +1 -1
  171. package/lib/summary/summaryCollection.d.ts +16 -0
  172. package/lib/summary/summaryCollection.d.ts.map +1 -1
  173. package/lib/summary/summaryCollection.js +1 -0
  174. package/lib/summary/summaryCollection.js.map +1 -1
  175. package/lib/summary/summaryFormat.d.ts +10 -1
  176. package/lib/summary/summaryFormat.d.ts.map +1 -1
  177. package/lib/summary/summaryFormat.js.map +1 -1
  178. package/package.json +25 -22
  179. package/src/blobManager.ts +61 -74
  180. package/src/containerRuntime.ts +103 -50
  181. package/src/dataStore.ts +2 -2
  182. package/src/dataStoreContext.ts +16 -9
  183. package/src/dataStoreRegistry.ts +3 -0
  184. package/src/dataStores.ts +4 -16
  185. package/src/deltaManagerProxyBase.ts +2 -2
  186. package/src/gc/garbageCollection.ts +18 -3
  187. package/src/gc/gcConfigs.ts +22 -4
  188. package/src/gc/gcDefinitions.ts +41 -9
  189. package/src/gc/gcSummaryDefinitions.ts +1 -1
  190. package/src/gc/gcTelemetry.ts +8 -8
  191. package/src/gc/index.ts +0 -4
  192. package/src/id-compressor/utilities.ts +3 -0
  193. package/src/index.ts +13 -1
  194. package/src/messageTypes.ts +4 -1
  195. package/src/opLifecycle/definitions.ts +3 -0
  196. package/src/packageVersion.ts +1 -1
  197. package/src/summary/orderedClientElection.ts +4 -1
  198. package/src/summary/runWhileConnectedCoordinator.ts +5 -1
  199. package/src/summary/summarizer.ts +1 -0
  200. package/src/summary/summarizerTypes.ts +95 -11
  201. package/src/summary/summaryCollection.ts +18 -1
  202. package/src/summary/summaryFormat.ts +11 -1
  203. package/dist/container-runtime-alpha.d.ts +0 -1554
  204. package/dist/container-runtime-beta.d.ts +0 -1554
  205. package/dist/container-runtime-public.d.ts +0 -1554
  206. package/dist/container-runtime.d.ts +0 -1611
  207. package/src/gc/gcEarlyAdoption.md +0 -145
@@ -25,6 +25,7 @@ import {
25
25
  ILoaderOptions,
26
26
  ILoader,
27
27
  LoaderHeader,
28
+ IGetPendingLocalStateProps,
28
29
  } from "@fluidframework/container-definitions";
29
30
  import {
30
31
  IContainerRuntime,
@@ -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,6 +376,7 @@ export interface ISummaryRuntimeOptions {
355
376
 
356
377
  /**
357
378
  * Options for op compression.
379
+ * @public
358
380
  */
359
381
  export interface ICompressionRuntimeOptions {
360
382
  /**
@@ -372,6 +394,7 @@ export interface ICompressionRuntimeOptions {
372
394
 
373
395
  /**
374
396
  * Options for container runtime.
397
+ * @public
375
398
  */
376
399
  export interface IContainerRuntimeOptions {
377
400
  readonly summaryOptions?: ISummaryRuntimeOptions;
@@ -453,6 +476,7 @@ export interface IContainerRuntimeOptions {
453
476
 
454
477
  /**
455
478
  * Accepted header keys for requests coming to the runtime.
479
+ * @public
456
480
  */
457
481
  export enum RuntimeHeaders {
458
482
  /** True to wait for a data store to be created and loaded before returning it. */
@@ -461,14 +485,25 @@ export enum RuntimeHeaders {
461
485
  viaHandle = "viaHandle",
462
486
  }
463
487
 
464
- /** True if a tombstoned object should be returned without erroring */
488
+ /** True if a tombstoned object should be returned without erroring
489
+ * @public
490
+ */
465
491
  export const AllowTombstoneRequestHeaderKey = "allowTombstone"; // Belongs in the enum above, but avoiding the breaking change
466
- /** [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
+ */
467
496
  export const AllowInactiveRequestHeaderKey = "allowInactive"; // Belongs in the enum above, but avoiding the breaking change
468
497
 
469
- /** 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
+ */
470
502
  export const TombstoneResponseHeaderKey = "isTombstoned";
471
- /** 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
+ */
472
507
  export const InactiveResponseHeaderKey = "isInactive";
473
508
 
474
509
  /**
@@ -489,6 +524,7 @@ export const defaultRuntimeHeaderData: Required<RuntimeHeaderData> = {
489
524
 
490
525
  /**
491
526
  * Available compression algorithms for op compression.
527
+ * @public
492
528
  */
493
529
  export enum CompressionAlgorithms {
494
530
  lz4 = "lz4",
@@ -552,7 +588,8 @@ export const defaultPendingOpsRetryDelayMs = 1000;
552
588
  const defaultCloseSummarizerDelayMs = 5000; // 5 seconds
553
589
 
554
590
  /**
555
- * @deprecated - use ContainerRuntimeMessageType instead
591
+ * @deprecated use ContainerRuntimeMessageType instead
592
+ * @public
556
593
  */
557
594
  export enum RuntimeMessage {
558
595
  FluidDataStoreOp = "component",
@@ -565,7 +602,8 @@ export enum RuntimeMessage {
565
602
  }
566
603
 
567
604
  /**
568
- * @deprecated - please use version in driver-utils
605
+ * @deprecated please use version in driver-utils
606
+ * @public
569
607
  */
570
608
  export function isRuntimeMessage(message: ISequencedDocumentMessage): boolean {
571
609
  return (Object.values(RuntimeMessage) as string[]).includes(message.type);
@@ -575,6 +613,7 @@ export function isRuntimeMessage(message: ISequencedDocumentMessage): boolean {
575
613
  * Legacy ID for the built-in AgentScheduler. To minimize disruption while removing it, retaining this as a
576
614
  * special-case for document dirty state. Ultimately we should have no special-cases from the
577
615
  * ContainerRuntime's perspective.
616
+ * @public
578
617
  */
579
618
  export const agentSchedulerId = "_scheduler";
580
619
 
@@ -674,6 +713,7 @@ async function createSummarizer(loader: ILoader, url: string): Promise<ISummariz
674
713
 
675
714
  /**
676
715
  * This function is not supported publicly and exists for e2e testing
716
+ * @internal
677
717
  */
678
718
  export async function TEST_requestSummarizer(loader: ILoader, url: string): Promise<ISummarizer> {
679
719
  return createSummarizer(loader, url);
@@ -682,6 +722,7 @@ export async function TEST_requestSummarizer(loader: ILoader, url: string): Prom
682
722
  /**
683
723
  * Represents the runtime of the container. Contains helper functions/state of the container.
684
724
  * It will define the store level mappings.
725
+ * @public
685
726
  */
686
727
  export class ContainerRuntime
687
728
  extends TypedEventEmitter<IContainerRuntimeEvents & ISummarizerEvents>
@@ -693,14 +734,14 @@ export class ContainerRuntime
693
734
  IProvideFluidHandleContext
694
735
  {
695
736
  /**
696
- * @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
697
738
  */
698
739
  public get IFluidRouter() {
699
740
  return this;
700
741
  }
701
742
 
702
743
  /**
703
- * @deprecated - use loadRuntime instead.
744
+ * @deprecated use loadRuntime instead.
704
745
  * Load the stores from a snapshot and returns the runtime.
705
746
  * @param context - Context of the container.
706
747
  * @param registryEntries - Mapping to the stores.
@@ -948,7 +989,7 @@ export class ContainerRuntime
948
989
  summaryOp: ISummaryContent,
949
990
  referenceSequenceNumber?: number,
950
991
  ) => number;
951
- private readonly submitSignalFn: (contents: any) => void;
992
+ private readonly submitSignalFn: (content: any, targetClientId?: string) => void;
952
993
  public readonly disposeFn: (error?: ICriticalContainerError) => void;
953
994
  public readonly closeFn: (error?: ICriticalContainerError) => void;
954
995
 
@@ -1140,10 +1181,20 @@ export class ContainerRuntime
1140
1181
  */
1141
1182
  private nextSummaryNumber: number;
1142
1183
 
1143
- /**
1144
- * If false, loading or using a Tombstoned object should merely log, not fail
1145
- */
1146
- 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
+ }
1147
1198
 
1148
1199
  /**
1149
1200
  * GUID to identify a document in telemetry
@@ -1290,11 +1341,6 @@ export class ContainerRuntime
1290
1341
  // Later updates come through calls to setConnectionState.
1291
1342
  this._connected = connected;
1292
1343
 
1293
- this.gcTombstoneEnforcementAllowed = shouldAllowGcTombstoneEnforcement(
1294
- metadata?.gcFeatureMatrix?.tombstoneGeneration /* persisted */,
1295
- this.runtimeOptions.gcOptions[gcTombstoneGenerationOptionName] /* current */,
1296
- );
1297
-
1298
1344
  this.mc.logger.sendTelemetryEvent({
1299
1345
  eventName: "GCFeatureMatrix",
1300
1346
  metadataValue: JSON.stringify(metadata?.gcFeatureMatrix),
@@ -1726,7 +1772,7 @@ export class ContainerRuntime
1726
1772
  /**
1727
1773
  * Notifies this object about the request made to the container.
1728
1774
  * @param request - Request made to the handler.
1729
- * @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
1730
1776
  */
1731
1777
  public async request(request: IRequest): Promise<IResponse> {
1732
1778
  try {
@@ -1778,7 +1824,10 @@ export class ContainerRuntime
1778
1824
  }
1779
1825
  : create404Response(request);
1780
1826
  } else if (requestParser.pathParts.length > 0) {
1781
- 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
+
1782
1831
  const subRequest = requestParser.createSubRequest(1);
1783
1832
  // We always expect createSubRequest to include a leading slash, but asserting here to protect against
1784
1833
  // unintentionally modifying the url if that changes.
@@ -1811,6 +1860,7 @@ export class ContainerRuntime
1811
1860
  private async getDataStoreFromRequest(
1812
1861
  id: string,
1813
1862
  request: IRequest,
1863
+ requestForChild: boolean,
1814
1864
  ): Promise<IFluidDataStoreChannel> {
1815
1865
  const headerData: RuntimeHeaderData = {};
1816
1866
  if (typeof request.headers?.[RuntimeHeaders.wait] === "boolean") {
@@ -1823,6 +1873,11 @@ export class ContainerRuntime
1823
1873
  headerData.allowTombstone = request.headers[AllowTombstoneRequestHeaderKey];
1824
1874
  }
1825
1875
 
1876
+ // We allow Tombstone requests for sub-DataStore objects
1877
+ if (requestForChild) {
1878
+ headerData.allowTombstone = true;
1879
+ }
1880
+
1826
1881
  await this.dataStores.waitIfPendingAlias(id);
1827
1882
  const internalId = this.internalId(id);
1828
1883
  const dataStoreContext = await this.dataStores.getDataStore(internalId, headerData);
@@ -2382,7 +2437,7 @@ export class ContainerRuntime
2382
2437
  * Returns the runtime of the data store.
2383
2438
  * @param id - Id supplied during creating the data store.
2384
2439
  * @param wait - True if you want to wait for it.
2385
- * @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.
2386
2441
  */
2387
2442
  // eslint-disable-next-line import/no-deprecated
2388
2443
  public async getRootDataStore(id: string, wait = true): Promise<IFluidRouter> {
@@ -2609,16 +2664,28 @@ export class ContainerRuntime
2609
2664
  * Submits the signal to be sent to other clients.
2610
2665
  * @param type - Type of the signal.
2611
2666
  * @param content - Content of the signal.
2667
+ * @param targetClientId - When specified, the signal is only sent to the provided client id.
2612
2668
  */
2613
- public submitSignal(type: string, content: any) {
2669
+ public submitSignal(type: string, content: any, targetClientId?: string) {
2614
2670
  this.verifyNotClosed();
2615
2671
  const envelope = this.createNewSignalEnvelope(undefined /* address */, type, content);
2616
- return this.submitSignalFn(envelope);
2672
+ return this.submitSignalFn(envelope, targetClientId);
2617
2673
  }
2618
2674
 
2619
- 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
+ ) {
2620
2687
  const envelope = this.createNewSignalEnvelope(address, type, content);
2621
- return this.submitSignalFn(envelope);
2688
+ return this.submitSignalFn(envelope, targetClientId);
2622
2689
  }
2623
2690
 
2624
2691
  public setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void {
@@ -2817,7 +2884,7 @@ export class ContainerRuntime
2817
2884
  }
2818
2885
 
2819
2886
  /**
2820
- * @deprecated - Replaced by deleteSweepReadyNodes.
2887
+ * @deprecated Replaced by deleteSweepReadyNodes.
2821
2888
  */
2822
2889
  public deleteUnusedNodes(unusedRoutes: string[]): string[] {
2823
2890
  throw new Error("deleteUnusedRoutes should not be called");
@@ -3737,7 +3804,7 @@ export class ContainerRuntime
3737
3804
  * and then close as the current main client is likely to be re-elected as the parent summarizer again.
3738
3805
  */
3739
3806
  if (!result.isSummaryTracked && result.isSummaryNewer) {
3740
- const fetchResult = await this.fetchSnapshotFromStorage(
3807
+ const fetchResult = await this.fetchLatestSnapshotFromStorage(
3741
3808
  summaryLogger,
3742
3809
  {
3743
3810
  eventName: "RefreshLatestSummaryAckFetch",
@@ -3745,7 +3812,6 @@ export class ContainerRuntime
3745
3812
  targetSequenceNumber: summaryRefSeq,
3746
3813
  },
3747
3814
  readAndParseBlob,
3748
- null,
3749
3815
  );
3750
3816
 
3751
3817
  /**
@@ -3794,13 +3860,12 @@ export class ContainerRuntime
3794
3860
 
3795
3861
  // This is a performance optimization as the same parent is likely to be elected again, and would use its
3796
3862
  // cache to fetch the snapshot instead of the network.
3797
- await this.fetchSnapshotFromStorage(
3863
+ await this.fetchLatestSnapshotFromStorage(
3798
3864
  summaryLogger,
3799
3865
  {
3800
3866
  eventName: "RefreshLatestSummaryFromServerFetch",
3801
3867
  },
3802
3868
  readAndParseBlob,
3803
- null,
3804
3869
  );
3805
3870
 
3806
3871
  await this.closeStaleSummarizer("RefreshLatestSummaryFromServerFetch");
@@ -3814,16 +3879,6 @@ export class ContainerRuntime
3814
3879
  }
3815
3880
 
3816
3881
  private async closeStaleSummarizer(codePath: string): Promise<void> {
3817
- this.mc.logger.sendTelemetryEvent(
3818
- {
3819
- eventName: "ClosingSummarizerOnSummaryStale",
3820
- codePath,
3821
- message: "Stopping fetch from storage",
3822
- closeSummarizerDelayMs: this.closeSummarizerDelayMs,
3823
- },
3824
- new GenericError("Restarting summarizer instead of refreshing"),
3825
- );
3826
-
3827
3882
  // Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
3828
3883
  await delay(this.closeSummarizerDelayMs);
3829
3884
  this._summarizer?.stop("latestSummaryStateStale");
@@ -3831,15 +3886,14 @@ export class ContainerRuntime
3831
3886
  }
3832
3887
 
3833
3888
  /**
3834
- * Downloads snapshot from storage with the given versionId or latest if versionId is null.
3889
+ * Downloads the latest snapshot from storage.
3835
3890
  * By default, it also closes the container after downloading the snapshot. However, this may be
3836
3891
  * overridden via options.
3837
3892
  */
3838
- private async fetchSnapshotFromStorage(
3893
+ private async fetchLatestSnapshotFromStorage(
3839
3894
  logger: ITelemetryLoggerExt,
3840
3895
  event: ITelemetryGenericEvent,
3841
3896
  readAndParseBlob: ReadAndParseBlob,
3842
- versionId: string | null,
3843
3897
  ): Promise<{ snapshotTree: ISnapshotTree; versionId: string; latestSnapshotRefSeq: number }> {
3844
3898
  return PerformanceEvent.timedExecAsync(
3845
3899
  logger,
@@ -3861,10 +3915,10 @@ export class ContainerRuntime
3861
3915
  const trace = Trace.start();
3862
3916
 
3863
3917
  const versions = await this.storage.getVersions(
3864
- versionId,
3918
+ null,
3865
3919
  1,
3866
3920
  "prefetchLatestSummaryBeforeClose",
3867
- versionId === null ? FetchSource.noCache : undefined,
3921
+ FetchSource.noCache,
3868
3922
  );
3869
3923
  assert(
3870
3924
  !!versions && !!versions[0],
@@ -3891,9 +3945,7 @@ export class ContainerRuntime
3891
3945
 
3892
3946
  public notifyAttaching() {} // do nothing (deprecated method)
3893
3947
 
3894
- public async getPendingLocalState(props?: {
3895
- notifyImminentClosure: boolean;
3896
- }): Promise<unknown> {
3948
+ public async getPendingLocalState(props?: IGetPendingLocalStateProps): Promise<unknown> {
3897
3949
  return PerformanceEvent.timedExecAsync(
3898
3950
  this.mc.logger,
3899
3951
  {
@@ -3903,6 +3955,7 @@ export class ContainerRuntime
3903
3955
  async (event) => {
3904
3956
  this.verifyNotClosed();
3905
3957
  const waitBlobsToAttach = props?.notifyImminentClosure;
3958
+ const stopBlobAttachingSignal = props?.stopBlobAttachingSignal;
3906
3959
  if (this._orderSequentiallyCalls !== 0) {
3907
3960
  throw new UsageError("can't get state during orderSequentially");
3908
3961
  }
@@ -3911,7 +3964,7 @@ export class ContainerRuntime
3911
3964
  // to close current batch.
3912
3965
  this.flush();
3913
3966
  const pendingAttachmentBlobs = waitBlobsToAttach
3914
- ? await this.blobManager.attachAndGetPendingBlobs()
3967
+ ? await this.blobManager.attachAndGetPendingBlobs(stopBlobAttachingSignal)
3915
3968
  : undefined;
3916
3969
  const pending = this.pendingStateManager.getLocalState();
3917
3970
  if (!pendingAttachmentBlobs && !this.hasPendingMessages()) {
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;
@@ -78,7 +78,7 @@ import {
78
78
  summarizerClientType,
79
79
  } from "./summary";
80
80
  import { ContainerRuntime } from "./containerRuntime";
81
- import { sendGCUnexpectedUsageEvent, throwOnTombstoneUsageKey } from "./gc";
81
+ import { sendGCUnexpectedUsageEvent } from "./gc";
82
82
 
83
83
  function createAttributes(
84
84
  pkg: readonly string[],
@@ -325,11 +325,7 @@ export abstract class FluidDataStoreContext
325
325
  this.mc.logger,
326
326
  );
327
327
 
328
- // Tombstone should only throw when the feature flag is enabled and the client isn't a summarizer
329
- this.throwOnTombstoneUsage =
330
- this.mc.config.getBoolean(throwOnTombstoneUsageKey) === true &&
331
- this._containerRuntime.gcTombstoneEnforcementAllowed &&
332
- this.clientDetails.type !== summarizerClientType;
328
+ this.throwOnTombstoneUsage = this._containerRuntime.gcThrowOnTombstoneUsage;
333
329
 
334
330
  // By default, a data store can log maximum 10 local changes telemetry in summarizer.
335
331
  this.localChangesTelemetryCount =
@@ -458,6 +454,11 @@ export abstract class FluidDataStoreContext
458
454
  const channel = await factory.instantiateDataStore(this, existing);
459
455
  assert(channel !== undefined, 0x140 /* "undefined channel on datastore context" */);
460
456
  this.bindRuntime(channel);
457
+ // This data store may have been disposed before the channel is created during realization. If so,
458
+ // dispose the channel now.
459
+ if (this.disposed) {
460
+ channel.dispose();
461
+ }
461
462
  }
462
463
 
463
464
  /**
@@ -720,11 +721,17 @@ export abstract class FluidDataStoreContext
720
721
  }
721
722
  }
722
723
 
723
- public submitSignal(type: string, content: any) {
724
+ /**
725
+ * Submits the signal to be sent to other clients.
726
+ * @param type - Type of the signal.
727
+ * @param content - Content of the signal.
728
+ * @param targetClientId - When specified, the signal is only sent to the provided client id.
729
+ */
730
+ public submitSignal(type: string, content: any, targetClientId?: string) {
724
731
  this.verifyNotClosed("submitSignal");
725
732
 
726
733
  assert(!!this.channel, 0x147 /* "Channel must exist on submitting signal" */);
727
- return this._containerRuntime.submitDataStoreSignal(this.id, type, content);
734
+ return this._containerRuntime.submitDataStoreSignal(this.id, type, content, targetClientId);
728
735
  }
729
736
 
730
737
  /**
@@ -815,7 +822,7 @@ export abstract class FluidDataStoreContext
815
822
  }
816
823
 
817
824
  /**
818
- * @deprecated - The functionality to get base GC details has been moved to summarizer node.
825
+ * @deprecated The functionality to get base GC details has been moved to summarizer node.
819
826
  */
820
827
  public async getBaseGCDetails(): Promise<IGarbageCollectionDetailsBase> {
821
828
  return {};
@@ -9,6 +9,9 @@ import {
9
9
  NamedFluidDataStoreRegistryEntries,
10
10
  } from "@fluidframework/runtime-definitions";
11
11
 
12
+ /**
13
+ * @public
14
+ */
12
15
  export class FluidDataStoreRegistry implements IFluidDataStoreRegistry {
13
16
  private readonly map: Map<
14
17
  string,
package/src/dataStores.ts CHANGED
@@ -65,12 +65,7 @@ import {
65
65
  } from "./dataStoreContext";
66
66
  import { StorageServiceWithAttachBlobs } from "./storageServiceWithAttachBlobs";
67
67
  import { IDataStoreAliasMessage, isDataStoreAliasMessage } from "./dataStore";
68
- import {
69
- GCNodeType,
70
- disableDatastoreSweepKey,
71
- throwOnTombstoneLoadKey,
72
- sendGCUnexpectedUsageEvent,
73
- } from "./gc";
68
+ import { GCNodeType, disableDatastoreSweepKey, sendGCUnexpectedUsageEvent } from "./gc";
74
69
  import {
75
70
  summarizerClientType,
76
71
  IContainerRuntimeMetadata,
@@ -104,8 +99,6 @@ export class DataStores implements IDisposable {
104
99
  // Stores the ids of new data stores between two GC runs. This is used to notify the garbage collector of new
105
100
  // root data stores that are added.
106
101
  private dataStoresSinceLastGC: string[] = [];
107
- /** If true, throw an error when a tombstone data store is retrieved. */
108
- private readonly throwOnTombstoneLoad: boolean;
109
102
  // The handle to the container runtime. This is used mainly for GC purposes to represent outbound reference from
110
103
  // the container runtime to other nodes.
111
104
  private readonly containerRuntimeHandle: IFluidHandle;
@@ -140,12 +133,6 @@ export class DataStores implements IDisposable {
140
133
  this.runtime.IFluidHandleContext,
141
134
  );
142
135
 
143
- // Tombstone should only throw when the feature flag is enabled and the client isn't a summarizer
144
- this.throwOnTombstoneLoad =
145
- this.mc.config.getBoolean(throwOnTombstoneLoadKey) === true &&
146
- this.runtime.gcTombstoneEnforcementAllowed &&
147
- this.runtime.clientDetails.type !== summarizerClientType;
148
-
149
136
  // Extract stores stored inside the snapshot
150
137
  const fluidDataStores = new Map<string, ISnapshotTree>();
151
138
  if (baseSnapshot) {
@@ -542,7 +529,8 @@ export class DataStores implements IDisposable {
542
529
  if (!context.tombstoned) {
543
530
  return false;
544
531
  }
545
- const logErrorEvent = this.throwOnTombstoneLoad && !requestHeaderData.allowTombstone;
532
+ const logErrorEvent =
533
+ this.runtime.gcThrowOnTombstoneLoad && !requestHeaderData.allowTombstone;
546
534
  sendGCUnexpectedUsageEvent(
547
535
  this.mc,
548
536
  {
@@ -578,7 +566,7 @@ export class DataStores implements IDisposable {
578
566
  request,
579
567
  );
580
568
  // Throw an error if configured via options and via request headers.
581
- if (this.throwOnTombstoneLoad && !requestHeaderData.allowTombstone) {
569
+ if (this.runtime.gcThrowOnTombstoneLoad && !requestHeaderData.allowTombstone) {
582
570
  throw error;
583
571
  }
584
572
  }
@@ -101,8 +101,8 @@ export class DeltaManagerProxyBase
101
101
  super.dispose();
102
102
  }
103
103
 
104
- public submitSignal(content: any): void {
105
- return this.deltaManager.submitSignal(content);
104
+ public submitSignal(content: any, targetClientId?: string): void {
105
+ return this.deltaManager.submitSignal(content, targetClientId);
106
106
  }
107
107
 
108
108
  public flush(): void {
@@ -113,6 +113,19 @@ export class GarbageCollector implements IGarbageCollector {
113
113
  private readonly summaryStateTracker: GCSummaryStateTracker;
114
114
  private readonly telemetryTracker: GCTelemetryTracker;
115
115
 
116
+ /** If false, loading or using a Tombstoned object should merely log, not fail */
117
+ public get tombstoneEnforcementAllowed(): boolean {
118
+ return this.configs.tombstoneEnforcementAllowed;
119
+ }
120
+ /** If true, throw an error when a tombstone data store is retrieved */
121
+ public get throwOnTombstoneLoad(): boolean {
122
+ return this.configs.throwOnTombstoneLoad;
123
+ }
124
+ /** If true, throw an error when a tombstone data store is used */
125
+ public get throwOnTombstoneUsage(): boolean {
126
+ return this.configs.throwOnTombstoneUsage;
127
+ }
128
+
116
129
  /** For a given node path, returns the node's package path. */
117
130
  private readonly getNodePackagePath: (
118
131
  nodePath: string,
@@ -176,7 +189,6 @@ export class GarbageCollector implements IGarbageCollector {
176
189
  this.mc,
177
190
  this.configs,
178
191
  this.isSummarizerClient,
179
- this.runtime.gcTombstoneEnforcementAllowed,
180
192
  createParams.createContainerMetadata,
181
193
  (nodeId: string) => this.runtime.getNodeType(nodeId),
182
194
  (nodeId: string) => this.unreferencedNodesState.get(nodeId),
@@ -881,8 +893,11 @@ export class GarbageCollector implements IGarbageCollector {
881
893
  viaHandle: requestHeaders?.[RuntimeHeaders.viaHandle],
882
894
  });
883
895
 
884
- // Unless this is a Loaded event, we're done after telemetry tracking
885
- if (reason !== "Loaded") {
896
+ // Unless this is a Loaded event for a Blob or DataStore, we're done after telemetry tracking
897
+ if (
898
+ reason !== "Loaded" ||
899
+ ![GCNodeType.Blob, GCNodeType.DataStore].includes(this.runtime.getNodeType(nodePath))
900
+ ) {
886
901
  return;
887
902
  }
888
903