@fluidframework/container-runtime 2.0.0-dev-rc.5.0.0.271717 → 2.0.0-dev-rc.5.0.0.272889

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 (257) hide show
  1. package/api-extractor/api-extractor-lint-bundle.json +5 -0
  2. package/api-extractor/api-extractor-lint-legacy.cjs.json +5 -0
  3. package/api-extractor/api-extractor-lint-legacy.esm.json +5 -0
  4. package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
  5. package/api-extractor/api-extractor-lint-public.esm.json +5 -0
  6. package/api-extractor.json +1 -1
  7. package/api-report/container-runtime.alpha.api.md +1 -1
  8. package/container-runtime.test-files.tar +0 -0
  9. package/dist/batchTracker.d.ts.map +1 -1
  10. package/dist/batchTracker.js.map +1 -1
  11. package/dist/blobManager.d.ts.map +1 -1
  12. package/dist/blobManager.js.map +1 -1
  13. package/dist/channelCollection.d.ts +12 -2
  14. package/dist/channelCollection.d.ts.map +1 -1
  15. package/dist/channelCollection.js +86 -90
  16. package/dist/channelCollection.js.map +1 -1
  17. package/dist/connectionTelemetry.d.ts.map +1 -1
  18. package/dist/connectionTelemetry.js.map +1 -1
  19. package/dist/containerRuntime.d.ts +2 -1
  20. package/dist/containerRuntime.d.ts.map +1 -1
  21. package/dist/containerRuntime.js +29 -9
  22. package/dist/containerRuntime.js.map +1 -1
  23. package/dist/dataStoreContext.d.ts +2 -1
  24. package/dist/dataStoreContext.d.ts.map +1 -1
  25. package/dist/dataStoreContext.js +5 -3
  26. package/dist/dataStoreContext.js.map +1 -1
  27. package/dist/dataStoreContexts.d.ts.map +1 -1
  28. package/dist/dataStoreContexts.js.map +1 -1
  29. package/dist/deltaManagerProxies.d.ts.map +1 -1
  30. package/dist/deltaManagerProxies.js.map +1 -1
  31. package/dist/deltaScheduler.d.ts.map +1 -1
  32. package/dist/deltaScheduler.js +1 -3
  33. package/dist/deltaScheduler.js.map +1 -1
  34. package/dist/gc/garbageCollection.d.ts +4 -2
  35. package/dist/gc/garbageCollection.d.ts.map +1 -1
  36. package/dist/gc/garbageCollection.js +12 -8
  37. package/dist/gc/garbageCollection.js.map +1 -1
  38. package/dist/gc/gcConfigs.js +1 -1
  39. package/dist/gc/gcConfigs.js.map +1 -1
  40. package/dist/gc/gcDefinitions.d.ts +7 -4
  41. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  42. package/dist/gc/gcDefinitions.js.map +1 -1
  43. package/dist/gc/gcHelpers.d.ts.map +1 -1
  44. package/dist/gc/gcHelpers.js.map +1 -1
  45. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  46. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  47. package/dist/gc/gcTelemetry.d.ts +1 -1
  48. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  49. package/dist/gc/gcTelemetry.js +1 -7
  50. package/dist/gc/gcTelemetry.js.map +1 -1
  51. package/dist/index.d.ts +1 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js.map +1 -1
  54. package/dist/messageTypes.d.ts +5 -21
  55. package/dist/messageTypes.d.ts.map +1 -1
  56. package/dist/messageTypes.js.map +1 -1
  57. package/dist/opLifecycle/index.d.ts +1 -1
  58. package/dist/opLifecycle/index.d.ts.map +1 -1
  59. package/dist/opLifecycle/index.js.map +1 -1
  60. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  61. package/dist/opLifecycle/opDecompressor.js +1 -2
  62. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  63. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  64. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  65. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  66. package/dist/opLifecycle/opSplitter.js +1 -1
  67. package/dist/opLifecycle/opSplitter.js.map +1 -1
  68. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  69. package/dist/opLifecycle/outbox.js.map +1 -1
  70. package/dist/packageVersion.d.ts +1 -1
  71. package/dist/packageVersion.js +1 -1
  72. package/dist/packageVersion.js.map +1 -1
  73. package/dist/pendingStateManager.d.ts.map +1 -1
  74. package/dist/pendingStateManager.js +1 -1
  75. package/dist/pendingStateManager.js.map +1 -1
  76. package/dist/summary/documentSchema.d.ts.map +1 -1
  77. package/dist/summary/documentSchema.js +1 -2
  78. package/dist/summary/documentSchema.js.map +1 -1
  79. package/dist/summary/index.d.ts +1 -1
  80. package/dist/summary/index.d.ts.map +1 -1
  81. package/dist/summary/index.js.map +1 -1
  82. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  83. package/dist/summary/orderedClientElection.js.map +1 -1
  84. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  85. package/dist/summary/runningSummarizer.js +1 -2
  86. package/dist/summary/runningSummarizer.js.map +1 -1
  87. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  88. package/dist/summary/summarizerClientElection.js.map +1 -1
  89. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  90. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  91. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  92. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  93. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  94. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +4 -1
  95. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  96. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  97. package/dist/summary/summarizerTypes.js.map +1 -1
  98. package/dist/summary/summaryCollection.d.ts.map +1 -1
  99. package/dist/summary/summaryCollection.js.map +1 -1
  100. package/dist/summary/summaryFormat.d.ts.map +1 -1
  101. package/dist/summary/summaryFormat.js.map +1 -1
  102. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  103. package/dist/summary/summaryGenerator.js +1 -2
  104. package/dist/summary/summaryGenerator.js.map +1 -1
  105. package/dist/summary/summaryManager.d.ts.map +1 -1
  106. package/dist/summary/summaryManager.js +1 -2
  107. package/dist/summary/summaryManager.js.map +1 -1
  108. package/dist/throttler.d.ts.map +1 -1
  109. package/dist/throttler.js +3 -1
  110. package/dist/throttler.js.map +1 -1
  111. package/lib/batchTracker.d.ts.map +1 -1
  112. package/lib/batchTracker.js +1 -1
  113. package/lib/batchTracker.js.map +1 -1
  114. package/lib/blobManager.d.ts.map +1 -1
  115. package/lib/blobManager.js +1 -1
  116. package/lib/blobManager.js.map +1 -1
  117. package/lib/channelCollection.d.ts +12 -2
  118. package/lib/channelCollection.d.ts.map +1 -1
  119. package/lib/channelCollection.js +86 -90
  120. package/lib/channelCollection.js.map +1 -1
  121. package/lib/connectionTelemetry.d.ts.map +1 -1
  122. package/lib/connectionTelemetry.js.map +1 -1
  123. package/lib/containerRuntime.d.ts +2 -1
  124. package/lib/containerRuntime.d.ts.map +1 -1
  125. package/lib/containerRuntime.js +32 -12
  126. package/lib/containerRuntime.js.map +1 -1
  127. package/lib/dataStoreContext.d.ts +2 -1
  128. package/lib/dataStoreContext.d.ts.map +1 -1
  129. package/lib/dataStoreContext.js +5 -3
  130. package/lib/dataStoreContext.js.map +1 -1
  131. package/lib/dataStoreContexts.d.ts.map +1 -1
  132. package/lib/dataStoreContexts.js +1 -1
  133. package/lib/dataStoreContexts.js.map +1 -1
  134. package/lib/deltaManagerProxies.d.ts.map +1 -1
  135. package/lib/deltaManagerProxies.js.map +1 -1
  136. package/lib/deltaScheduler.d.ts.map +1 -1
  137. package/lib/deltaScheduler.js +1 -3
  138. package/lib/deltaScheduler.js.map +1 -1
  139. package/lib/gc/garbageCollection.d.ts +4 -2
  140. package/lib/gc/garbageCollection.d.ts.map +1 -1
  141. package/lib/gc/garbageCollection.js +13 -9
  142. package/lib/gc/garbageCollection.js.map +1 -1
  143. package/lib/gc/gcConfigs.js +1 -1
  144. package/lib/gc/gcConfigs.js.map +1 -1
  145. package/lib/gc/gcDefinitions.d.ts +7 -4
  146. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  147. package/lib/gc/gcDefinitions.js.map +1 -1
  148. package/lib/gc/gcHelpers.d.ts.map +1 -1
  149. package/lib/gc/gcHelpers.js.map +1 -1
  150. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  151. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  152. package/lib/gc/gcTelemetry.d.ts +1 -1
  153. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  154. package/lib/gc/gcTelemetry.js +1 -7
  155. package/lib/gc/gcTelemetry.js.map +1 -1
  156. package/lib/index.d.ts +1 -1
  157. package/lib/index.d.ts.map +1 -1
  158. package/lib/index.js.map +1 -1
  159. package/lib/messageTypes.d.ts +5 -21
  160. package/lib/messageTypes.d.ts.map +1 -1
  161. package/lib/messageTypes.js.map +1 -1
  162. package/lib/opLifecycle/index.d.ts +1 -1
  163. package/lib/opLifecycle/index.d.ts.map +1 -1
  164. package/lib/opLifecycle/index.js +1 -1
  165. package/lib/opLifecycle/index.js.map +1 -1
  166. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  167. package/lib/opLifecycle/opDecompressor.js +1 -2
  168. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  169. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  170. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  171. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  172. package/lib/opLifecycle/opSplitter.js +1 -1
  173. package/lib/opLifecycle/opSplitter.js.map +1 -1
  174. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  175. package/lib/opLifecycle/outbox.js.map +1 -1
  176. package/lib/packageVersion.d.ts +1 -1
  177. package/lib/packageVersion.js +1 -1
  178. package/lib/packageVersion.js.map +1 -1
  179. package/lib/pendingStateManager.d.ts.map +1 -1
  180. package/lib/pendingStateManager.js +1 -1
  181. package/lib/pendingStateManager.js.map +1 -1
  182. package/lib/summary/documentSchema.d.ts.map +1 -1
  183. package/lib/summary/documentSchema.js +1 -2
  184. package/lib/summary/documentSchema.js.map +1 -1
  185. package/lib/summary/index.d.ts +1 -1
  186. package/lib/summary/index.d.ts.map +1 -1
  187. package/lib/summary/index.js +1 -1
  188. package/lib/summary/index.js.map +1 -1
  189. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  190. package/lib/summary/orderedClientElection.js.map +1 -1
  191. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  192. package/lib/summary/runningSummarizer.js +1 -2
  193. package/lib/summary/runningSummarizer.js.map +1 -1
  194. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  195. package/lib/summary/summarizerClientElection.js.map +1 -1
  196. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  197. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  198. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  199. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  200. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  201. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +4 -1
  202. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  203. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  204. package/lib/summary/summarizerTypes.js.map +1 -1
  205. package/lib/summary/summaryCollection.d.ts.map +1 -1
  206. package/lib/summary/summaryCollection.js.map +1 -1
  207. package/lib/summary/summaryFormat.d.ts.map +1 -1
  208. package/lib/summary/summaryFormat.js.map +1 -1
  209. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  210. package/lib/summary/summaryGenerator.js +1 -2
  211. package/lib/summary/summaryGenerator.js.map +1 -1
  212. package/lib/summary/summaryManager.d.ts.map +1 -1
  213. package/lib/summary/summaryManager.js +1 -2
  214. package/lib/summary/summaryManager.js.map +1 -1
  215. package/lib/throttler.d.ts.map +1 -1
  216. package/lib/throttler.js +3 -1
  217. package/lib/throttler.js.map +1 -1
  218. package/package.json +33 -20
  219. package/src/batchTracker.ts +4 -1
  220. package/src/blobManager.ts +14 -16
  221. package/src/channelCollection.ts +139 -132
  222. package/src/connectionTelemetry.ts +3 -8
  223. package/src/containerRuntime.ts +72 -44
  224. package/src/dataStoreContext.ts +34 -11
  225. package/src/dataStoreContexts.ts +7 -2
  226. package/src/deltaManagerProxies.ts +12 -3
  227. package/src/deltaScheduler.ts +1 -3
  228. package/src/gc/garbageCollection.ts +47 -31
  229. package/src/gc/gcConfigs.ts +7 -3
  230. package/src/gc/gcDefinitions.ts +16 -4
  231. package/src/gc/gcHelpers.ts +6 -2
  232. package/src/gc/gcSummaryStateTracker.ts +4 -1
  233. package/src/gc/gcTelemetry.ts +2 -9
  234. package/src/index.ts +0 -1
  235. package/src/messageTypes.ts +7 -23
  236. package/src/opLifecycle/index.ts +5 -1
  237. package/src/opLifecycle/opDecompressor.ts +2 -6
  238. package/src/opLifecycle/opGroupingManager.ts +1 -4
  239. package/src/opLifecycle/opSplitter.ts +9 -3
  240. package/src/opLifecycle/outbox.ts +1 -4
  241. package/src/packageVersion.ts +1 -1
  242. package/src/pendingStateManager.ts +4 -2
  243. package/src/summary/documentSchema.ts +4 -7
  244. package/src/summary/index.ts +4 -1
  245. package/src/summary/orderedClientElection.ts +17 -10
  246. package/src/summary/runningSummarizer.ts +20 -9
  247. package/src/summary/summarizerClientElection.ts +2 -1
  248. package/src/summary/summarizerNode/summarizerNode.ts +6 -4
  249. package/src/summary/summarizerNode/summarizerNodeUtils.ts +7 -2
  250. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +10 -6
  251. package/src/summary/summarizerTypes.ts +9 -2
  252. package/src/summary/summaryCollection.ts +4 -1
  253. package/src/summary/summaryFormat.ts +8 -3
  254. package/src/summary/summaryGenerator.ts +4 -9
  255. package/src/summary/summaryManager.ts +6 -9
  256. package/src/throttler.ts +3 -1
  257. package/tsdoc.json +4 -0
