@fluidframework/container-runtime 2.53.1 → 2.61.0-355054

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 (478) hide show
  1. package/.mocharc.cjs +1 -2
  2. package/CHANGELOG.md +4 -0
  3. package/api-report/{container-runtime.legacy.alpha.api.md → container-runtime.legacy.beta.api.md} +55 -55
  4. package/container-runtime.test-files.tar +0 -0
  5. package/dist/batchTracker.d.ts +1 -1
  6. package/dist/batchTracker.d.ts.map +1 -1
  7. package/dist/batchTracker.js.map +1 -1
  8. package/dist/blobManager/blobManager.d.ts +29 -17
  9. package/dist/blobManager/blobManager.d.ts.map +1 -1
  10. package/dist/blobManager/blobManager.js +150 -135
  11. package/dist/blobManager/blobManager.js.map +1 -1
  12. package/dist/blobManager/blobManagerSnapSum.d.ts +4 -4
  13. package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  14. package/dist/blobManager/blobManagerSnapSum.js +30 -33
  15. package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
  16. package/dist/blobManager/index.d.ts +2 -2
  17. package/dist/blobManager/index.d.ts.map +1 -1
  18. package/dist/blobManager/index.js.map +1 -1
  19. package/dist/channelCollection.d.ts +9 -11
  20. package/dist/channelCollection.d.ts.map +1 -1
  21. package/dist/channelCollection.js +2 -3
  22. package/dist/channelCollection.js.map +1 -1
  23. package/dist/compressionDefinitions.d.ts +3 -6
  24. package/dist/compressionDefinitions.d.ts.map +1 -1
  25. package/dist/compressionDefinitions.js +2 -4
  26. package/dist/compressionDefinitions.js.map +1 -1
  27. package/dist/connectionTelemetry.d.ts +3 -4
  28. package/dist/connectionTelemetry.d.ts.map +1 -1
  29. package/dist/connectionTelemetry.js.map +1 -1
  30. package/dist/containerHandleContext.d.ts +2 -2
  31. package/dist/containerHandleContext.d.ts.map +1 -1
  32. package/dist/containerHandleContext.js.map +1 -1
  33. package/dist/containerRuntime.d.ts +13 -20
  34. package/dist/containerRuntime.d.ts.map +1 -1
  35. package/dist/containerRuntime.js +4 -7
  36. package/dist/containerRuntime.js.map +1 -1
  37. package/dist/dataStore.d.ts +3 -3
  38. package/dist/dataStore.d.ts.map +1 -1
  39. package/dist/dataStore.js.map +1 -1
  40. package/dist/dataStoreContext.d.ts +8 -8
  41. package/dist/dataStoreContext.d.ts.map +1 -1
  42. package/dist/dataStoreContext.js.map +1 -1
  43. package/dist/dataStoreContexts.d.ts +2 -2
  44. package/dist/dataStoreContexts.d.ts.map +1 -1
  45. package/dist/dataStoreContexts.js.map +1 -1
  46. package/dist/dataStoreRegistry.d.ts +1 -1
  47. package/dist/dataStoreRegistry.d.ts.map +1 -1
  48. package/dist/dataStoreRegistry.js.map +1 -1
  49. package/dist/deltaManagerProxies.d.ts +2 -3
  50. package/dist/deltaManagerProxies.d.ts.map +1 -1
  51. package/dist/deltaManagerProxies.js.map +1 -1
  52. package/dist/deltaScheduler.d.ts +2 -2
  53. package/dist/deltaScheduler.d.ts.map +1 -1
  54. package/dist/deltaScheduler.js.map +1 -1
  55. package/dist/error.d.ts +1 -1
  56. package/dist/error.d.ts.map +1 -1
  57. package/dist/error.js.map +1 -1
  58. package/dist/gc/garbageCollection.d.ts +4 -4
  59. package/dist/gc/garbageCollection.d.ts.map +1 -1
  60. package/dist/gc/garbageCollection.js.map +1 -1
  61. package/dist/gc/gcConfigs.d.ts +3 -3
  62. package/dist/gc/gcConfigs.d.ts.map +1 -1
  63. package/dist/gc/gcConfigs.js.map +1 -1
  64. package/dist/gc/gcDefinitions.d.ts +10 -11
  65. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  66. package/dist/gc/gcDefinitions.js.map +1 -1
  67. package/dist/gc/gcHelpers.d.ts +4 -4
  68. package/dist/gc/gcHelpers.d.ts.map +1 -1
  69. package/dist/gc/gcHelpers.js.map +1 -1
  70. package/dist/gc/gcReferenceGraphAlgorithm.d.ts +1 -1
  71. package/dist/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -1
  72. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  73. package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
  74. package/dist/gc/gcSummaryDefinitions.d.ts.map +1 -1
  75. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  76. package/dist/gc/gcSummaryStateTracker.d.ts +4 -4
  77. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  78. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  79. package/dist/gc/gcTelemetry.d.ts +6 -6
  80. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  81. package/dist/gc/gcTelemetry.js.map +1 -1
  82. package/dist/gc/index.d.ts +3 -3
  83. package/dist/gc/index.d.ts.map +1 -1
  84. package/dist/gc/index.js.map +1 -1
  85. package/dist/inboundBatchAggregator.d.ts +2 -2
  86. package/dist/inboundBatchAggregator.d.ts.map +1 -1
  87. package/dist/inboundBatchAggregator.js.map +1 -1
  88. package/dist/index.d.ts +7 -7
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/legacy.d.ts +2 -1
  92. package/dist/messageTypes.d.ts +7 -8
  93. package/dist/messageTypes.d.ts.map +1 -1
  94. package/dist/messageTypes.js +1 -2
  95. package/dist/messageTypes.js.map +1 -1
  96. package/dist/opLifecycle/batchManager.d.ts +2 -2
  97. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  98. package/dist/opLifecycle/batchManager.js.map +1 -1
  99. package/dist/opLifecycle/definitions.d.ts +1 -1
  100. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  101. package/dist/opLifecycle/definitions.js.map +1 -1
  102. package/dist/opLifecycle/duplicateBatchDetector.d.ts +1 -1
  103. package/dist/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
  104. package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
  105. package/dist/opLifecycle/index.d.ts +5 -5
  106. package/dist/opLifecycle/index.d.ts.map +1 -1
  107. package/dist/opLifecycle/index.js.map +1 -1
  108. package/dist/opLifecycle/opCompressor.d.ts +2 -2
  109. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  110. package/dist/opLifecycle/opCompressor.js.map +1 -1
  111. package/dist/opLifecycle/opDecompressor.d.ts +2 -2
  112. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  113. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  114. package/dist/opLifecycle/opGroupingManager.d.ts +3 -3
  115. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  116. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  117. package/dist/opLifecycle/opSplitter.d.ts +4 -4
  118. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  119. package/dist/opLifecycle/opSplitter.js.map +1 -1
  120. package/dist/opLifecycle/outbox.d.ts +9 -9
  121. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  122. package/dist/opLifecycle/outbox.js.map +1 -1
  123. package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -4
  124. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  125. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  126. package/dist/opProperties.d.ts +1 -1
  127. package/dist/opProperties.d.ts.map +1 -1
  128. package/dist/opProperties.js.map +1 -1
  129. package/dist/packageVersion.d.ts +1 -1
  130. package/dist/packageVersion.d.ts.map +1 -1
  131. package/dist/packageVersion.js +1 -1
  132. package/dist/packageVersion.js.map +1 -1
  133. package/dist/pendingStateManager.d.ts +3 -3
  134. package/dist/pendingStateManager.d.ts.map +1 -1
  135. package/dist/pendingStateManager.js.map +1 -1
  136. package/dist/storageServiceWithAttachBlobs.d.ts +1 -1
  137. package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -1
  138. package/dist/storageServiceWithAttachBlobs.js.map +1 -1
  139. package/dist/summary/documentSchema.d.ts +1 -2
  140. package/dist/summary/documentSchema.d.ts.map +1 -1
  141. package/dist/summary/documentSchema.js.map +1 -1
  142. package/dist/summary/index.d.ts +10 -10
  143. package/dist/summary/index.d.ts.map +1 -1
  144. package/dist/summary/index.js.map +1 -1
  145. package/dist/summary/orderedClientElection.d.ts +4 -4
  146. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  147. package/dist/summary/orderedClientElection.js.map +1 -1
  148. package/dist/summary/summarizerClientElection.d.ts +5 -5
  149. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  150. package/dist/summary/summarizerClientElection.js.map +1 -1
  151. package/dist/summary/summarizerNode/index.d.ts +3 -3
  152. package/dist/summary/summarizerNode/index.d.ts.map +1 -1
  153. package/dist/summary/summarizerNode/index.js.map +1 -1
  154. package/dist/summary/summarizerNode/summarizerNode.d.ts +5 -6
  155. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  156. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  157. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +3 -3
  158. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  159. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  160. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +3 -3
  161. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  162. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  163. package/dist/summary/summarizerTypes.d.ts +25 -44
  164. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  165. package/dist/summary/summarizerTypes.js.map +1 -1
  166. package/dist/summary/summarizerUtils.d.ts +3 -3
  167. package/dist/summary/summarizerUtils.d.ts.map +1 -1
  168. package/dist/summary/summarizerUtils.js.map +1 -1
  169. package/dist/summary/summaryCollection.d.ts +13 -23
  170. package/dist/summary/summaryCollection.d.ts.map +1 -1
  171. package/dist/summary/summaryCollection.js +1 -2
  172. package/dist/summary/summaryCollection.js.map +1 -1
  173. package/dist/summary/summaryDelayLoadedModule/index.d.ts +2 -2
  174. package/dist/summary/summaryDelayLoadedModule/index.d.ts.map +1 -1
  175. package/dist/summary/summaryDelayLoadedModule/index.js.map +1 -1
  176. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts +1 -1
  177. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -1
  178. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
  179. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +3 -3
  180. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  181. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  182. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts +5 -5
  183. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  184. package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  185. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts +3 -4
  186. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -1
  187. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
  188. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +3 -3
  189. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
  190. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  191. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +1 -1
  192. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -1
  193. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
  194. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +5 -10
  195. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -1
  196. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -1
  197. package/dist/summary/summaryFormat.d.ts +9 -14
  198. package/dist/summary/summaryFormat.d.ts.map +1 -1
  199. package/dist/summary/summaryFormat.js.map +1 -1
  200. package/dist/summary/summaryHelpers.d.ts +1 -2
  201. package/dist/summary/summaryHelpers.d.ts.map +1 -1
  202. package/dist/summary/summaryHelpers.js +1 -2
  203. package/dist/summary/summaryHelpers.js.map +1 -1
  204. package/dist/summary/summaryManager.d.ts +3 -3
  205. package/dist/summary/summaryManager.d.ts.map +1 -1
  206. package/dist/summary/summaryManager.js.map +1 -1
  207. package/internal.d.ts +1 -1
  208. package/legacy.d.ts +1 -1
  209. package/lib/batchTracker.d.ts +1 -1
  210. package/lib/batchTracker.d.ts.map +1 -1
  211. package/lib/batchTracker.js.map +1 -1
  212. package/lib/blobManager/blobManager.d.ts +29 -17
  213. package/lib/blobManager/blobManager.d.ts.map +1 -1
  214. package/lib/blobManager/blobManager.js +142 -127
  215. package/lib/blobManager/blobManager.js.map +1 -1
  216. package/lib/blobManager/blobManagerSnapSum.d.ts +4 -4
  217. package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  218. package/lib/blobManager/blobManagerSnapSum.js +26 -29
  219. package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
  220. package/lib/blobManager/index.d.ts +2 -2
  221. package/lib/blobManager/index.d.ts.map +1 -1
  222. package/lib/blobManager/index.js.map +1 -1
  223. package/lib/channelCollection.d.ts +9 -11
  224. package/lib/channelCollection.d.ts.map +1 -1
  225. package/lib/channelCollection.js +2 -3
  226. package/lib/channelCollection.js.map +1 -1
  227. package/lib/compressionDefinitions.d.ts +3 -6
  228. package/lib/compressionDefinitions.d.ts.map +1 -1
  229. package/lib/compressionDefinitions.js +2 -4
  230. package/lib/compressionDefinitions.js.map +1 -1
  231. package/lib/connectionTelemetry.d.ts +3 -4
  232. package/lib/connectionTelemetry.d.ts.map +1 -1
  233. package/lib/connectionTelemetry.js.map +1 -1
  234. package/lib/containerHandleContext.d.ts +2 -2
  235. package/lib/containerHandleContext.d.ts.map +1 -1
  236. package/lib/containerHandleContext.js.map +1 -1
  237. package/lib/containerRuntime.d.ts +13 -20
  238. package/lib/containerRuntime.d.ts.map +1 -1
  239. package/lib/containerRuntime.js +4 -7
  240. package/lib/containerRuntime.js.map +1 -1
  241. package/lib/dataStore.d.ts +3 -3
  242. package/lib/dataStore.d.ts.map +1 -1
  243. package/lib/dataStore.js.map +1 -1
  244. package/lib/dataStoreContext.d.ts +8 -8
  245. package/lib/dataStoreContext.d.ts.map +1 -1
  246. package/lib/dataStoreContext.js.map +1 -1
  247. package/lib/dataStoreContexts.d.ts +2 -2
  248. package/lib/dataStoreContexts.d.ts.map +1 -1
  249. package/lib/dataStoreContexts.js.map +1 -1
  250. package/lib/dataStoreRegistry.d.ts +1 -1
  251. package/lib/dataStoreRegistry.d.ts.map +1 -1
  252. package/lib/dataStoreRegistry.js.map +1 -1
  253. package/lib/deltaManagerProxies.d.ts +2 -3
  254. package/lib/deltaManagerProxies.d.ts.map +1 -1
  255. package/lib/deltaManagerProxies.js.map +1 -1
  256. package/lib/deltaScheduler.d.ts +2 -2
  257. package/lib/deltaScheduler.d.ts.map +1 -1
  258. package/lib/deltaScheduler.js +1 -1
  259. package/lib/deltaScheduler.js.map +1 -1
  260. package/lib/error.d.ts +1 -1
  261. package/lib/error.d.ts.map +1 -1
  262. package/lib/error.js.map +1 -1
  263. package/lib/gc/garbageCollection.d.ts +4 -4
  264. package/lib/gc/garbageCollection.d.ts.map +1 -1
  265. package/lib/gc/garbageCollection.js.map +1 -1
  266. package/lib/gc/gcConfigs.d.ts +3 -3
  267. package/lib/gc/gcConfigs.d.ts.map +1 -1
  268. package/lib/gc/gcConfigs.js.map +1 -1
  269. package/lib/gc/gcDefinitions.d.ts +10 -11
  270. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  271. package/lib/gc/gcDefinitions.js.map +1 -1
  272. package/lib/gc/gcHelpers.d.ts +4 -4
  273. package/lib/gc/gcHelpers.d.ts.map +1 -1
  274. package/lib/gc/gcHelpers.js.map +1 -1
  275. package/lib/gc/gcReferenceGraphAlgorithm.d.ts +1 -1
  276. package/lib/gc/gcReferenceGraphAlgorithm.d.ts.map +1 -1
  277. package/lib/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  278. package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
  279. package/lib/gc/gcSummaryDefinitions.d.ts.map +1 -1
  280. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  281. package/lib/gc/gcSummaryStateTracker.d.ts +4 -4
  282. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  283. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  284. package/lib/gc/gcTelemetry.d.ts +6 -6
  285. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  286. package/lib/gc/gcTelemetry.js.map +1 -1
  287. package/lib/gc/index.d.ts +3 -3
  288. package/lib/gc/index.d.ts.map +1 -1
  289. package/lib/gc/index.js.map +1 -1
  290. package/lib/inboundBatchAggregator.d.ts +2 -2
  291. package/lib/inboundBatchAggregator.d.ts.map +1 -1
  292. package/lib/inboundBatchAggregator.js.map +1 -1
  293. package/lib/index.d.ts +7 -7
  294. package/lib/index.d.ts.map +1 -1
  295. package/lib/index.js.map +1 -1
  296. package/lib/legacy.d.ts +2 -1
  297. package/lib/messageTypes.d.ts +7 -8
  298. package/lib/messageTypes.d.ts.map +1 -1
  299. package/lib/messageTypes.js +1 -2
  300. package/lib/messageTypes.js.map +1 -1
  301. package/lib/opLifecycle/batchManager.d.ts +2 -2
  302. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  303. package/lib/opLifecycle/batchManager.js.map +1 -1
  304. package/lib/opLifecycle/definitions.d.ts +1 -1
  305. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  306. package/lib/opLifecycle/definitions.js.map +1 -1
  307. package/lib/opLifecycle/duplicateBatchDetector.d.ts +1 -1
  308. package/lib/opLifecycle/duplicateBatchDetector.d.ts.map +1 -1
  309. package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
  310. package/lib/opLifecycle/index.d.ts +5 -5
  311. package/lib/opLifecycle/index.d.ts.map +1 -1
  312. package/lib/opLifecycle/index.js.map +1 -1
  313. package/lib/opLifecycle/opCompressor.d.ts +2 -2
  314. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  315. package/lib/opLifecycle/opCompressor.js.map +1 -1
  316. package/lib/opLifecycle/opDecompressor.d.ts +2 -2
  317. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  318. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  319. package/lib/opLifecycle/opGroupingManager.d.ts +3 -3
  320. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  321. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  322. package/lib/opLifecycle/opSplitter.d.ts +4 -4
  323. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  324. package/lib/opLifecycle/opSplitter.js +1 -1
  325. package/lib/opLifecycle/opSplitter.js.map +1 -1
  326. package/lib/opLifecycle/outbox.d.ts +9 -9
  327. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  328. package/lib/opLifecycle/outbox.js.map +1 -1
  329. package/lib/opLifecycle/remoteMessageProcessor.d.ts +4 -4
  330. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  331. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  332. package/lib/opProperties.d.ts +1 -1
  333. package/lib/opProperties.d.ts.map +1 -1
  334. package/lib/opProperties.js.map +1 -1
  335. package/lib/packageVersion.d.ts +1 -1
  336. package/lib/packageVersion.d.ts.map +1 -1
  337. package/lib/packageVersion.js +1 -1
  338. package/lib/packageVersion.js.map +1 -1
  339. package/lib/pendingStateManager.d.ts +3 -3
  340. package/lib/pendingStateManager.d.ts.map +1 -1
  341. package/lib/pendingStateManager.js.map +1 -1
  342. package/lib/storageServiceWithAttachBlobs.d.ts +1 -1
  343. package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -1
  344. package/lib/storageServiceWithAttachBlobs.js.map +1 -1
  345. package/lib/summary/documentSchema.d.ts +1 -2
  346. package/lib/summary/documentSchema.d.ts.map +1 -1
  347. package/lib/summary/documentSchema.js.map +1 -1
  348. package/lib/summary/index.d.ts +10 -10
  349. package/lib/summary/index.d.ts.map +1 -1
  350. package/lib/summary/index.js.map +1 -1
  351. package/lib/summary/orderedClientElection.d.ts +4 -4
  352. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  353. package/lib/summary/orderedClientElection.js.map +1 -1
  354. package/lib/summary/summarizerClientElection.d.ts +5 -5
  355. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  356. package/lib/summary/summarizerClientElection.js.map +1 -1
  357. package/lib/summary/summarizerNode/index.d.ts +3 -3
  358. package/lib/summary/summarizerNode/index.d.ts.map +1 -1
  359. package/lib/summary/summarizerNode/index.js.map +1 -1
  360. package/lib/summary/summarizerNode/summarizerNode.d.ts +5 -6
  361. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  362. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  363. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +3 -3
  364. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  365. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  366. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +3 -3
  367. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  368. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  369. package/lib/summary/summarizerTypes.d.ts +25 -44
  370. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  371. package/lib/summary/summarizerTypes.js.map +1 -1
  372. package/lib/summary/summarizerUtils.d.ts +3 -3
  373. package/lib/summary/summarizerUtils.d.ts.map +1 -1
  374. package/lib/summary/summarizerUtils.js.map +1 -1
  375. package/lib/summary/summaryCollection.d.ts +13 -23
  376. package/lib/summary/summaryCollection.d.ts.map +1 -1
  377. package/lib/summary/summaryCollection.js +1 -2
  378. package/lib/summary/summaryCollection.js.map +1 -1
  379. package/lib/summary/summaryDelayLoadedModule/index.d.ts +2 -2
  380. package/lib/summary/summaryDelayLoadedModule/index.d.ts.map +1 -1
  381. package/lib/summary/summaryDelayLoadedModule/index.js.map +1 -1
  382. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts +1 -1
  383. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -1
  384. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
  385. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts +3 -3
  386. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  387. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  388. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts +5 -5
  389. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  390. package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  391. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts +3 -4
  392. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -1
  393. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
  394. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +3 -3
  395. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -1
  396. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  397. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +1 -1
  398. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -1
  399. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
  400. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +5 -10
  401. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -1
  402. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -1
  403. package/lib/summary/summaryFormat.d.ts +9 -14
  404. package/lib/summary/summaryFormat.d.ts.map +1 -1
  405. package/lib/summary/summaryFormat.js.map +1 -1
  406. package/lib/summary/summaryHelpers.d.ts +1 -2
  407. package/lib/summary/summaryHelpers.d.ts.map +1 -1
  408. package/lib/summary/summaryHelpers.js +1 -2
  409. package/lib/summary/summaryHelpers.js.map +1 -1
  410. package/lib/summary/summaryManager.d.ts +3 -3
  411. package/lib/summary/summaryManager.d.ts.map +1 -1
  412. package/lib/summary/summaryManager.js.map +1 -1
  413. package/lib/tsdoc-metadata.json +1 -1
  414. package/package.json +27 -27
  415. package/src/batchTracker.ts +3 -3
  416. package/src/blobManager/blobManager.ts +165 -174
  417. package/src/blobManager/blobManagerSnapSum.ts +31 -53
  418. package/src/blobManager/index.ts +4 -4
  419. package/src/channelCollection.ts +28 -29
  420. package/src/compressionDefinitions.ts +3 -6
  421. package/src/connectionTelemetry.ts +8 -9
  422. package/src/containerHandleContext.ts +2 -2
  423. package/src/containerRuntime.ts +43 -50
  424. package/src/dataStore.ts +6 -6
  425. package/src/dataStoreContext.ts +33 -33
  426. package/src/dataStoreContexts.ts +3 -3
  427. package/src/dataStoreRegistry.ts +1 -1
  428. package/src/deltaManagerProxies.ts +3 -3
  429. package/src/deltaScheduler.ts +6 -3
  430. package/src/error.ts +1 -1
  431. package/src/gc/garbageCollection.ts +18 -18
  432. package/src/gc/gcConfigs.ts +7 -7
  433. package/src/gc/gcDefinitions.ts +11 -12
  434. package/src/gc/gcHelpers.ts +7 -7
  435. package/src/gc/gcReferenceGraphAlgorithm.ts +1 -1
  436. package/src/gc/gcSummaryDefinitions.ts +1 -1
  437. package/src/gc/gcSummaryStateTracker.ts +5 -5
  438. package/src/gc/gcTelemetry.ts +8 -8
  439. package/src/gc/index.ts +18 -18
  440. package/src/inboundBatchAggregator.ts +4 -4
  441. package/src/index.ts +79 -79
  442. package/src/messageTypes.ts +9 -10
  443. package/src/opLifecycle/batchManager.ts +2 -2
  444. package/src/opLifecycle/definitions.ts +1 -1
  445. package/src/opLifecycle/duplicateBatchDetector.ts +1 -1
  446. package/src/opLifecycle/index.ts +9 -9
  447. package/src/opLifecycle/opCompressor.ts +2 -2
  448. package/src/opLifecycle/opDecompressor.ts +3 -3
  449. package/src/opLifecycle/opGroupingManager.ts +6 -6
  450. package/src/opLifecycle/opSplitter.ts +10 -7
  451. package/src/opLifecycle/outbox.ts +17 -14
  452. package/src/opLifecycle/remoteMessageProcessor.ts +4 -4
  453. package/src/opProperties.ts +1 -1
  454. package/src/packageVersion.ts +1 -1
  455. package/src/pendingStateManager.ts +10 -10
  456. package/src/storageServiceWithAttachBlobs.ts +11 -11
  457. package/src/summary/documentSchema.ts +1 -2
  458. package/src/summary/index.ts +69 -69
  459. package/src/summary/orderedClientElection.ts +12 -4
  460. package/src/summary/summarizerClientElection.ts +5 -5
  461. package/src/summary/summarizerNode/index.ts +3 -3
  462. package/src/summary/summarizerNode/summarizerNode.ts +14 -12
  463. package/src/summary/summarizerNode/summarizerNodeUtils.ts +3 -3
  464. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +3 -3
  465. package/src/summary/summarizerTypes.ts +25 -44
  466. package/src/summary/summarizerUtils.ts +3 -3
  467. package/src/summary/summaryCollection.ts +19 -29
  468. package/src/summary/summaryDelayLoadedModule/index.ts +2 -2
  469. package/src/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.ts +1 -1
  470. package/src/summary/summaryDelayLoadedModule/runningSummarizer.ts +4 -4
  471. package/src/summary/summaryDelayLoadedModule/summarizer.ts +8 -8
  472. package/src/summary/summaryDelayLoadedModule/summarizerHeuristics.ts +4 -4
  473. package/src/summary/summaryDelayLoadedModule/summaryGenerator.ts +3 -3
  474. package/src/summary/summaryDelayLoadedModule/summaryResultBuilder.ts +3 -3
  475. package/src/summary/summaryDelayLoadedModule/summaryResultTypes.ts +5 -10
  476. package/src/summary/summaryFormat.ts +9 -14
  477. package/src/summary/summaryHelpers.ts +1 -2
  478. package/src/summary/summaryManager.ts +4 -4
