@fluidframework/container-runtime 2.31.0 → 2.32.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 (299) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/container-runtime.test-files.tar +0 -0
  3. package/dist/channelCollection.d.ts +0 -14
  4. package/dist/channelCollection.d.ts.map +1 -1
  5. package/dist/channelCollection.js +10 -25
  6. package/dist/channelCollection.js.map +1 -1
  7. package/dist/containerRuntime.d.ts +16 -9
  8. package/dist/containerRuntime.d.ts.map +1 -1
  9. package/dist/containerRuntime.js +137 -103
  10. package/dist/containerRuntime.js.map +1 -1
  11. package/dist/dataStoreContext.d.ts +1 -5
  12. package/dist/dataStoreContext.d.ts.map +1 -1
  13. package/dist/dataStoreContext.js +0 -8
  14. package/dist/dataStoreContext.js.map +1 -1
  15. package/dist/index.d.ts +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -2
  18. package/dist/index.js.map +1 -1
  19. package/dist/messageTypes.d.ts +3 -7
  20. package/dist/messageTypes.d.ts.map +1 -1
  21. package/dist/messageTypes.js.map +1 -1
  22. package/dist/opLifecycle/batchManager.d.ts +4 -4
  23. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  24. package/dist/opLifecycle/batchManager.js +4 -4
  25. package/dist/opLifecycle/batchManager.js.map +1 -1
  26. package/dist/opLifecycle/definitions.d.ts +40 -6
  27. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  28. package/dist/opLifecycle/definitions.js.map +1 -1
  29. package/dist/opLifecycle/index.d.ts +4 -3
  30. package/dist/opLifecycle/index.d.ts.map +1 -1
  31. package/dist/opLifecycle/index.js +4 -3
  32. package/dist/opLifecycle/index.js.map +1 -1
  33. package/dist/opLifecycle/opCompressor.d.ts +10 -11
  34. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  35. package/dist/opLifecycle/opCompressor.js +19 -18
  36. package/dist/opLifecycle/opCompressor.js.map +1 -1
  37. package/dist/opLifecycle/opGroupingManager.d.ts +9 -5
  38. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  39. package/dist/opLifecycle/opGroupingManager.js +18 -22
  40. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  41. package/dist/opLifecycle/opSerialization.d.ts +20 -0
  42. package/dist/opLifecycle/opSerialization.d.ts.map +1 -0
  43. package/dist/opLifecycle/opSerialization.js +40 -0
  44. package/dist/opLifecycle/opSerialization.js.map +1 -0
  45. package/dist/opLifecycle/opSplitter.d.ts +12 -13
  46. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  47. package/dist/opLifecycle/opSplitter.js +13 -13
  48. package/dist/opLifecycle/opSplitter.js.map +1 -1
  49. package/dist/opLifecycle/outbox.d.ts +16 -18
  50. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  51. package/dist/opLifecycle/outbox.js +57 -43
  52. package/dist/opLifecycle/outbox.js.map +1 -1
  53. package/dist/opLifecycle/remoteMessageProcessor.d.ts +0 -7
  54. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  55. package/dist/opLifecycle/remoteMessageProcessor.js +1 -15
  56. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  57. package/dist/packageVersion.d.ts +1 -1
  58. package/dist/packageVersion.js +1 -1
  59. package/dist/packageVersion.js.map +1 -1
  60. package/dist/pendingStateManager.d.ts +2 -2
  61. package/dist/pendingStateManager.d.ts.map +1 -1
  62. package/dist/pendingStateManager.js +1 -1
  63. package/dist/pendingStateManager.js.map +1 -1
  64. package/dist/runtimeLayerCompatState.d.ts.map +1 -1
  65. package/dist/runtimeLayerCompatState.js +6 -5
  66. package/dist/runtimeLayerCompatState.js.map +1 -1
  67. package/dist/summary/index.d.ts +5 -8
  68. package/dist/summary/index.d.ts.map +1 -1
  69. package/dist/summary/index.js +20 -21
  70. package/dist/summary/index.js.map +1 -1
  71. package/dist/summary/orderedClientElection.js +9 -9
  72. package/dist/summary/orderedClientElection.js.map +1 -1
  73. package/dist/summary/summarizerClientElection.d.ts +0 -1
  74. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  75. package/dist/summary/summarizerClientElection.js +3 -3
  76. package/dist/summary/summarizerClientElection.js.map +1 -1
  77. package/dist/summary/summarizerTypes.d.ts +3 -75
  78. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  79. package/dist/summary/summarizerTypes.js +2 -0
  80. package/dist/summary/summarizerTypes.js.map +1 -1
  81. package/{lib/summary/summaryGenerator.d.ts → dist/summary/summarizerUtils.d.ts} +12 -43
  82. package/dist/summary/summarizerUtils.d.ts.map +1 -0
  83. package/dist/summary/summarizerUtils.js +71 -0
  84. package/dist/summary/summarizerUtils.js.map +1 -0
  85. package/dist/summary/summaryDelayLoadedModule/index.d.ts +10 -0
  86. package/dist/summary/summaryDelayLoadedModule/index.d.ts.map +1 -0
  87. package/dist/summary/summaryDelayLoadedModule/index.js +20 -0
  88. package/dist/summary/summaryDelayLoadedModule/index.js.map +1 -0
  89. package/dist/summary/{runWhileConnectedCoordinator.d.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts} +1 -1
  90. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -0
  91. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -0
  92. package/dist/summary/{runningSummarizer.d.ts → summaryDelayLoadedModule/runningSummarizer.d.ts} +4 -13
  93. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -0
  94. package/dist/summary/{runningSummarizer.js → summaryDelayLoadedModule/runningSummarizer.js} +17 -24
  95. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -0
  96. package/dist/summary/{summarizer.d.ts → summaryDelayLoadedModule/summarizer.d.ts} +13 -2
  97. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -0
  98. package/dist/summary/{summarizer.js → summaryDelayLoadedModule/summarizer.js} +13 -3
  99. package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -0
  100. package/{lib/summary → dist/summary/summaryDelayLoadedModule}/summarizerHeuristics.d.ts +3 -3
  101. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -0
  102. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -0
  103. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +36 -0
  104. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -0
  105. package/dist/summary/{summaryGenerator.js → summaryDelayLoadedModule/summaryGenerator.js} +14 -99
  106. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -0
  107. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +21 -0
  108. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -0
  109. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js +44 -0
  110. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -0
  111. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +80 -0
  112. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -0
  113. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js +7 -0
  114. package/dist/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -0
  115. package/dist/summary/summaryHelpers.d.ts +1 -1
  116. package/dist/summary/summaryHelpers.d.ts.map +1 -1
  117. package/dist/summary/summaryHelpers.js +2 -2
  118. package/dist/summary/summaryHelpers.js.map +1 -1
  119. package/dist/summary/summaryManager.d.ts +4 -3
  120. package/dist/summary/summaryManager.d.ts.map +1 -1
  121. package/dist/summary/summaryManager.js +2 -2
  122. package/dist/summary/summaryManager.js.map +1 -1
  123. package/lib/channelCollection.d.ts +0 -14
  124. package/lib/channelCollection.d.ts.map +1 -1
  125. package/lib/channelCollection.js +6 -21
  126. package/lib/channelCollection.js.map +1 -1
  127. package/lib/containerRuntime.d.ts +16 -9
  128. package/lib/containerRuntime.d.ts.map +1 -1
  129. package/lib/containerRuntime.js +140 -106
  130. package/lib/containerRuntime.js.map +1 -1
  131. package/lib/dataStoreContext.d.ts +1 -5
  132. package/lib/dataStoreContext.d.ts.map +1 -1
  133. package/lib/dataStoreContext.js +0 -8
  134. package/lib/dataStoreContext.js.map +1 -1
  135. package/lib/index.d.ts +1 -1
  136. package/lib/index.d.ts.map +1 -1
  137. package/lib/index.js +1 -1
  138. package/lib/index.js.map +1 -1
  139. package/lib/messageTypes.d.ts +3 -7
  140. package/lib/messageTypes.d.ts.map +1 -1
  141. package/lib/messageTypes.js.map +1 -1
  142. package/lib/opLifecycle/batchManager.d.ts +4 -4
  143. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  144. package/lib/opLifecycle/batchManager.js +4 -4
  145. package/lib/opLifecycle/batchManager.js.map +1 -1
  146. package/lib/opLifecycle/definitions.d.ts +40 -6
  147. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  148. package/lib/opLifecycle/definitions.js.map +1 -1
  149. package/lib/opLifecycle/index.d.ts +4 -3
  150. package/lib/opLifecycle/index.d.ts.map +1 -1
  151. package/lib/opLifecycle/index.js +3 -2
  152. package/lib/opLifecycle/index.js.map +1 -1
  153. package/lib/opLifecycle/opCompressor.d.ts +10 -11
  154. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  155. package/lib/opLifecycle/opCompressor.js +20 -19
  156. package/lib/opLifecycle/opCompressor.js.map +1 -1
  157. package/lib/opLifecycle/opGroupingManager.d.ts +9 -5
  158. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  159. package/lib/opLifecycle/opGroupingManager.js +18 -22
  160. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  161. package/lib/opLifecycle/opSerialization.d.ts +20 -0
  162. package/lib/opLifecycle/opSerialization.d.ts.map +1 -0
  163. package/lib/opLifecycle/opSerialization.js +35 -0
  164. package/lib/opLifecycle/opSerialization.js.map +1 -0
  165. package/lib/opLifecycle/opSplitter.d.ts +12 -13
  166. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  167. package/lib/opLifecycle/opSplitter.js +13 -13
  168. package/lib/opLifecycle/opSplitter.js.map +1 -1
  169. package/lib/opLifecycle/outbox.d.ts +16 -18
  170. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  171. package/lib/opLifecycle/outbox.js +56 -41
  172. package/lib/opLifecycle/outbox.js.map +1 -1
  173. package/lib/opLifecycle/remoteMessageProcessor.d.ts +0 -7
  174. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  175. package/lib/opLifecycle/remoteMessageProcessor.js +0 -13
  176. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  177. package/lib/packageVersion.d.ts +1 -1
  178. package/lib/packageVersion.js +1 -1
  179. package/lib/packageVersion.js.map +1 -1
  180. package/lib/pendingStateManager.d.ts +2 -2
  181. package/lib/pendingStateManager.d.ts.map +1 -1
  182. package/lib/pendingStateManager.js +1 -1
  183. package/lib/pendingStateManager.js.map +1 -1
  184. package/lib/runtimeLayerCompatState.d.ts.map +1 -1
  185. package/lib/runtimeLayerCompatState.js +3 -2
  186. package/lib/runtimeLayerCompatState.js.map +1 -1
  187. package/lib/summary/index.d.ts +5 -8
  188. package/lib/summary/index.d.ts.map +1 -1
  189. package/lib/summary/index.js +5 -7
  190. package/lib/summary/index.js.map +1 -1
  191. package/lib/summary/orderedClientElection.js +1 -1
  192. package/lib/summary/orderedClientElection.js.map +1 -1
  193. package/lib/summary/summarizerClientElection.d.ts +0 -1
  194. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  195. package/lib/summary/summarizerClientElection.js +1 -1
  196. package/lib/summary/summarizerClientElection.js.map +1 -1
  197. package/lib/summary/summarizerTypes.d.ts +3 -75
  198. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  199. package/lib/summary/summarizerTypes.js +1 -1
  200. package/lib/summary/summarizerTypes.js.map +1 -1
  201. package/{dist/summary/summaryGenerator.d.ts → lib/summary/summarizerUtils.d.ts} +12 -43
  202. package/lib/summary/summarizerUtils.d.ts.map +1 -0
  203. package/lib/summary/summarizerUtils.js +64 -0
  204. package/lib/summary/summarizerUtils.js.map +1 -0
  205. package/lib/summary/summaryDelayLoadedModule/index.d.ts +10 -0
  206. package/lib/summary/summaryDelayLoadedModule/index.d.ts.map +1 -0
  207. package/lib/summary/summaryDelayLoadedModule/index.js +9 -0
  208. package/lib/summary/summaryDelayLoadedModule/index.js.map +1 -0
  209. package/lib/summary/{runWhileConnectedCoordinator.d.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts} +1 -1
  210. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.d.ts.map +1 -0
  211. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -0
  212. package/lib/summary/{runningSummarizer.d.ts → summaryDelayLoadedModule/runningSummarizer.d.ts} +4 -13
  213. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -0
  214. package/lib/summary/{runningSummarizer.js → summaryDelayLoadedModule/runningSummarizer.js} +5 -12
  215. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -0
  216. package/lib/summary/{summarizer.d.ts → summaryDelayLoadedModule/summarizer.d.ts} +13 -2
  217. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -0
  218. package/lib/summary/{summarizer.js → summaryDelayLoadedModule/summarizer.js} +11 -1
  219. package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -0
  220. package/{dist/summary → lib/summary/summaryDelayLoadedModule}/summarizerHeuristics.d.ts +3 -3
  221. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.d.ts.map +1 -0
  222. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -0
  223. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts +36 -0
  224. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.d.ts.map +1 -0
  225. package/lib/summary/{summaryGenerator.js → summaryDelayLoadedModule/summaryGenerator.js} +4 -85
  226. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -0
  227. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts +21 -0
  228. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.d.ts.map +1 -0
  229. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js +40 -0
  230. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -0
  231. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts +80 -0
  232. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.d.ts.map +1 -0
  233. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js +6 -0
  234. package/lib/summary/summaryDelayLoadedModule/summaryResultTypes.js.map +1 -0
  235. package/lib/summary/summaryHelpers.d.ts +1 -1
  236. package/lib/summary/summaryHelpers.d.ts.map +1 -1
  237. package/lib/summary/summaryHelpers.js +1 -1
  238. package/lib/summary/summaryHelpers.js.map +1 -1
  239. package/lib/summary/summaryManager.d.ts +4 -3
  240. package/lib/summary/summaryManager.d.ts.map +1 -1
  241. package/lib/summary/summaryManager.js +2 -2
  242. package/lib/summary/summaryManager.js.map +1 -1
  243. package/package.json +21 -20
  244. package/src/channelCollection.ts +5 -20
  245. package/src/containerRuntime.ts +220 -178
  246. package/src/dataStoreContext.ts +0 -11
  247. package/src/index.ts +0 -1
  248. package/src/messageTypes.ts +5 -19
  249. package/src/opLifecycle/batchManager.ts +19 -12
  250. package/src/opLifecycle/definitions.ts +45 -6
  251. package/src/opLifecycle/index.ts +14 -3
  252. package/src/opLifecycle/opCompressor.ts +25 -24
  253. package/src/opLifecycle/opGroupingManager.ts +27 -26
  254. package/src/opLifecycle/opSerialization.ts +46 -0
  255. package/src/opLifecycle/opSplitter.ts +20 -16
  256. package/src/opLifecycle/outbox.ts +101 -66
  257. package/src/opLifecycle/remoteMessageProcessor.ts +0 -17
  258. package/src/packageVersion.ts +1 -1
  259. package/src/pendingStateManager.ts +3 -3
  260. package/src/runtimeLayerCompatState.ts +3 -2
  261. package/src/summary/index.ts +35 -31
  262. package/src/summary/orderedClientElection.ts +1 -1
  263. package/src/summary/summarizerClientElection.ts +1 -2
  264. package/src/summary/summarizerTypes.ts +7 -91
  265. package/src/summary/summarizerUtils.ts +132 -0
  266. package/src/summary/summaryDelayLoadedModule/index.ts +28 -0
  267. package/src/summary/{runWhileConnectedCoordinator.ts → summaryDelayLoadedModule/runWhileConnectedCoordinator.ts} +1 -1
  268. package/src/summary/{runningSummarizer.ts → summaryDelayLoadedModule/runningSummarizer.ts} +13 -28
  269. package/src/summary/{summarizer.ts → summaryDelayLoadedModule/summarizer.ts} +19 -8
  270. package/src/summary/{summarizerHeuristics.ts → summaryDelayLoadedModule/summarizerHeuristics.ts} +3 -3
  271. package/src/summary/{summaryGenerator.ts → summaryDelayLoadedModule/summaryGenerator.ts} +13 -179
  272. package/src/summary/summaryDelayLoadedModule/summaryResultBuilder.ts +70 -0
  273. package/src/summary/summaryDelayLoadedModule/summaryResultTypes.ts +100 -0
  274. package/src/summary/summaryHelpers.ts +6 -6
  275. package/src/summary/summaryManager.ts +8 -6
  276. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
  277. package/dist/summary/runWhileConnectedCoordinator.js.map +0 -1
  278. package/dist/summary/runningSummarizer.d.ts.map +0 -1
  279. package/dist/summary/runningSummarizer.js.map +0 -1
  280. package/dist/summary/summarizer.d.ts.map +0 -1
  281. package/dist/summary/summarizer.js.map +0 -1
  282. package/dist/summary/summarizerHeuristics.d.ts.map +0 -1
  283. package/dist/summary/summarizerHeuristics.js.map +0 -1
  284. package/dist/summary/summaryGenerator.d.ts.map +0 -1
  285. package/dist/summary/summaryGenerator.js.map +0 -1
  286. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +0 -1
  287. package/lib/summary/runWhileConnectedCoordinator.js.map +0 -1
  288. package/lib/summary/runningSummarizer.d.ts.map +0 -1
  289. package/lib/summary/runningSummarizer.js.map +0 -1
  290. package/lib/summary/summarizer.d.ts.map +0 -1
  291. package/lib/summary/summarizer.js.map +0 -1
  292. package/lib/summary/summarizerHeuristics.d.ts.map +0 -1
  293. package/lib/summary/summarizerHeuristics.js.map +0 -1
  294. package/lib/summary/summaryGenerator.d.ts.map +0 -1
  295. package/lib/summary/summaryGenerator.js.map +0 -1
  296. /package/dist/summary/{runWhileConnectedCoordinator.js → summaryDelayLoadedModule/runWhileConnectedCoordinator.js} +0 -0
  297. /package/dist/summary/{summarizerHeuristics.js → summaryDelayLoadedModule/summarizerHeuristics.js} +0 -0
  298. /package/lib/summary/{runWhileConnectedCoordinator.js → summaryDelayLoadedModule/runWhileConnectedCoordinator.js} +0 -0
  299. /package/lib/summary/{summarizerHeuristics.js → summaryDelayLoadedModule/summarizerHeuristics.js} +0 -0