@@ -266,7 +266,7 @@ class ChannelCollection {
266
266
  const foundGCData = (0, internal_5.processAttachMessageGCData)(attachMessage.snapshot, (nodeId, toPath) => {
267
267
  // nodeId is the relative path under the node being attached. Always starts with "/", but no trailing "/" after an id
268
268
  const fromPath = `/${attachMessage.id}${nodeId === "/" ? "" : nodeId}`;
269
- this.parentContext.addedGCOutboundRoute(fromPath, toPath);
269
+ this.parentContext.addedGCOutboundRoute(fromPath, toPath, message.timestamp);
270
270
  });
271
271
  // Only log once per container to avoid noise/cost.
272
272
  // Allows longitudinal tracking of various state (e.g. foundGCData), and some sampled details
@@ -338,12 +338,12 @@ class ChannelCollection {
338
338
  });
339
339
  }
340
340
  const resolve = localOpMetadata;
341
- const aliasResult = this.processAliasMessageCore(aliasMessage.internalId, aliasMessage.alias);
341
+ const aliasResult = this.processAliasMessageCore(aliasMessage.internalId, aliasMessage.alias, message.timestamp);
342
342
  if (local) {
343
343
  resolve(aliasResult);
344
344
  }
345
345
  }
346
- processAliasMessageCore(internalId, alias) {
346
+ processAliasMessageCore(internalId, alias, messageTimestampMs) {
347
347
  if (this.alreadyProcessed(alias)) {
348
348
  return false;
349
349
  }
@@ -360,7 +360,11 @@ class ChannelCollection {
360
360
  });
361
361
  return false;
362
362
  }