@@ -8,7 +8,7 @@ import {
8
8
  AttachState,
9
9
  type IContainerStorageService,
10
10
  } from "@fluidframework/container-definitions/internal";
11
- import {
11
+ import type {
12
12
  IContainerRuntime,
13
13
  IContainerRuntimeEvents,
14
14
  } from "@fluidframework/container-runtime-definitions/internal";
@@ -23,13 +23,12 @@ import type {
23
23
  PayloadState,
24
24
  } from "@fluidframework/core-interfaces/internal";
25
25
  import { assert, Deferred } from "@fluidframework/core-utils/internal";
26
- import { ICreateBlobResponse } from "@fluidframework/driver-definitions/internal";
27
- import { canRetryOnError, runWithRetry } from "@fluidframework/driver-utils/internal";
28
- import {
26
+ import type { ICreateBlobResponse } from "@fluidframework/driver-definitions/internal";
27
+ import type {
29
28
  IGarbageCollectionData,
30
29
  ISummaryTreeWithStats,
31
30
  ITelemetryContext,
32
- type ISequencedMessageEnvelope,
31
+ ISequencedMessageEnvelope,
33
32
  } from "@fluidframework/runtime-definitions/internal";
34
33
  import {
35
34
  FluidHandleBase,
@@ -39,11 +38,10 @@ import {
39
38
  } from "@fluidframework/runtime-utils/internal";
40
39
  import {
41
40
  LoggingError,
42
- MonitoringContext,
41
+ type MonitoringContext,
43
42
  PerformanceEvent,
44
43
  UsageError,
45
44
  createChildMonitoringContext,
46
- wrapError,
47
45
  } from "@fluidframework/telemetry-utils/internal";
48
46
  import { v4 as uuid } from "uuid";
49
47
 
@@ -143,7 +141,7 @@ interface PendingBlob {
143
141
  opsent?: boolean;
144
142
  storageId?: string;
145
143
  handleP: Deferred<BlobHandle>;
146
- uploadP?: Promise<ICreateBlobResponse | void>;
144
+ uploadP?: Promise<void>;
147
145
  uploadTime?: number;
148
146
  minTTLInSeconds?: number;
149
147
  attached?: boolean;
@@ -183,13 +181,12 @@ export class BlobManager {
183
181
  private readonly internalEvents = createEmitter<IBlobManagerInternalEvents>();
184
182
 
185
183
  /**
186
- * Map of local IDs to storage IDs. Contains identity entries (storageId storageId) for storage IDs. All requested IDs should
187
- * be a key in this map. Blobs created while the container is detached are stored in IDetachedBlobStorage which
188
- * gives local IDs; the storage IDs are filled in at attach time.
189
- * Note: It contains mappings from all clients, i.e., from remote clients as well. local ID comes from the client
190
- * that uploaded the blob but its mapping to storage ID is needed in all clients in order to retrieve the blob.
184
+ * Map of local IDs to storage IDs. Also includes identity mappings of storage ID to storage ID for all known
185
+ * storage IDs. All requested IDs must be a key in this map. Blobs created while the container is detached are
186
+ * stored in IDetachedBlobStorage which gives pseudo storage IDs; the real storage IDs are filled in at attach
187
+ * time via setRedirectTable().
191
188
  */
192
- private readonly redirectTable: Map<string, string | undefined>;
189
+ private readonly redirectTable: Map<string, string>;
193
190
 
194
191
  /**
195
192
  * Blobs which we have not yet seen a BlobAttach op round-trip and not yet attached to a DDS.
@@ -208,13 +205,13 @@ export class BlobManager {
208
205
  private readonly routeContext: IFluidHandleContext;
209
206
  private readonly storage: Pick<IContainerStorageService, "createBlob" | "readBlob">;
210
207
  // Called when a blob node is requested. blobPath is the path of the blob's node in GC's graph.
211
- // blobPath's format - `/<basePath>/<blobId>`.
208
+ // blobPath's format - `/<basePath>/<localId>`.
212
209
  private readonly blobRequested: (blobPath: string) => void;
213
210
  // Called to check if a blob has been deleted by GC.
214
- // blobPath's format - `/<basePath>/<blobId>`.
211
+ // blobPath's format - `/<basePath>/<localId>`.
215
212
  private readonly isBlobDeleted: (blobPath: string) => boolean;
216
213
  private readonly runtime: IBlobManagerRuntime;
217
- private readonly localBlobIdGenerator: () => string;
214
+ private readonly localIdGenerator: () => string;
218
215
 
219
216
  private readonly createBlobPayloadPending: boolean;
220
217
 
@@ -235,14 +232,14 @@ export class BlobManager {
235
232
  */
236
233
  sendBlobAttachOp: (localId: string, storageId: string) => void;
237
234
  // Called when a blob node is requested. blobPath is the path of the blob's node in GC's graph.
238
- // blobPath's format - `/<basePath>/<blobId>`.
235
+ // blobPath's format - `/<basePath>/<localId>`.
239
236
  readonly blobRequested: (blobPath: string) => void;
240
237
  // Called to check if a blob has been deleted by GC.
241
- // blobPath's format - `/<basePath>/<blobId>`.
238
+ // blobPath's format - `/<basePath>/<localId>`.
242
239
  readonly isBlobDeleted: (blobPath: string) => boolean;
243
240
  readonly runtime: IBlobManagerRuntime;
244
241
  stashedBlobs: IPendingBlobs | undefined;
245
- readonly localBlobIdGenerator?: (() => string) | undefined;
242
+ readonly localIdGenerator?: (() => string) | undefined;
246
243
  readonly createBlobPayloadPending: boolean;
247
244
  }) {
248
245
  const {
@@ -253,7 +250,7 @@ export class BlobManager {
253
250
  blobRequested,
254
251
  isBlobDeleted,
255
252
  runtime,
256
- localBlobIdGenerator,
253
+ localIdGenerator,
257
254
  createBlobPayloadPending,
258
255
  } = props;
259
256
  this.routeContext = routeContext;
@@ -261,7 +258,7 @@ export class BlobManager {
261
258
  this.blobRequested = blobRequested;
262
259
  this.isBlobDeleted = isBlobDeleted;
263
260
  this.runtime = runtime;
264
- this.localBlobIdGenerator = localBlobIdGenerator ?? uuid;
261
+ this.localIdGenerator = localIdGenerator ?? uuid;
265
262
  this.createBlobPayloadPending = createBlobPayloadPending;
266
263
 
267
264
  this.mc = createChildMonitoringContext({
@@ -269,13 +266,9 @@ export class BlobManager {
269
266
  namespace: "BlobManager",
270
267
  });
271
268
 
272
- this.redirectTable = toRedirectTable(
273
- blobManagerLoadInfo,
274
- this.mc.logger,
275
- this.runtime.attachState,
276
- );
269
+ this.redirectTable = toRedirectTable(blobManagerLoadInfo, this.mc.logger);
277
270
 
278
- this.sendBlobAttachOp = (localId: string, blobId: string) => {
271
+ this.sendBlobAttachOp = (localId: string, storageId: string) => {
279
272
  const pendingEntry = this.pendingBlobs.get(localId);
280
273
  assert(
281
274
  pendingEntry !== undefined,
@@ -304,7 +297,7 @@ export class BlobManager {
304
297
  }
305
298
  }
306
299
  pendingEntry.opsent = true;
307
- sendBlobAttachOp(localId, blobId);
300
+ sendBlobAttachOp(localId, storageId);
308
301
  };
309
302
  }
310
303
 
@@ -331,59 +324,49 @@ export class BlobManager {
331
324
  });
332
325
  }
333
326
 
334
- public hasBlob(blobId: string): boolean {
335
- return this.redirectTable.get(blobId) !== undefined;
327
+ public hasBlob(localId: string): boolean {
328
+ return this.redirectTable.get(localId) !== undefined;
336
329
  }
337
330
 
338
331
  /**
339
332
  * Retrieve the blob with the given local blob id.
340
- * @param blobId - The local blob id. Likely coming from a handle.
333
+ * @param localId - The local blob id. Likely coming from a handle.
341
334
  * @param payloadPending - Whether we suspect the payload may be pending and not available yet.
342
335
  * @returns A promise which resolves to the blob contents
343
336
  */
344
- public async getBlob(blobId: string, payloadPending: boolean): Promise<ArrayBufferLike> {
337
+ public async getBlob(localId: string, payloadPending: boolean): Promise<ArrayBufferLike> {
345
338
  // Verify that the blob is not deleted, i.e., it has not been garbage collected. If it is, this will throw
346
339
  // an error, failing the call.
347
- this.verifyBlobNotDeleted(blobId);
340
+ this.verifyBlobNotDeleted(localId);
348
341
  // Let runtime know that the corresponding GC node was requested.
349
342
  // Note that this will throw if the blob is inactive or tombstoned and throwing on incorrect usage
350
343
  // is configured.
351
- this.blobRequested(getGCNodePathFromBlobId(blobId));
344
+ this.blobRequested(getGCNodePathFromLocalId(localId));
352
345
 
353
- const pending = this.pendingBlobs.get(blobId);
346
+ const pending = this.pendingBlobs.get(localId);
354
347
  if (pending) {
355
348
  return pending.blob;
356
349
  }
357
350
 
358
- let storageId: string;
359
- if (this.runtime.attachState === AttachState.Detached) {
360
- assert(this.redirectTable.has(blobId), 0x383 /* requesting unknown blobs */);
361
-
362
- // Blobs created while the container is detached are stored in IDetachedBlobStorage.
363
- // The 'IContainerStorageService.readBlob()' call below will retrieve these via localId.
364
- storageId = blobId;
365
- } else {
366
- const attachedStorageId = this.redirectTable.get(blobId);
367
- if (!payloadPending) {
368
- // Only blob handles explicitly marked with pending payload are permitted to exist without
369
- // yet knowing their storage id. Otherwise they must already be associated with a storage id.
370
- assert(attachedStorageId !== undefined, 0x11f /* "requesting unknown blobs" */);
371
- }
372
- // If we didn't find it in the redirectTable, assume the attach op is coming eventually and wait.
373
- // We do this even if the local client doesn't have the blob payloadPending flag enabled, in case a
374
- // remote client does have it enabled. This wait may be infinite if the uploading client failed
375
- // the upload and doesn't exist anymore.
376
- storageId =
377
- attachedStorageId ??
378
- (await new Promise<string>((resolve) => {
379
- const onProcessBlobAttach = (localId: string, _storageId: string): void => {
380
- if (localId === blobId) {
381
- this.internalEvents.off("processedBlobAttach", onProcessBlobAttach);
382
- resolve(_storageId);
383
- }
384
- };
385
- this.internalEvents.on("processedBlobAttach", onProcessBlobAttach);
386
- }));
351
+ let storageId = this.redirectTable.get(localId);
352
+ if (storageId === undefined) {
353
+ // Only blob handles explicitly marked with pending payload are permitted to exist without
354
+ // yet knowing their storage id. Otherwise they must already be associated with a storage id.
355
+ // Handles for detached blobs are not payload pending.
356
+ assert(payloadPending, 0x11f /* "requesting unknown blobs" */);
357
+ // If we didn't find it in the redirectTable and it's payloadPending, assume the attach op is coming
358
+ // eventually and wait. We do this even if the local client doesn't have the blob payloadPending flag
359
+ // enabled, in case a remote client does have it enabled. This wait may be infinite if the uploading
360
+ // client failed the upload and doesn't exist anymore.
361
+ storageId = await new Promise<string>((resolve) => {
362
+ const onProcessBlobAttach = (_localId: string, _storageId: string): void => {
363
+ if (_localId === localId) {
364
+ this.internalEvents.off("processedBlobAttach", onProcessBlobAttach);
365
+ resolve(_storageId);
366
+ }
367
+ };
368
+ this.internalEvents.on("processedBlobAttach", onProcessBlobAttach);
369
+ });
387
370
  }
388
371
 
389
372
  return PerformanceEvent.timedExecAsync(
@@ -419,7 +402,7 @@ export class BlobManager {
419
402
  }
420
403
  : undefined;
421
404
  return new BlobHandle(
422
- getGCNodePathFromBlobId(localId),
405
+ getGCNodePathFromLocalId(localId),
423
406
  this.routeContext,
424
407
  async () => this.getBlob(localId, false),
425
408
  false, // payloadPending
@@ -430,11 +413,13 @@ export class BlobManager {
430
413
  private async createBlobDetached(
431
414
  blob: ArrayBufferLike,
432
415
  ): Promise<IFluidHandleInternalPayloadPending<ArrayBufferLike>> {
416
+ const localId = this.localIdGenerator();
433
417
  // Blobs created while the container is detached are stored in IDetachedBlobStorage.
434
- // The 'IContainerStorageService.createBlob()' call below will respond with a localId.
435
- const response = await this.storage.createBlob(blob);
436
- this.setRedirection(response.id, undefined);
437
- return this.getBlobHandle(response.id);
418
+ // The 'IContainerStorageService.createBlob()' call below will respond with a pseudo storage ID.
419
+ // That pseudo storage ID will be replaced with the real storage ID at attach time.
420
+ const { id: detachedStorageId } = await this.storage.createBlob(blob);
421
+ this.setRedirection(localId, detachedStorageId);
422
+ return this.getBlobHandle(localId);
438
423
  }
439
424
 
440
425
  public async createBlob(
@@ -469,7 +454,7 @@ export class BlobManager {
469
454
 
470
455
  // Create a local ID for the blob. After uploading it to storage and before returning it, a local ID to
471
456
  // storage ID mapping is created.
472
- const localId = this.localBlobIdGenerator();
457
+ const localId = this.localIdGenerator();
473
458
  const pendingEntry: PendingBlob = {
474
459
  blob,
475
460
  handleP: new Deferred(),
@@ -496,10 +481,10 @@ export class BlobManager {
496
481
  private createBlobWithPayloadPending(
497
482
  blob: ArrayBufferLike,
498
483
  ): IFluidHandleInternalPayloadPending<ArrayBufferLike> {
499
- const localId = this.localBlobIdGenerator();
484
+ const localId = this.localIdGenerator();
500
485
 
501
486
  const blobHandle = new BlobHandle(
502
- getGCNodePathFromBlobId(localId),
487
+ getGCNodePathFromLocalId(localId),
503
488
  this.routeContext,
504
489
  async () => blob,
505
490
  true, // payloadPending
@@ -535,59 +520,55 @@ export class BlobManager {
535
520
  return blobHandle;
536
521
  }
537
522
 
538
- private async uploadBlob(
539
- localId: string,
540
- blob: ArrayBufferLike,
541
- ): Promise<ICreateBlobResponse | void> {
542
- return runWithRetry(
543
- async () => {
544
- try {
545
- return await this.storage.createBlob(blob);
546
- } catch (error) {
547
- const entry = this.pendingBlobs.get(localId);
548
- assert(
549
- !!entry,
550
- 0x387 /* Must have pending blob entry for blob which failed to upload */,
551
- );
552
- if (entry.opsent && !canRetryOnError(error)) {
553
- throw wrapError(
554
- error,
555
- () => new LoggingError(`uploadBlob error`, { canRetry: true }),
556
- );
557
- }
558
- throw error;
559
- }
560
- },
561
- "createBlob",
562
- this.mc.logger,
563
- {
564
- cancel: this.pendingBlobs.get(localId)?.abortSignal,
565
- },
566
- ).then(
567
- (response) => this.onUploadResolve(localId, response),
568
- (error) => {
569
- this.mc.logger.sendTelemetryEvent({
570
- eventName: "UploadBlobReject",
571
- // TODO: better typing
572
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
573
- error,
574
- localId,
575
- });
576
- // it will only reject if we haven't sent an op
577
- // and is a non-retriable error. It will only reject
578
- // the promise but not throw any error outside.
579
- this.pendingBlobs.get(localId)?.handleP.reject(error);
523
+ /**
524
+ * Upload a blob to the storage service.
525
+ * @returns A promise that resolves when the upload is complete and a blob attach op has been sent (but not ack'd).
526
+ *
527
+ * @privateRemarks This method must not reject, as there is no error handling for it in current tracking.
528
+ */
529
+ private async uploadBlob(localId: string, blob: ArrayBufferLike): Promise<void> {
530
+ let response: ICreateBlobResponseWithTTL;
531
+ try {
532
+ response = await this.storage.createBlob(blob);
533
+ } catch (error) {
534
+ const entry = this.pendingBlobs.get(localId);
535
+ this.mc.logger.sendTelemetryEvent({
536
+ eventName: "UploadBlobReject",
537
+ // TODO: better typing
538
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
539
+ error: error as any,
540
+ message: entry === undefined ? "Missing pendingBlob" : undefined,
541
+ localId,
542
+ });
543
+ // We probably should assert the pendingBlobs entry here, but we don't currently have any error handling
544
+ // for the uploadP - a promise rejection would be unhandled anyway. For now we can detect this with the
545
+ // message on the UploadBlobReject telemetry.
546
+ if (entry !== undefined) {
547
+ entry.handleP.reject(error);
580
548
  this.deletePendingBlob(localId);
581
- this.internalEvents.emit("uploadFailed", localId, error);
582
- },
583
- );
549
+ }
550
+ this.internalEvents.emit("uploadFailed", localId, error);
551
+ return;
552
+ }
553
+
554
+ try {
555
+ this.onUploadResolve(localId, response);
556
+ } catch (error) {
557
+ this.mc.logger.sendTelemetryEvent({
558
+ eventName: "OnUploadResolveError",
559
+ // TODO: better typing
560
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
561
+ error: error as any,
562
+ localId,
563
+ });
564
+ }
584
565
  }
585
566
 
586
567
  /**
587
568
  * Set up a mapping in the redirect table from fromId to toId. Also, notify the runtime that a reference is added
588
569
  * which is required for GC.
589
570
  */
590
- private setRedirection(fromId: string, toId: string | undefined): void {
571
+ private setRedirection(fromId: string, toId: string): void {
591
572
  this.redirectTable.set(fromId, toId);
592
573
  }
593
574
 
@@ -636,7 +617,7 @@ export class BlobManager {
636
617
  if (!entry.opsent) {
637
618
  this.sendBlobAttachOp(localId, response.id);
638
619
  }
639
- const storageIds = getStorageIds(this.redirectTable, this.runtime.attachState);
620
+ const storageIds = getStorageIds(this.redirectTable);
640
621
  if (storageIds.has(response.id)) {
641
622
  // The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
642
623
  // an existing blob, we don't have to wait for the op to be ack'd since this step has already
@@ -669,7 +650,7 @@ export class BlobManager {
669
650
  */
670
651
  public reSubmit(metadata: Record<string, unknown> | undefined): void {
671
652
  assert(isBlobMetadata(metadata), 0xc01 /* Expected blob metadata for a BlobAttach op */);
672
- const { localId, blobId } = metadata;
653
+ const { localId, blobId: storageId } = metadata;
673
654
  // Any blob that we're actively trying to advance to attached state must have a
674
655
  // pendingBlobs entry. Decline to resubmit for anything else.
675
656
  // For example, we might be asked to resubmit stashed ops for blobs that never had
@@ -677,7 +658,7 @@ export class BlobManager {
677
658
  // try to attach them since they won't be accessible to the customer and would just
678
659
  // be considered garbage immediately.
679
660
  if (this.pendingBlobs.has(localId)) {
680
- this.sendBlobAttachOp(localId, blobId);
661
+ this.sendBlobAttachOp(localId, storageId);
681
662
  }
682
663
  }
683
664
 
@@ -686,19 +667,19 @@ export class BlobManager {
686
667
  isBlobMetadata(message.metadata),
687
668
  0xc02 /* Expected blob metadata for a BlobAttach op */,
688
669
  );
689
- const { localId, blobId } = message.metadata;
670
+ const { localId, blobId: storageId } = message.metadata;
690
671
  const pendingEntry = this.pendingBlobs.get(localId);
691
672
  if (pendingEntry?.abortSignal?.aborted) {
692
673
  this.deletePendingBlob(localId);
693
674
  return;
694
675
  }
695
676
 
696
- this.setRedirection(localId, blobId);
677
+ this.setRedirection(localId, storageId);
697
678
  // set identity (id -> id) entry
698
- this.setRedirection(blobId, blobId);
679
+ this.setRedirection(storageId, storageId);
699
680
 
700
681
  if (local) {
701
- const waitingBlobs = this.opsInFlight.get(blobId);
682
+ const waitingBlobs = this.opsInFlight.get(storageId);
702
683
  if (waitingBlobs !== undefined) {
703
684
  // For each op corresponding to this storage ID that we are waiting for, resolve the pending blob.
704
685
  // This is safe because the server will keep the blob alive and the op containing the local ID to
@@ -709,14 +690,14 @@ export class BlobManager {
709
690
  entry !== undefined,
710
691
  0x38f /* local online BlobAttach op with no pending blob entry */,
711
692
  );
712
- this.setRedirection(pendingLocalId, blobId);
693
+ this.setRedirection(pendingLocalId, storageId);
713
694
  entry.acked = true;
714
695
  const blobHandle = this.getBlobHandle(pendingLocalId);
715
696
  blobHandle.notifyShared();
716
697
  entry.handleP.resolve(blobHandle);
717
698
  this.deletePendingBlobMaybe(pendingLocalId);
718
699
  }
719
- this.opsInFlight.delete(blobId);
700
+ this.opsInFlight.delete(storageId);
720
701
  }
721
702
  const localEntry = this.pendingBlobs.get(localId);
722
703
  if (localEntry) {
@@ -727,11 +708,11 @@ export class BlobManager {
727
708
  this.deletePendingBlobMaybe(localId);
728
709
  }
729
710
  }
730
- this.internalEvents.emit("processedBlobAttach", localId, blobId);
711
+ this.internalEvents.emit("processedBlobAttach", localId, storageId);
731
712
  }
732
713
 
733
714
  public summarize(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats {
734
- return summarizeBlobManagerState(this.redirectTable, this.runtime.attachState);
715
+ return summarizeBlobManagerState(this.redirectTable);
735
716
  }
736
717
 
737
718
  /**
@@ -743,13 +724,12 @@ export class BlobManager {
743
724
  public getGCData(fullGC: boolean = false): IGarbageCollectionData {
744
725
  const gcData: IGarbageCollectionData = { gcNodes: {} };
745
726
  for (const [localId, storageId] of this.redirectTable) {
746
- assert(!!storageId, 0x390 /* Must be attached to get GC data */);
747
- // Only return local ids as GC nodes because a blob can only be referenced via its local id. The storage
748
- // id entries have the same key and value, ignore them.
749
- // The outbound routes are empty because a blob node cannot reference other nodes. It can only be referenced
750
- // by adding its handle to a referenced DDS.
727
+ // Don't report the identity mappings to GC - these exist to service old handles that referenced the storage
728
+ // IDs directly. We'll implicitly clean them up if all of their localId references get GC'd first.
751
729
  if (localId !== storageId) {
752
- gcData.gcNodes[getGCNodePathFromBlobId(localId)] = [];
730
+ // The outbound routes are empty because a blob node cannot reference other nodes. It can only be referenced
731
+ // by adding its handle to a referenced DDS.
732
+ gcData.gcNodes[getGCNodePathFromLocalId(localId)] = [];
753
733
  }
754
734
  }
755
735
  return gcData;
@@ -770,58 +750,55 @@ export class BlobManager {
770
750
  * Delete blobs with the given routes from the redirect table.
771
751
  *
772
752
  * @remarks
773
- * The routes are GC nodes paths of format -`/<blobManagerBasePath>/<blobId>`. The blob ids are all local ids.
753
+ * The routes are GC nodes paths of format -`/<blobManagerBasePath>/<localId>`.
774
754
  * Deleting the blobs involves 2 steps:
775
755
  *
776
756
  * 1. The redirect table entry for the local ids are deleted.
777
757
  *
778
- * 2. If the storage ids corresponding to the deleted local ids are not in-use anymore, the redirect table entries
779
- * for the storage ids are deleted as well.
758
+ * 2. If the storage ids corresponding to the deleted local ids are not referenced by any further local ids, the
759
+ * identity mappings in the redirect table are deleted as well.
780
760
  *
781
761
  * Note that this does not delete the blobs from storage service immediately. Deleting the blobs from redirect table
782
- * will remove them the next summary. The service would them delete them some time in the future.
762
+ * will ensure we don't create an attachment blob for them at the next summary. The service would then delete them
763
+ * some time in the future.
783
764
  */
784
765
  private deleteBlobsFromRedirectTable(blobRoutes: readonly string[]): void {
785
- if (blobRoutes.length === 0) {
786
- return;
787
- }
788
-
789
- // This tracks the storage ids of local ids that are deleted. After the local ids have been deleted, if any of
790
- // these storage ids are unused, they will be deleted as well.
766
+ // maybeUnusedStorageIds is used to compute the set of storage IDs that *used to have a local ID*, but that
767
+ // local ID is being deleted.
791
768
  const maybeUnusedStorageIds: Set<string> = new Set();
792
769
  for (const route of blobRoutes) {
793
- const blobId = getBlobIdFromGCNodePath(route);
770
+ const localId = getLocalIdFromGCNodePath(route);
794
771
  // If the blob hasn't already been deleted, log an error because this should never happen.
795
772
  // If the blob has already been deleted, log a telemetry event. This can happen because multiple GC
796
773
  // sweep ops can contain the same data store. It would be interesting to track how often this happens.
797
774
  const alreadyDeleted = this.isBlobDeleted(route);
798
- if (!this.redirectTable.has(blobId)) {
775
+ const storageId = this.redirectTable.get(localId);
776
+ if (storageId === undefined) {
799
777
  this.mc.logger.sendTelemetryEvent({
800
778
  eventName: "DeletedAttachmentBlobNotFound",
801
779
  category: alreadyDeleted ? "generic" : "error",
802
- blobId,
780
+ blobId: localId,
803
781
  details: { alreadyDeleted },
804
782
  });
805
783
  continue;
806
784
  }
807
- const storageId = this.redirectTable.get(blobId);
808
- assert(!!storageId, 0x5bb /* Must be attached to run GC */);
809
785
  maybeUnusedStorageIds.add(storageId);
810
- this.redirectTable.delete(blobId);
786
+ this.redirectTable.delete(localId);
811
787
  }
812
788
 
813
- // Find out storage ids that are in-use and remove them from maybeUnusedStorageIds. A storage id is in-use if
814
- // the redirect table has a local id -> storage id entry for it.
815
- for (const [localId, storageId] of this.redirectTable.entries()) {
816
- assert(!!storageId, 0x5bc /* Must be attached to run GC */);
817
- // For every storage id, the redirect table has a id -> id entry. These do not make the storage id in-use.
818
- if (maybeUnusedStorageIds.has(storageId) && localId !== storageId) {
789
+ // Remove any storage IDs that still have local IDs referring to them (excluding the identity mapping).
790
+ for (const [localId, storageId] of this.redirectTable) {
791
+ if (localId !== storageId) {
819
792
  maybeUnusedStorageIds.delete(storageId);
820
793
  }
821
794
  }
822
795
 
823
- // For unused storage ids, delete their id -> id entries from the redirect table.
824
- // This way they'll be absent from the next summary, and the service is free to delete them from storage.
796
+ // Now delete any identity mappings (storage ID -> storage ID) from the redirect table that used to be
797
+ // referenced by a distinct local ID. This way they'll be absent from the next summary, and the service
798
+ // is free to delete them from storage.
799
+ // WARNING: This can potentially delete identity mappings that are still referenced, if storage deduping
800
+ // has let us add a local ID -> storage ID mapping that is later deleted. AB#47337 tracks this issue
801
+ // and possible solutions.
825
802
  for (const storageId of maybeUnusedStorageIds) {
826
803
  this.redirectTable.delete(storageId);
827
804
  }
@@ -831,12 +808,12 @@ export class BlobManager {
831
808
  * Verifies that the blob with given id is not deleted, i.e., it has not been garbage collected. If the blob is GC'd,
832
809
  * log an error and throw if necessary.
833
810
  */
834
- private verifyBlobNotDeleted(blobId: string): void {
835
- if (!this.isBlobDeleted(getGCNodePathFromBlobId(blobId))) {
811
+ private verifyBlobNotDeleted(localId: string): void {
812
+ if (!this.isBlobDeleted(getGCNodePathFromLocalId(localId))) {
836
813
  return;
837
814
  }
838
815
 
839
- const request = { url: blobId };
816
+ const request = { url: localId };
840
817
  const error = responseToException(
841
818
  createResponseError(404, `Blob was deleted`, request),
842
819
  request,
@@ -852,20 +829,34 @@ export class BlobManager {
852
829
  throw error;
853
830
  }
854
831
 
855
- public setRedirectTable(table: Map<string, string>): void {
832
+ /**
833
+ * Called in detached state just prior to attaching, this will update the redirect table by
834
+ * converting the pseudo storage IDs into real storage IDs using the provided detachedStorageTable.
835
+ * The provided table must have exactly the same set of pseudo storage IDs as are found in the redirect table.
836
+ * @param detachedStorageTable - A map of pseudo storage IDs to real storage IDs.
837
+ */
838
+ public patchRedirectTable(detachedStorageTable: Map<string, string>): void {
856
839
  assert(
857
840
  this.runtime.attachState === AttachState.Detached,
858
841
  0x252 /* "redirect table can only be set in detached container" */,
859
842
  );
843
+ // The values of the redirect table are the pseudo storage IDs, which are the keys of the
844
+ // detachedStorageTable. We expect to have a many:1 mapping from local IDs to pseudo
845
+ // storage IDs (many in the case that the storage dedupes the blob).
860
846
  assert(
861
- this.redirectTable.size === table.size,
847
+ new Set(this.redirectTable.values()).size === detachedStorageTable.size,
862
848
  0x391 /* Redirect table size must match BlobManager's local ID count */,
863
849
  );
864
- for (const [localId, storageId] of table) {
865
- assert(this.redirectTable.has(localId), 0x254 /* "unrecognized id in redirect table" */);
866
- this.setRedirection(localId, storageId);
850
+ // Taking a snapshot of the redirect table entries before iterating, because
851
+ // we will be adding identity mappings to the the redirect table as we iterate
852
+ // and we don't want to include those in the iteration.
853
+ const redirectTableEntries = [...this.redirectTable.entries()];
854
+ for (const [localId, detachedStorageId] of redirectTableEntries) {
855
+ const newStorageId = detachedStorageTable.get(detachedStorageId);
856
+ assert(newStorageId !== undefined, "Couldn't find a matching storage ID");
857
+ this.setRedirection(localId, newStorageId);
867
858
  // set identity (id -> id) entry
868
- this.setRedirection(storageId, storageId);
859
+ this.setRedirection(newStorageId, newStorageId);
869
860
  }
870
861
  }
871
862
 
@@ -902,17 +893,17 @@ export class BlobManager {
902
893
  }
903
894
 
904
895
  /**
905
- * For a blobId, returns its path in GC's graph. The node path is of the format `/<blobManagerBasePath>/<blobId>`.
896
+ * For a localId, returns its path in GC's graph. The node path is of the format `/<blobManagerBasePath>/<localId>`.
906
897
  * This path must match the path of the blob handle returned by the createBlob API because blobs are marked
907
898
  * referenced by storing these handles in a referenced DDS.
908
899
  */
909
- const getGCNodePathFromBlobId = (blobId: string): string =>
910
- `/${blobManagerBasePath}/${blobId}`;
900
+ const getGCNodePathFromLocalId = (localId: string): string =>
901
+ `/${blobManagerBasePath}/${localId}`;
911
902
 
912
903
  /**
913
- * For a given GC node path, return the blobId. The node path is of the format `/<basePath>/<blobId>`.
904
+ * For a given GC node path, return the localId. The node path is of the format `/<basePath>/<localId>`.
914
905
  */
915
- const getBlobIdFromGCNodePath = (nodePath: string): string => {
906
+ const getLocalIdFromGCNodePath = (nodePath: string): string => {
916
907
  const pathParts = nodePath.split("/");
917
908
  assert(areBlobPathParts(pathParts), 0x5bd /* Invalid blob node path */);
918
909
  return pathParts[2];