@@ -21,6 +21,7 @@ import type {
21
21
  IRuntime,
22
22
  IDeltaManager,
23
23
  IDeltaManagerFull,
24
+ ILoader,
24
25
  } from "@fluidframework/container-definitions/internal";
25
26
  import { isIDeltaManagerFull } from "@fluidframework/container-definitions/internal";
26
27
  import type {
@@ -131,6 +132,7 @@ import {
131
132
  raiseConnectedEvent,
132
133
  wrapError,
133
134
  tagCodeArtifacts,
135
+ normalizeError,
134
136
  } from "@fluidframework/telemetry-utils/internal";
135
137
  import { v4 as uuid } from "uuid";
136
138
 
@@ -175,17 +177,15 @@ import {
175
177
  type ContainerRuntimeIdAllocationMessage,
176
178
  type InboundSequencedContainerRuntimeMessage,
177
179
  type LocalContainerRuntimeMessage,
178
- type OutboundContainerRuntimeMessage,
179
180
  type UnknownContainerRuntimeMessage,
180
181
  } from "./messageTypes.js";
181
182
  import { ISavedOpMetadata } from "./metadata.js";
182
183
  import {
183
184
  BatchId,
184
- BatchMessage,
185
+ LocalBatchMessage,
185
186
  BatchStartInfo,
186
187
  DuplicateBatchDetector,
187
188
  ensureContentsDeserialized,
188
- IBatch,
189
189
  IBatchCheckpoint,
190
190
  OpCompressor,
191
191
  OpDecompressor,
@@ -193,7 +193,8 @@ import {
193
193
  OpSplitter,
194
194
  Outbox,
195
195
  RemoteMessageProcessor,
196
- serializeOpContents,
196
+ serializeOp,
197
+ type OutboundBatch,
197
198
  } from "./opLifecycle/index.js";
198
199
  import { pkgVersion } from "./packageVersion.js";
199
200
  import {
@@ -207,37 +208,36 @@ import {
207
208
  validateLoaderCompatibility,
208
209
  } from "./runtimeLayerCompatState.js";
209
210
  import { SignalTelemetryManager } from "./signalTelemetryProcessing.js";
211
+ // These types are imported as types here because they are present in summaryDelayLoadedModule, which is loaded dynamically when required.
212
+ import type {
213
+ IDocumentSchemaChangeMessage,
214
+ IDocumentSchemaCurrent,
215
+ Summarizer,
216
+ IDocumentSchemaFeatures,
217
+ EnqueueSummarizeResult,
218
+ ISerializedElection,
219
+ ISummarizeResults,
220
+ } from "./summary/index.js";
210
221
  import {
211
222
  DocumentsSchemaController,
212
- EnqueueSummarizeResult,
213
223
  IBaseSummarizeResult,
214
224
  IConnectableRuntime,
215
225
  IContainerRuntimeMetadata,
216
226
  ICreateContainerMetadata,
217
- type IDocumentSchemaChangeMessage,
218
- type IDocumentSchemaCurrent,
219
227
  IEnqueueSummarizeOptions,
220
228
  IGenerateSummaryTreeResult,
221
229
  IGeneratedSummaryStats,
222
230
  IOnDemandSummarizeOptions,
223
231
  IRefreshSummaryAckOptions,
224
232
  IRootSummarizerNodeWithGC,
225
- ISerializedElection,
226
233
  ISubmitSummaryOptions,
227
- ISummarizeResults,
228
234
  ISummarizerInternalsProvider,
229
235
  ISummarizerRuntime,
230
236
  ISummaryMetadataMessage,
231
237
  IdCompressorMode,
232
- OrderedClientCollection,
233
238
  OrderedClientElection,
234
239
  RetriableSummaryError,
235
- RunWhileConnectedCoordinator,
236
240
  SubmitSummaryResult,
237
- Summarizer,
238
- SummarizerClientElection,
239
- SummaryCollection,
240
- SummaryManager,
241
241
  aliasBlobName,
242
242
  chunksBlobName,
243
243
  recentBatchInfoBlobName,
@@ -249,9 +249,12 @@ import {
249
249
  rootHasIsolatedChannels,
250
250
  summarizerClientType,
251
251
  wrapSummaryInChannelsTree,
252
- type IDocumentSchemaFeatures,
253
252
  formCreateSummarizerFn,
254
253
  summarizerRequestUrl,
254
+ SummaryManager,
255
+ SummarizerClientElection,
256
+ SummaryCollection,
257
+ OrderedClientCollection,
255
258
  validateSummaryHeuristicConfiguration,
256
259
  ISummaryConfiguration,
257
260
  DefaultSummaryConfiguration,
@@ -369,7 +372,7 @@ export interface IContainerRuntimeOptions {
369
372
  * regardless of the overhead of an individual op.
370
373
  *
371
374
  * Any value of `chunkSizeInBytes` exceeding {@link IContainerRuntimeOptions.maxBatchSizeInBytes} will disable this feature, therefore if a compressed batch's content
372
- * size exceeds {@link IContainerRuntimeOptions.maxBatchSizeInBytes} after compression, the container will close with an instance of `GenericError` with
375
+ * size exceeds {@link IContainerRuntimeOptions.maxBatchSizeInBytes} after compression, the container will close with an instance of `DataProcessingError` with
373
376
  * the `BatchTooLarge` message.
374
377
  */
375
378
  readonly chunkSizeInBytes?: number;
@@ -602,7 +605,7 @@ export const makeLegacySendBatchFn =
602
605
  ) => number,
603
606
  deltaManager: Pick<IDeltaManager<unknown, unknown>, "flush">,
604
607
  ) =>
605
- (batch: IBatch): number => {
608
+ (batch: OutboundBatch): number => {
606
609
  // Default to negative one to match Container.submitBatch behavior
607
610
  let clientSequenceNumber: number = -1;
608
611
  for (const message of batch.messages) {
@@ -1033,7 +1036,7 @@ export class ContainerRuntime
1033
1036
  await runtime.pendingStateManager.applyStashedOpsAt(runtimeSequenceNumber ?? 0);
1034
1037
 
1035
1038
  // Initialize the base state of the runtime before it's returned.
1036
- await runtime.initializeBaseState();
1039
+ await runtime.initializeBaseState(context.loader);
1037
1040
 
1038
1041
  return runtime;
1039
1042
  }
@@ -1167,13 +1170,13 @@ export class ContainerRuntime
1167
1170
  // internal logger for ContainerRuntime. Use this.logger for stores, summaries, etc.
1168
1171
  private readonly mc: MonitoringContext;
1169
1172
 
1170
- private readonly summarizerClientElection?: SummarizerClientElection;
1173
+ private summarizerClientElection?: SummarizerClientElection;
1171
1174
  /**
1172
1175
  * summaryManager will only be created if this client is permitted to spawn a summarizing client
1173
1176
  * It is created only by interactive client, i.e. summarizer client, as well as non-interactive bots
1174
1177
  * do not create it (see SummarizerClientElection.clientDetailsPermitElection() for details)
1175
1178
  */
1176
- private readonly summaryManager?: SummaryManager;
1179
+ private summaryManager?: SummaryManager;
1177
1180
 
1178
1181
  private readonly summarizerNode: IRootSummarizerNodeWithGC;
1179
1182
 
@@ -1235,7 +1238,7 @@ export class ContainerRuntime
1235
1238
  * It is created only by summarizing container (i.e. one with clientType === "summarizer")
1236
1239
  */
1237
1240
 
1238
- private readonly _summarizer?: Summarizer;
1241
+ private _summarizer?: Summarizer;
1239
1242
  private readonly deltaScheduler: DeltaScheduler;
1240
1243
  private readonly inboundBatchAggregator: InboundBatchAggregator;
1241
1244
  private readonly blobManager: BlobManager;
@@ -1315,11 +1318,11 @@ export class ContainerRuntime
1315
1318
  }
1316
1319
 
1317
1320
  /**
1318
- * If true, will skip Outbox flushing before processing an incoming message,
1321
+ * If true, will skip Outbox flushing before processing an incoming message (and on DeltaManager "op" event for loader back-compat),
1319
1322
  * and instead the Outbox will check for a split batch on every submit.
1320
1323
  * This is a kill-bit switch for this simplification of logic, in case it causes unexpected issues.
1321
1324
  */
1322
- private readonly disableFlushBeforeProcess: boolean;
1325
+ private readonly skipSafetyFlushDuringProcessStack: boolean;
1323
1326
 
1324
1327
  /***/
1325
1328
  protected constructor(
@@ -1328,10 +1331,10 @@ export class ContainerRuntime
1328
1331
 
1329
1332
  private readonly metadata: IContainerRuntimeMetadata | undefined,
1330
1333
 
1331
- electedSummarizerData: ISerializedElection | undefined,
1334
+ private readonly electedSummarizerData: ISerializedElection | undefined,
1332
1335
  chunks: [string, string[]][],
1333
1336
  dataStoreAliasMap: [string, string][],
1334
- runtimeOptions: Readonly<Required<IContainerRuntimeOptionsInternal>>,
1337
+ private readonly runtimeOptions: Readonly<Required<IContainerRuntimeOptionsInternal>>,
1335
1338
  private readonly containerScope: FluidObject,
1336
1339
  // Create a custom ITelemetryBaseLogger to output telemetry events.
1337
1340
  public readonly baseLogger: ITelemetryBaseLogger,
@@ -1348,8 +1351,8 @@ export class ContainerRuntime
1348
1351
  request: IRequest,
1349
1352
  runtime: IContainerRuntime,
1350
1353
  ) => Promise<IResponse>,
1351
- // eslint-disable-next-line unicorn/no-object-as-default-parameter
1352
- summaryConfiguration: ISummaryConfiguration = {
1354
+ // // eslint-disable-next-line unicorn/no-object-as-default-parameter
1355
+ private readonly summaryConfiguration: ISummaryConfiguration = {
1353
1356
  // the defaults
1354
1357
  ...DefaultSummaryConfiguration,
1355
1358
  // the runtime configuration overrides
@@ -1373,7 +1376,6 @@ export class ContainerRuntime
1373
1376
  deltaManager,
1374
1377
  quorum,
1375
1378
  audience,
1376
- loader,
1377
1379
  pendingLocalState,
1378
1380
  supportedFeatures,
1379
1381
  snapshotWithContents,
@@ -1558,23 +1560,11 @@ export class ContainerRuntime
1558
1560
 
1559
1561
  this.handleContext = new ContainerFluidHandleContext("", this);
1560
1562
 
1561
- if (summaryConfiguration.state === "enabled") {
1562
- validateSummaryHeuristicConfiguration(summaryConfiguration);
1563
+ if (this.summaryConfiguration.state === "enabled") {
1564
+ validateSummaryHeuristicConfiguration(this.summaryConfiguration);
1563
1565
  }
1564
1566
 
1565
- this.summariesDisabled = isSummariesDisabled(summaryConfiguration);
1566
- const { maxOpsSinceLastSummary = 0, initialSummarizerDelayMs = 0 } = isSummariesDisabled(
1567
- summaryConfiguration,
1568
- )
1569
- ? {}
1570
- : {
1571
- ...summaryConfiguration,
1572
- initialSummarizerDelayMs:
1573
- // back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
1574
- // to ISummaryConfiguration in 0.60.
1575
- runtimeOptions.summaryOptions.initialSummarizerDelayMs ??
1576
- summaryConfiguration.initialSummarizerDelayMs,
1577
- };
1567
+ this.summariesDisabled = isSummariesDisabled(this.summaryConfiguration);
1578
1568
 
1579
1569
  this.maxConsecutiveReconnects =
1580
1570
  this.mc.config.getNumber(maxConsecutiveReconnectsKey) ?? defaultMaxConsecutiveReconnects;
@@ -1756,7 +1746,8 @@ export class ContainerRuntime
1756
1746
 
1757
1747
  const legacySendBatchFn = makeLegacySendBatchFn(submitFn, this.innerDeltaManager);
1758
1748
 
1759
- this.disableFlushBeforeProcess =
1749
+ this.skipSafetyFlushDuringProcessStack =
1750
+ // Keep the old flag name even though we renamed the class member (it shipped in 2.31.0)
1760
1751
  this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableFlushBeforeProcess") === true;
1761
1752
 
1762
1753
  this.outbox = new Outbox({
@@ -1770,7 +1761,7 @@ export class ContainerRuntime
1770
1761
  compressionOptions,
1771
1762
  maxBatchSizeInBytes: runtimeOptions.maxBatchSizeInBytes,
1772
1763
  // If we disable flush before process, we must be ready to flush partial batches
1773
- flushPartialBatches: this.disableFlushBeforeProcess,
1764
+ flushPartialBatches: this.skipSafetyFlushDuringProcessStack,
1774
1765
  },
1775
1766
  logger: this.mc.logger,
1776
1767
  groupingManager: opGroupingManager,
@@ -1781,7 +1772,6 @@ export class ContainerRuntime
1781
1772
  }),
1782
1773
  reSubmit: this.reSubmit.bind(this),
1783
1774
  opReentrancy: () => this.dataModelChangeRunner.running,
1784
- closeContainer: this.closeFn,
1785
1775
  });
1786
1776
 
1787
1777
  this._quorum = quorum;
@@ -1821,112 +1811,18 @@ export class ContainerRuntime
1821
1811
  );
1822
1812
  this.closeSummarizerDelayMs =
1823
1813
  closeSummarizerDelayOverride ?? defaultCloseSummarizerDelayMs;
1824
- const summaryCollection = new SummaryCollection(this.deltaManager, this.baseLogger);
1825
1814
 
1826
1815
  this.dirtyContainer =
1827
1816
  this.attachState !== AttachState.Attached || this.hasPendingMessages();
1828
1817
  context.updateDirtyContainerState(this.dirtyContainer);
1829
1818
 
1830
- if (this.summariesDisabled) {
1831
- this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
1832
- } else {
1833
- const orderedClientLogger = createChildLogger({
1834
- logger: this.baseLogger,
1835
- namespace: "OrderedClientElection",
1836
- });
1837
- const orderedClientCollection = new OrderedClientCollection(
1838
- orderedClientLogger,
1839
- this.innerDeltaManager,
1840
- this._quorum,
1841
- );
1842
- const orderedClientElectionForSummarizer = new OrderedClientElection(
1843
- orderedClientLogger,
1844
- orderedClientCollection,
1845
- electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber,
1846
- SummarizerClientElection.isClientEligible,
1847
- this.mc.config.getBoolean(
1848
- "Fluid.ContainerRuntime.OrderedClientElection.EnablePerformanceEvents",
1849
- ),
1850
- );
1851
-
1852
- this.summarizerClientElection = new SummarizerClientElection(
1853
- orderedClientLogger,
1854
- summaryCollection,
1855
- orderedClientElectionForSummarizer,
1856
- maxOpsSinceLastSummary,
1857
- );
1858
-
1859
- if (isSummarizerClient) {
1860
- this._summarizer = new Summarizer(
1861
- this /* ISummarizerRuntime */,
1862
- () => summaryConfiguration,
1863
- this /* ISummarizerInternalsProvider */,
1864
- this.handleContext,
1865
- summaryCollection,
1866
-
1867
- async (runtime: IConnectableRuntime) =>
1868
- RunWhileConnectedCoordinator.create(
1869
- runtime,
1870
- // Summarization runs in summarizer client and needs access to the real (non-proxy) active
1871
- // information. The proxy delta manager would always return false for summarizer client.
1872
- () => this.innerDeltaManager.active,
1873
- ),
1874
- );
1875
- } else if (SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
1876
- // Only create a SummaryManager and SummarizerClientElection
1877
- // if summaries are enabled and we are not the summarizer client.
1878
- const defaultAction = (): void => {
1879
- if (summaryCollection.opsSinceLastAck > maxOpsSinceLastSummary) {
1880
- this.mc.logger.sendTelemetryEvent({ eventName: "SummaryStatus:Behind" });
1881
- // unregister default to no log on every op after falling behind
1882
- // and register summary ack handler to re-register this handler
1883
- // after successful summary
1884
- summaryCollection.once(MessageType.SummaryAck, () => {
1885
- this.mc.logger.sendTelemetryEvent({
1886
- eventName: "SummaryStatus:CaughtUp",
1887
- });
1888
- // we've caught up, so re-register the default action to monitor for
1889
- // falling behind, and unregister ourself
1890
- summaryCollection.on("default", defaultAction);
1891
- });
1892
- summaryCollection.off("default", defaultAction);
1893
- }
1894
- };
1895
-
1896
- summaryCollection.on("default", defaultAction);
1897
-
1898
- // Create the SummaryManager and mark the initial state
1899
- this.summaryManager = new SummaryManager(
1900
- this.summarizerClientElection,
1901
- this, // IConnectedState
1902
- summaryCollection,
1903
- this.baseLogger,
1904
- formCreateSummarizerFn(loader),
1905
- new Throttler(
1906
- 60 * 1000, // 60 sec delay window
1907
- 30 * 1000, // 30 sec max delay
1908
- // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
1909
- formExponentialFn({ coefficient: 20, initialDelay: 0 }),
1910
- ),
1911
- {
1912
- initialDelayMs: initialSummarizerDelayMs,
1913
- },
1914
- );
1915
- // Forward events from SummaryManager
1916
- for (const eventName of [
1917
- "summarize",
1918
- "summarizeAllAttemptsFailed",
1919
- "summarizerStop",
1920
- "summarizerStart",
1921
- "summarizerStartupFailed",
1922
- ]) {
1923
- this.summaryManager?.on(eventName, (...args: unknown[]) => {
1924
- this.emit(eventName, ...args);
1925
- });
1926
- }
1927
-
1928
- this.summaryManager.start();
1929
- }
1819
+ if (!this.skipSafetyFlushDuringProcessStack) {
1820
+ // Reference Sequence Number may have just changed, and it must be consistent across a batch,
1821
+ // so we should flush now to clear the way for the next ops.
1822
+ // NOTE: This will be redundant whenever CR.process was called for the op (since we flush there too) -
1823
+ // But we need this coverage for old loaders that don't call ContainerRuntime.process for non-runtime messages.
1824
+ // (We have to call flush _before_ processing a runtime op, but after is ok for non-runtime op)
1825
+ this.deltaManager.on("op", () => this.flush());
1930
1826
  }
1931
1827
 
1932
1828
  // logging hardware telemetry
@@ -1951,7 +1847,7 @@ export class ContainerRuntime
1951
1847
  featureGates: JSON.stringify({
1952
1848
  ...featureGatesForTelemetry,
1953
1849
  closeSummarizerDelayOverride,
1954
- disableFlushBeforeProcess: this.disableFlushBeforeProcess,
1850
+ disableFlushBeforeProcess: this.skipSafetyFlushDuringProcessStack,
1955
1851
  }),
1956
1852
  telemetryDocumentId: this.telemetryDocumentId,
1957
1853
  groupedBatchingEnabled: this.groupedBatchingEnabled,
@@ -2029,7 +1925,9 @@ export class ContainerRuntime
2029
1925
  /**
2030
1926
  * Initializes the state from the base snapshot this container runtime loaded from.
2031
1927
  */
2032
- private async initializeBaseState(): Promise<void> {
1928
+ private async initializeBaseState(loader: ILoader): Promise<void> {
1929
+ await this.initializeSummarizer(loader);
1930
+
2033
1931
  if (
2034
1932
  this.sessionSchema.idCompressorMode === "on" ||
2035
1933
  (this.sessionSchema.idCompressorMode === "delayed" && this.connected)
@@ -2042,6 +1940,134 @@ export class ContainerRuntime
2042
1940
  await this.garbageCollector.initializeBaseState();
2043
1941
  }
2044
1942
 
1943
+ private async initializeSummarizer(loader: ILoader): Promise<void> {
1944
+ if (this.summariesDisabled) {
1945
+ this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
1946
+ return;
1947
+ }
1948
+
1949
+ const { maxOpsSinceLastSummary = 0, initialSummarizerDelayMs = 0 } = isSummariesDisabled(
1950
+ this.summaryConfiguration,
1951
+ )
1952
+ ? {}
1953
+ : {
1954
+ ...this.summaryConfiguration,
1955
+ initialSummarizerDelayMs:
1956
+ // back-compat: initialSummarizerDelayMs was moved from ISummaryRuntimeOptions
1957
+ // to ISummaryConfiguration in 0.60.
1958
+ this.runtimeOptions.summaryOptions.initialSummarizerDelayMs ??
1959
+ this.summaryConfiguration.initialSummarizerDelayMs,
1960
+ };
1961
+
1962
+ const summaryCollection: SummaryCollection = new SummaryCollection(
1963
+ this.deltaManager,
1964
+ this.baseLogger,
1965
+ );
1966
+ const orderedClientLogger = createChildLogger({
1967
+ logger: this.baseLogger,
1968
+ namespace: "OrderedClientElection",
1969
+ });
1970
+ const orderedClientCollection = new OrderedClientCollection(
1971
+ orderedClientLogger,
1972
+ this.innerDeltaManager,
1973
+ this._quorum,
1974
+ );
1975
+ const orderedClientElectionForSummarizer = new OrderedClientElection(
1976
+ orderedClientLogger,
1977
+ orderedClientCollection,
1978
+ this.electedSummarizerData ?? this.innerDeltaManager.lastSequenceNumber,
1979
+ SummarizerClientElection.isClientEligible,
1980
+ this.mc.config.getBoolean(
1981
+ "Fluid.ContainerRuntime.OrderedClientElection.EnablePerformanceEvents",
1982
+ ),
1983
+ );
1984
+
1985
+ this.summarizerClientElection = new SummarizerClientElection(
1986
+ orderedClientLogger,
1987
+ summaryCollection,
1988
+ orderedClientElectionForSummarizer,
1989
+ maxOpsSinceLastSummary,
1990
+ );
1991
+
1992
+ const isSummarizerClient = this.clientDetails.type === summarizerClientType;
1993
+ if (isSummarizerClient) {
1994
+ // We want to dynamically import any thing inside summaryDelayLoadedModule module only when we are the summarizer client,
1995
+ // so that all non summarizer clients don't have to load the code inside this module.
1996
+ const module = await import(
1997
+ /* webpackChunkName: "summarizerDelayLoadedModule" */ "./summary/index.js"
1998
+ );
1999
+ this._summarizer = new module.Summarizer(
2000
+ this /* ISummarizerRuntime */,
2001
+ () => this.summaryConfiguration,
2002
+ this /* ISummarizerInternalsProvider */,
2003
+ this.handleContext,
2004
+ summaryCollection,
2005
+
2006
+ async (runtime: IConnectableRuntime) =>
2007
+ module.RunWhileConnectedCoordinator.create(
2008
+ runtime,
2009
+ // Summarization runs in summarizer client and needs access to the real (non-proxy) active
2010
+ // information. The proxy delta manager would always return false for summarizer client.
2011
+ () => this.innerDeltaManager.active,
2012
+ ),
2013
+ );
2014
+ } else if (SummarizerClientElection.clientDetailsPermitElection(this.clientDetails)) {
2015
+ // Only create a SummaryManager and SummarizerClientElection
2016
+ // if summaries are enabled and we are not the summarizer client.
2017
+ const defaultAction = (): void => {
2018
+ if (summaryCollection.opsSinceLastAck > maxOpsSinceLastSummary) {
2019
+ this.mc.logger.sendTelemetryEvent({ eventName: "SummaryStatus:Behind" });
2020
+ // unregister default to no log on every op after falling behind
2021
+ // and register summary ack handler to re-register this handler
2022
+ // after successful summary
2023
+ summaryCollection.once(MessageType.SummaryAck, () => {
2024
+ this.mc.logger.sendTelemetryEvent({
2025
+ eventName: "SummaryStatus:CaughtUp",
2026
+ });
2027
+ // we've caught up, so re-register the default action to monitor for
2028
+ // falling behind, and unregister ourself
2029
+ summaryCollection.on("default", defaultAction);
2030
+ });
2031
+ summaryCollection.off("default", defaultAction);
2032
+ }
2033
+ };
2034
+
2035
+ summaryCollection.on("default", defaultAction);
2036
+
2037
+ // Create the SummaryManager and mark the initial state
2038
+ this.summaryManager = new SummaryManager(
2039
+ this.summarizerClientElection,
2040
+ this, // IConnectedState
2041
+ summaryCollection,
2042
+ this.baseLogger,
2043
+ formCreateSummarizerFn(loader),
2044
+ new Throttler(
2045
+ 60 * 1000, // 60 sec delay window
2046
+ 30 * 1000, // 30 sec max delay
2047
+ // throttling function increases exponentially (0ms, 40ms, 80ms, 160ms, etc)
2048
+ formExponentialFn({ coefficient: 20, initialDelay: 0 }),
2049
+ ),
2050
+ {
2051
+ initialDelayMs: initialSummarizerDelayMs,
2052
+ },
2053
+ );
2054
+ // Forward events from SummaryManager
2055
+ for (const eventName of [
2056
+ "summarize",
2057
+ "summarizeAllAttemptsFailed",
2058
+ "summarizerStop",
2059
+ "summarizerStart",
2060
+ "summarizerStartupFailed",
2061
+ ]) {
2062
+ this.summaryManager?.on(eventName, (...args: unknown[]) => {
2063
+ this.emit(eventName, ...args);
2064
+ });
2065
+ }
2066
+
2067
+ this.summaryManager.start();
2068
+ }
2069
+ }
2070
+
2045
2071
  public dispose(error?: Error): void {
2046
2072
  if (this._disposed) {
2047
2073
  return;
@@ -2438,7 +2464,6 @@ export class ContainerRuntime
2438
2464
  * Parse an op's type and actual content from given serialized content
2439
2465
  * ! Note: this format needs to be in-line with what is set in the "ContainerRuntime.submit(...)" method
2440
2466
  */
2441
- // TODO: markfields: confirm Local- versus Outbound- ContainerRuntimeMessage typing
2442
2467
  private parseLocalOpContent(serializedContents?: string): LocalContainerRuntimeMessage {
2443
2468
  assert(serializedContents !== undefined, 0x6d5 /* content must be defined */);
2444
2469
  const message = JSON.parse(serializedContents) as LocalContainerRuntimeMessage;
@@ -2447,7 +2472,7 @@ export class ContainerRuntime
2447
2472
  }
2448
2473
 
2449
2474
  private async applyStashedOp(serializedOpContent: string): Promise<unknown> {
2450
- // Need to parse from string for back-compat
2475
+ // Pending State contains serialized contents, so parse it here.
2451
2476
  const opContents = this.parseLocalOpContent(serializedOpContent);
2452
2477
  switch (opContents.type) {
2453
2478
  case ContainerMessageType.FluidDataStoreOp:
@@ -2639,9 +2664,9 @@ export class ContainerRuntime
2639
2664
 
2640
2665
  this.verifyNotClosed();
2641
2666
 
2642
- if (!this.disableFlushBeforeProcess) {
2667
+ if (!this.skipSafetyFlushDuringProcessStack) {
2643
2668
  // Reference Sequence Number may be about to change, and it must be consistent across a batch, so flush now
2644
- this.outbox.flush();
2669
+ this.flush();
2645
2670
  }
2646
2671
 
2647
2672
  this.ensureNoDataModelChanges(() => {
@@ -3092,17 +3117,29 @@ export class ContainerRuntime
3092
3117
  /**
3093
3118
  * Flush the pending ops manually.
3094
3119
  * This method is expected to be called at the end of a batch.
3120
+ * @remarks - If it throws (e.g. if the batch is too large to send), the container will be closed.
3121
+ *
3095
3122
  * @param resubmittingBatchId - If defined, indicates this is a resubmission of a batch
3096
3123
  * with the given Batch ID, which must be preserved
3097
3124
  */
3098
3125
  private flush(resubmittingBatchId?: BatchId): void {
3099
- assert(
3100
- !this.batchRunner.running,
3101
- 0x24c /* "Cannot call `flush()` while manually accumulating a batch (e.g. under orderSequentially) */,
3102
- );
3126
+ try {
3127
+ assert(
3128
+ !this.batchRunner.running,
3129
+ 0x24c /* "Cannot call `flush()` while manually accumulating a batch (e.g. under orderSequentially) */,
3130
+ );
3103
3131
 
3104
- this.outbox.flush(resubmittingBatchId);
3105
- assert(this.outbox.isEmpty, 0x3cf /* reentrancy */);
3132
+ this.outbox.flush(resubmittingBatchId);
3133
+ assert(this.outbox.isEmpty, 0x3cf /* reentrancy */);
3134
+ } catch (error) {
3135
+ const error2 = normalizeError(error, {
3136
+ props: {
3137
+ orderSequentiallyCalls: this.batchRunner.runs,
3138
+ },
3139
+ });
3140
+ this.closeFn(error2);
3141
+ throw error2;
3142
+ }
3106
3143
  }
3107
3144
 
3108
3145
  /**
@@ -3124,8 +3161,8 @@ export class ContainerRuntime
3124
3161
  if (checkpoint) {
3125
3162
  // This will throw and close the container if rollback fails
3126
3163
  try {
3127
- checkpoint.rollback((message: BatchMessage) =>
3128
- this.rollback(message.contents, message.localOpMetadata),
3164
+ checkpoint.rollback((message: LocalBatchMessage) =>
3165
+ this.rollback(message.serializedOp, message.localOpMetadata),
3129
3166
  );
3130
3167
  // reset the dirty state after rollback to what it was before to keep it consistent
3131
3168
  if (this.dirtyContainer !== checkpointDirtyState) {
@@ -3268,7 +3305,7 @@ export class ContainerRuntime
3268
3305
  private isContainerMessageDirtyable({
3269
3306
  type,
3270
3307
  contents,
3271
- }: OutboundContainerRuntimeMessage): boolean {
3308
+ }: LocalContainerRuntimeMessage): boolean {
3272
3309
  // Certain container runtime messages should not mark the container dirty such as the old built-in
3273
3310
  // AgentScheduler and Garbage collector messages.
3274
3311
  switch (type) {
@@ -4176,8 +4213,8 @@ export class ContainerRuntime
4176
4213
  type: ContainerMessageType.IdAllocation,
4177
4214
  contents: idRange,
4178
4215
  };
4179
- const idAllocationBatchMessage: BatchMessage = {
4180
- contents: serializeOpContents(idAllocationMessage),
4216
+ const idAllocationBatchMessage: LocalBatchMessage = {
4217
+ serializedOp: serializeOp(idAllocationMessage),
4181
4218
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
4182
4219
  };
4183
4220
  this.outbox.submitIdAllocation(idAllocationBatchMessage);
@@ -4186,7 +4223,7 @@ export class ContainerRuntime
4186
4223
  }
4187
4224
 
4188
4225
  private submit(
4189
- containerRuntimeMessage: OutboundContainerRuntimeMessage,
4226
+ containerRuntimeMessage: LocalContainerRuntimeMessage,
4190
4227
  localOpMetadata: unknown = undefined,
4191
4228
  metadata?: { localId: string; blobId?: string },
4192
4229
  ): void {
@@ -4240,13 +4277,15 @@ export class ContainerRuntime
4240
4277
  contents: schemaChangeMessage,
4241
4278
  };
4242
4279
  this.outbox.submit({
4243
- contents: serializeOpContents(msg),
4280
+ serializedOp: serializeOp(msg),
4244
4281
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
4245
4282
  });
4246
4283
  }
4247
4284
 
4248
- const message: BatchMessage = {
4249
- contents: serializeOpContents(containerRuntimeMessage),
4285
+ const message: LocalBatchMessage = {
4286
+ // This will encode any handles present in this op before serializing to string
4287
+ // Note: handles may already have been encoded by the DDS layer, but encoding handles is idempotent so there's no problem.
4288
+ serializedOp: serializeOp(containerRuntimeMessage),
4250
4289
  metadata,
4251
4290
  localOpMetadata,
4252
4291
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
@@ -4266,8 +4305,11 @@ export class ContainerRuntime
4266
4305
  this.scheduleFlush();
4267
4306
  }
4268
4307
  } catch (error) {
4269
- this.closeFn(error as GenericError);
4270
- throw error;
4308
+ const dpe = DataProcessingError.wrapIfUnrecognized(error, "ContainerRuntime.submit", {
4309
+ referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
4310
+ });
4311
+ this.closeFn(dpe);
4312
+ throw dpe;
4271
4313
  }
4272
4314
 
4273
4315
  if (this.isContainerMessageDirtyable(containerRuntimeMessage)) {
@@ -4286,11 +4328,7 @@ export class ContainerRuntime
4286
4328
  // eslint-disable-next-line unicorn/consistent-function-scoping -- Separate `flush` method already exists in outer scope
4287
4329
  const flush = (): void => {
4288
4330
  this.flushTaskExists = false;
4289
- try {
4290
- this.flush();
4291
- } catch (error) {
4292
- this.closeFn(error as GenericError);
4293
- }
4331
+ this.flush();
4294
4332
  };
4295
4333
 
4296
4334
  switch (this.flushMode) {
@@ -4366,7 +4404,9 @@ export class ContainerRuntime
4366
4404
  }
4367
4405
 
4368
4406
  private reSubmit(message: PendingMessageResubmitData): void {
4369
- // Need to parse from string for back-compat
4407
+ // Messages in the PendingStateManager and Outbox (both call resubmit) have serialized contents, so parse it here.
4408
+ // Note that roundtripping handles through string like this means this parsed contents
4409
+ // contains RemoteFluidObjectHandles, not the original handle.
4370
4410
  const containerRuntimeMessage = this.parseLocalOpContent(message.content);
4371
4411
  this.reSubmitCore(containerRuntimeMessage, message.localOpMetadata, message.opMetadata);
4372
4412
  }
@@ -4433,7 +4473,9 @@ export class ContainerRuntime
4433
4473
  }
4434
4474
 
4435
4475
  private rollback(content: string | undefined, localOpMetadata: unknown): void {
4436
- // Need to parse from string for back-compat
4476
+ // Messages in the Outbox (which calls rollback) have serialized contents, so parse it here.
4477
+ // Note that roundtripping handles through string like this means this parsed contents
4478
+ // contains RemoteFluidObjectHandles, not the original handle.
4437
4479
  const { type, contents } = this.parseLocalOpContent(content);
4438
4480
  switch (type) {
4439
4481
  case ContainerMessageType.FluidDataStoreOp: {