363
- this.parentContext.addedGCOutboundRoute("/", `/${internalId}`);
363
+ // If message timestamp doesn't exist, this is called in a detached container. Don't notify GC in that case
364
+ // because it doesn't run in detached container and doesn't need to know about this route.
365
+ if (messageTimestampMs) {
366
+ this.parentContext.addedGCOutboundRoute("/", `/${internalId}`, messageTimestampMs);
367
+ }
364
368
  this.aliasMap.set(alias, context.id);
365
369
  this.aliasedDataStores.add(context.id);
366
370
  context.setInMemoryRoot();
@@ -593,7 +597,7 @@ class ChannelCollection {
593
597
  };
594
598
  this.processChannelOp(envelope.address, transformed, local, localMessageMetadata);
595
599
  // Notify GC of any outbound references that were added by this op.
596
- detectOutboundReferences(envelope.address, transformed.contents, (fromPath, toPath) => this.parentContext.addedGCOutboundRoute(fromPath, toPath));
600
+ detectOutboundReferences(envelope.address, transformed.contents, (fromPath, toPath) => this.parentContext.addedGCOutboundRoute(fromPath, toPath, message.timestamp));
597
601
  break;
598
602
  }
599
603
  default:
@@ -674,9 +678,7 @@ class ChannelCollection {
674
678
  if (!this.isDataStoreDeleted(dataStoreNodePath)) {
675
679
  return false;
676
680
  }
677
- const idToLog = originalRequest !== undefined
678
- ? (0, index_js_1.urlToGCNodePath)(originalRequest.url)
679
- : dataStoreNodePath;
681
+ const idToLog = originalRequest !== undefined ? (0, index_js_1.urlToGCNodePath)(originalRequest.url) : dataStoreNodePath;
680
682
  // Log the package details asynchronously since getInitialSnapshotDetails is async
681
683
  const recentlyDeletedContext = this.contexts.getRecentlyDeletedContext(id);
682
684
  if (recentlyDeletedContext !== undefined) {
@@ -766,61 +768,24 @@ class ChannelCollection {
766
768
  get size() {
767
769
  return this.contexts.size;
768
770
  }
769
- async summarize(fullTree, trackState, telemetryContext) {
770
- const summaryBuilder = new internal_5.SummaryTreeBuilder();
771
- // Iterate over each store and ask it to snapshot
772
- await Promise.all(Array.from(this.contexts)
773
- .filter(([_, context]) => {
774
- // Summarizer works only with clients with no local changes. A data store in attaching
775
- // state indicates an op was sent to attach a local data store, and the the attach op
776
- // had not yet round tripped back to the client.
777
- if (context.attachState === container_definitions_1.AttachState.Attaching) {
778
- // Formerly assert 0x588
779
- const error = internal_6.DataProcessingError.create("Local data store detected in attaching state during summarize", "summarize");
780
- throw error;
781
- }
782
- return context.attachState === container_definitions_1.AttachState.Attached;
783
- })
784
- .map(async ([contextId, context]) => {
785
- const contextSummary = await context.summarize(fullTree, trackState, telemetryContext);
786
- summaryBuilder.addWithStats(contextId, contextSummary);
787
- }));
788
- return summaryBuilder.getSummaryTree();
789
- }
790
771
  /**
791
772
  * Create a summary. Used when attaching or serializing a detached container.
792
773
  */
793
774
  getAttachSummary(telemetryContext) {
794
775
  const builder = new internal_5.SummaryTreeBuilder();
795
- // Attaching graph of some stores can cause other stores to get bound too.
796
- // So keep taking summary until no new stores get bound.
797
- let notBoundContextsLength;
798
- do {
799
- const builderTree = builder.summary.tree;
800
- notBoundContextsLength = this.contexts.notBoundLength();
801
- // Iterate over each data store and ask it to snapshot
802
- Array.from(this.contexts)
803
- .filter(([key, _]) =>
804
- // Take summary of bounded data stores only, make sure we haven't summarized them already
805
- // and no attach op has been fired for that data store because for loader versions <= 0.24
806
- // we set attach state as "attaching" before taking createNew summary.
807
- !(this.contexts.isNotBound(key) ||
808
- builderTree[key] ||
809
- this.attachOpFiredForDataStore.has(key)))
810
- .map(([key, value]) => {
811
- let dataStoreSummary;
812
- if (value.isLoaded) {
813
- dataStoreSummary = value.getAttachSummary(telemetryContext);
814
- }
815
- else {
816
- // If this data store is not yet loaded, then there should be no changes in the snapshot from
817
- // which it was created as it is detached container. So just use the previous snapshot.
818
- (0, internal_1.assert)(!!this.baseSnapshot, 0x166 /* "BaseSnapshot should be there as detached container loaded from snapshot" */);
819
- dataStoreSummary = (0, internal_5.convertSnapshotTreeToSummaryTree)((0, internal_3.getSnapshotTree)(this.baseSnapshot).trees[key]);
820
- }
821
- builder.addWithStats(key, dataStoreSummary);
822
- });
823
- } while (notBoundContextsLength !== this.contexts.notBoundLength());
776
+ this.visitLocalBoundContextsDuringAttach((contextId, context) => {
777
+ let dataStoreSummary;
778
+ if (context.isLoaded) {
779
+ dataStoreSummary = context.getAttachSummary(telemetryContext);
780
+ }
781
+ else {
782
+ // If this data store is not yet loaded, then there should be no changes in the snapshot from
783
+ // which it was created as it is detached container. So just use the previous snapshot.
784
+ (0, internal_1.assert)(!!this.baseSnapshot, 0x166 /* "BaseSnapshot should be there as detached container loaded from snapshot" */);
785
+ dataStoreSummary = (0, internal_5.convertSnapshotTreeToSummaryTree)((0, internal_3.getSnapshotTree)(this.baseSnapshot).trees[contextId]);
786
+ }
787
+ builder.addWithStats(contextId, dataStoreSummary);
788
+ });
824
789
  return builder.getSummaryTree();
825
790
  }
826
791
  /**
@@ -828,27 +793,70 @@ class ChannelCollection {
828
793
  */
829
794
  getAttachGCData(telemetryContext) {
830
795
  const builder = new internal_5.GCDataBuilder();
831
- // Attaching graph of some stores can cause other stores to get bound too.
832
- // So keep taking summary until no new stores get bound.
833
- let notBoundContextsLength;
834
- do {
835
- notBoundContextsLength = this.contexts.notBoundLength();
836
- // Iterate over each data store and ask for its GC data.
837
- Array.from(this.contexts)
838
- .filter(([key, _]) =>
839
- // Take GC data of bounded data stores only.
840
- !this.contexts.isNotBound(key))
841
- .map(([key, value]) => {
842
- const contextGCData = value.getAttachGCData(telemetryContext);
843
- // Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.
844
- // This also gradually builds the id of each node to be a path from the root.
845
- builder.prefixAndAddNodes(key, contextGCData.gcNodes);
846
- });
847
- } while (notBoundContextsLength !== this.contexts.notBoundLength());
796
+ this.visitLocalBoundContextsDuringAttach((contextId, context) => {
797
+ const contextGCData = context.getAttachGCData(telemetryContext);
798
+ // Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.
799
+ // This also gradually builds the id of each node to be a path from the root.
800
+ builder.prefixAndAddNodes(contextId, contextGCData.gcNodes);
801
+ });
848
802
  // Get the outbound routes (aliased data stores) and add a GC node for this channel.
849
803
  builder.addNode("/", Array.from(this.aliasedDataStores));
850
804
  return builder.getGCData();
851
805
  }
806
+ /**
807
+ * Helper method for preparing to attach this channel.
808
+ * Runs the callback for each bound context to incorporate its data however the caller specifies
809
+ */
810
+ visitLocalBoundContextsDuringAttach(visitor) {
811
+ const visitedContexts = new Set();
812
+ let visitedLength = -1;
813
+ let notBoundContextsLength = -1;
814
+ while (visitedLength !== visitedContexts.size &&
815
+ notBoundContextsLength !== this.contexts.notBoundLength()) {
816
+ // detect changes in the visitedContexts set, as on visiting a context
817
+ // it could could make contexts available by removing other contexts
818
+ // from the not bound context list, so we need to ensure those get processed as well.
819
+ // only once the loop can run with no new contexts added to the visitedContexts set do we
820
+ // know for sure all possible contexts have been visited.
821
+ visitedLength = visitedContexts.size;
822
+ notBoundContextsLength = this.contexts.notBoundLength();
823
+ for (const [contextId, context] of this.contexts) {
824
+ if (!(visitedContexts.has(contextId) ||
825
+ this.contexts.isNotBound(contextId) ||
826
+ this.attachOpFiredForDataStore.has(contextId))) {
827
+ visitor(contextId, context);
828
+ visitedContexts.add(contextId);
829
+ }
830
+ }
831
+ }
832
+ }
833
+ /**
834
+ * Helper method for preparing to summarize this channel.
835
+ * Runs the callback for each bound context to incorporate its data however the caller specifies
836
+ */
837
+ async visitContextsDuringSummary(visitor) {
838
+ for (const [contextId, context] of this.contexts) {
839
+ // Summarizer client and hence GC works only with clients with no local changes. A data store in
840
+ // attaching state indicates an op was sent to attach a local data store, and the the attach op
841
+ // had not yet round tripped back to the client.
842
+ // Formerly assert 0x589
843
+ if (context.attachState === container_definitions_1.AttachState.Attaching) {
844
+ const error = internal_6.DataProcessingError.create("Local data store detected in attaching state", "summarize/getGCData");
845
+ throw error;
846
+ }
847
+ if (context.attachState === container_definitions_1.AttachState.Attached) {
848
+ await visitor(contextId, context);
849
+ }
850
+ }
851
+ }
852
+ async summarize(fullTree, trackState, telemetryContext) {
853
+ const summaryBuilder = new internal_5.SummaryTreeBuilder();
854
+ await this.visitContextsDuringSummary(async (contextId, context) => {
855
+ const contextSummary = await context.summarize(fullTree, trackState, telemetryContext);
856
+ summaryBuilder.addWithStats(contextId, contextSummary);
857
+ });
858
+ return summaryBuilder.getSummaryTree();
859
+ }
852
860
  /**
853
861
  * Generates data used for garbage collection. It does the following:
854
862
  *
@@ -864,25 +872,12 @@ class ChannelCollection {
864
872
  */
865
873
  async getGCData(fullGC = false) {
866
874
  const builder = new internal_5.GCDataBuilder();
867
- // Iterate over each store and get their GC data.
868
- await Promise.all(Array.from(this.contexts)
869
- .filter(([_, context]) => {
870
- // Summarizer client and hence GC works only with clients with no local changes. A data store in
871
- // attaching state indicates an op was sent to attach a local data store, and the the attach op
872
- // had not yet round tripped back to the client.
873
- // Formerly assert 0x589
874
- if (context.attachState === container_definitions_1.AttachState.Attaching) {
875
- const error = internal_6.DataProcessingError.create("Local data store detected in attaching state while running GC", "getGCData");
876
- throw error;
877
- }
878
- return context.attachState === container_definitions_1.AttachState.Attached;
879
- })
880
- .map(async ([contextId, context]) => {
875
+ await this.visitContextsDuringSummary(async (contextId, context) => {
881
876
  const contextGCData = await context.getGCData(fullGC);
882
877
  // Prefix the child's id to the ids of its GC nodes so they can be identified as belonging to the child.
883
878
  // This also gradually builds the id of each node to be a path from the root.
884
879
  builder.prefixAndAddNodes(contextId, contextGCData.gcNodes);
885
- }));
880
+ });
886
881
  // Get the outbound routes and add a GC node for this channel.
887
882
  builder.addNode("/", await this.getOutboundRoutes());
888
883
  return builder.getGCData();
@@ -1059,6 +1054,7 @@ class ChannelCollection {
1059
1054
  packagePath: details.pkg,
1060
1055
  request,
1061
1056
  headerData,
1057
+ timestampMs: undefined, // This will be added by the parent context if needed.
1062
1058
  });
1063
1059
  const dataStore = await dataStoreContext.realize();
1064
1060
  const subRequest = requestParser.createSubRequest(1);