@fluidframework/container-runtime 2.0.0-internal.6.1.1 → 2.0.0-internal.6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +4 -3
  3. package/dist/batchTracker.d.ts +1 -1
  4. package/dist/batchTracker.js +1 -1
  5. package/dist/batchTracker.js.map +1 -1
  6. package/dist/blobManager.d.ts +4 -20
  7. package/dist/blobManager.d.ts.map +1 -1
  8. package/dist/blobManager.js +47 -125
  9. package/dist/blobManager.js.map +1 -1
  10. package/dist/containerRuntime.d.ts +82 -14
  11. package/dist/containerRuntime.d.ts.map +1 -1
  12. package/dist/containerRuntime.js +236 -138
  13. package/dist/containerRuntime.js.map +1 -1
  14. package/dist/dataStore.d.ts.map +1 -1
  15. package/dist/dataStore.js +1 -2
  16. package/dist/dataStore.js.map +1 -1
  17. package/dist/dataStoreContext.d.ts.map +1 -1
  18. package/dist/dataStoreContext.js +4 -5
  19. package/dist/dataStoreContext.js.map +1 -1
  20. package/dist/dataStoreContexts.d.ts +1 -2
  21. package/dist/dataStoreContexts.d.ts.map +1 -1
  22. package/dist/dataStoreContexts.js.map +1 -1
  23. package/dist/dataStoreRegistry.js +2 -2
  24. package/dist/dataStoreRegistry.js.map +1 -1
  25. package/dist/dataStores.d.ts.map +1 -1
  26. package/dist/dataStores.js +4 -5
  27. package/dist/dataStores.js.map +1 -1
  28. package/dist/error.d.ts +14 -0
  29. package/dist/error.d.ts.map +1 -0
  30. package/dist/error.js +21 -0
  31. package/dist/error.js.map +1 -0
  32. package/dist/gc/garbageCollection.d.ts +1 -1
  33. package/dist/gc/garbageCollection.d.ts.map +1 -1
  34. package/dist/gc/garbageCollection.js +23 -5
  35. package/dist/gc/garbageCollection.js.map +1 -1
  36. package/dist/gc/gcConfigs.d.ts.map +1 -1
  37. package/dist/gc/gcConfigs.js +5 -3
  38. package/dist/gc/gcConfigs.js.map +1 -1
  39. package/dist/gc/gcDefinitions.d.ts +2 -0
  40. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  41. package/dist/gc/gcDefinitions.js.map +1 -1
  42. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  43. package/dist/gc/gcTelemetry.js +2 -0
  44. package/dist/gc/gcTelemetry.js.map +1 -1
  45. package/dist/id-compressor/appendOnlySortedMap.d.ts +8 -30
  46. package/dist/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
  47. package/dist/id-compressor/appendOnlySortedMap.js +25 -67
  48. package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
  49. package/dist/id-compressor/finalSpace.d.ts +29 -0
  50. package/dist/id-compressor/finalSpace.d.ts.map +1 -0
  51. package/dist/id-compressor/finalSpace.js +62 -0
  52. package/dist/id-compressor/finalSpace.js.map +1 -0
  53. package/dist/id-compressor/idCompressor.d.ts +25 -250
  54. package/dist/id-compressor/idCompressor.d.ts.map +1 -1
  55. package/dist/id-compressor/idCompressor.js +385 -1149
  56. package/dist/id-compressor/idCompressor.js.map +1 -1
  57. package/dist/id-compressor/identifiers.d.ts +32 -0
  58. package/dist/id-compressor/identifiers.d.ts.map +1 -0
  59. package/dist/id-compressor/identifiers.js +15 -0
  60. package/dist/id-compressor/identifiers.js.map +1 -0
  61. package/dist/id-compressor/index.d.ts +5 -6
  62. package/dist/id-compressor/index.d.ts.map +1 -1
  63. package/dist/id-compressor/index.js +20 -26
  64. package/dist/id-compressor/index.js.map +1 -1
  65. package/dist/id-compressor/persistanceUtilities.d.ts +22 -0
  66. package/dist/id-compressor/persistanceUtilities.d.ts.map +1 -0
  67. package/dist/id-compressor/persistanceUtilities.js +43 -0
  68. package/dist/id-compressor/persistanceUtilities.js.map +1 -0
  69. package/dist/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
  70. package/dist/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
  71. package/dist/id-compressor/sessionSpaceNormalizer.js +80 -0
  72. package/dist/id-compressor/sessionSpaceNormalizer.js.map +1 -0
  73. package/dist/id-compressor/sessions.d.ts +115 -0
  74. package/dist/id-compressor/sessions.d.ts.map +1 -0
  75. package/dist/id-compressor/sessions.js +305 -0
  76. package/dist/id-compressor/sessions.js.map +1 -0
  77. package/dist/id-compressor/utilities.d.ts +49 -0
  78. package/dist/id-compressor/utilities.d.ts.map +1 -0
  79. package/dist/id-compressor/utilities.js +166 -0
  80. package/dist/id-compressor/utilities.js.map +1 -0
  81. package/dist/index.d.ts +3 -3
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +6 -4
  84. package/dist/index.js.map +1 -1
  85. package/dist/opLifecycle/opCompressor.d.ts.map +1 -1
  86. package/dist/opLifecycle/opCompressor.js +1 -2
  87. package/dist/opLifecycle/opCompressor.js.map +1 -1
  88. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  89. package/dist/opLifecycle/opSplitter.js +2 -3
  90. package/dist/opLifecycle/opSplitter.js.map +1 -1
  91. package/dist/opLifecycle/outbox.d.ts +1 -0
  92. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  93. package/dist/opLifecycle/outbox.js +10 -11
  94. package/dist/opLifecycle/outbox.js.map +1 -1
  95. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  96. package/dist/opLifecycle/remoteMessageProcessor.js +11 -5
  97. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  98. package/dist/packageVersion.d.ts +1 -1
  99. package/dist/packageVersion.js +1 -1
  100. package/dist/packageVersion.js.map +1 -1
  101. package/dist/pendingStateManager.d.ts +12 -5
  102. package/dist/pendingStateManager.d.ts.map +1 -1
  103. package/dist/pendingStateManager.js +24 -10
  104. package/dist/pendingStateManager.js.map +1 -1
  105. package/dist/scheduleManager.d.ts.map +1 -1
  106. package/dist/scheduleManager.js +4 -5
  107. package/dist/scheduleManager.js.map +1 -1
  108. package/dist/summary/index.d.ts +2 -2
  109. package/dist/summary/index.d.ts.map +1 -1
  110. package/dist/summary/index.js +2 -1
  111. package/dist/summary/index.js.map +1 -1
  112. package/dist/summary/orderedClientElection.d.ts +1 -2
  113. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  114. package/dist/summary/orderedClientElection.js +2 -3
  115. package/dist/summary/orderedClientElection.js.map +1 -1
  116. package/dist/summary/runningSummarizer.d.ts +27 -4
  117. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  118. package/dist/summary/runningSummarizer.js +237 -66
  119. package/dist/summary/runningSummarizer.js.map +1 -1
  120. package/dist/summary/summarizer.d.ts +6 -5
  121. package/dist/summary/summarizer.d.ts.map +1 -1
  122. package/dist/summary/summarizer.js +70 -67
  123. package/dist/summary/summarizer.js.map +1 -1
  124. package/dist/summary/summarizerClientElection.d.ts +1 -1
  125. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  126. package/dist/summary/summarizerClientElection.js.map +1 -1
  127. package/dist/summary/summarizerTypes.d.ts +38 -25
  128. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  129. package/dist/summary/summarizerTypes.js.map +1 -1
  130. package/dist/summary/summaryCollection.d.ts +1 -2
  131. package/dist/summary/summaryCollection.d.ts.map +1 -1
  132. package/dist/summary/summaryCollection.js.map +1 -1
  133. package/dist/summary/summaryGenerator.d.ts +9 -3
  134. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  135. package/dist/summary/summaryGenerator.js +42 -38
  136. package/dist/summary/summaryGenerator.js.map +1 -1
  137. package/dist/summary/summaryManager.d.ts +7 -6
  138. package/dist/summary/summaryManager.d.ts.map +1 -1
  139. package/dist/summary/summaryManager.js +22 -15
  140. package/dist/summary/summaryManager.js.map +1 -1
  141. package/lib/batchTracker.d.ts +1 -1
  142. package/lib/batchTracker.js +1 -1
  143. package/lib/batchTracker.js.map +1 -1
  144. package/lib/blobManager.d.ts +4 -20
  145. package/lib/blobManager.d.ts.map +1 -1
  146. package/lib/blobManager.js +46 -124
  147. package/lib/blobManager.js.map +1 -1
  148. package/lib/containerRuntime.d.ts +82 -14
  149. package/lib/containerRuntime.d.ts.map +1 -1
  150. package/lib/containerRuntime.js +223 -123
  151. package/lib/containerRuntime.js.map +1 -1
  152. package/lib/dataStore.d.ts.map +1 -1
  153. package/lib/dataStore.js +1 -2
  154. package/lib/dataStore.js.map +1 -1
  155. package/lib/dataStoreContext.d.ts.map +1 -1
  156. package/lib/dataStoreContext.js +1 -2
  157. package/lib/dataStoreContext.js.map +1 -1
  158. package/lib/dataStoreContexts.d.ts +1 -2
  159. package/lib/dataStoreContexts.d.ts.map +1 -1
  160. package/lib/dataStoreContexts.js.map +1 -1
  161. package/lib/dataStoreRegistry.js +1 -1
  162. package/lib/dataStoreRegistry.js.map +1 -1
  163. package/lib/dataStores.d.ts.map +1 -1
  164. package/lib/dataStores.js +1 -2
  165. package/lib/dataStores.js.map +1 -1
  166. package/lib/error.d.ts +14 -0
  167. package/lib/error.d.ts.map +1 -0
  168. package/lib/error.js +17 -0
  169. package/lib/error.js.map +1 -0
  170. package/lib/gc/garbageCollection.d.ts +1 -1
  171. package/lib/gc/garbageCollection.d.ts.map +1 -1
  172. package/lib/gc/garbageCollection.js +22 -4
  173. package/lib/gc/garbageCollection.js.map +1 -1
  174. package/lib/gc/gcConfigs.d.ts.map +1 -1
  175. package/lib/gc/gcConfigs.js +3 -1
  176. package/lib/gc/gcConfigs.js.map +1 -1
  177. package/lib/gc/gcDefinitions.d.ts +2 -0
  178. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  179. package/lib/gc/gcDefinitions.js.map +1 -1
  180. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  181. package/lib/gc/gcTelemetry.js +2 -0
  182. package/lib/gc/gcTelemetry.js.map +1 -1
  183. package/lib/id-compressor/appendOnlySortedMap.d.ts +8 -30
  184. package/lib/id-compressor/appendOnlySortedMap.d.ts.map +1 -1
  185. package/lib/id-compressor/appendOnlySortedMap.js +24 -65
  186. package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
  187. package/lib/id-compressor/finalSpace.d.ts +29 -0
  188. package/lib/id-compressor/finalSpace.d.ts.map +1 -0
  189. package/lib/id-compressor/finalSpace.js +58 -0
  190. package/lib/id-compressor/finalSpace.js.map +1 -0
  191. package/lib/id-compressor/idCompressor.d.ts +25 -250
  192. package/lib/id-compressor/idCompressor.d.ts.map +1 -1
  193. package/lib/id-compressor/idCompressor.js +381 -1139
  194. package/lib/id-compressor/idCompressor.js.map +1 -1
  195. package/lib/id-compressor/identifiers.d.ts +32 -0
  196. package/lib/id-compressor/identifiers.d.ts.map +1 -0
  197. package/lib/id-compressor/identifiers.js +11 -0
  198. package/lib/id-compressor/identifiers.js.map +1 -0
  199. package/lib/id-compressor/index.d.ts +5 -6
  200. package/lib/id-compressor/index.d.ts.map +1 -1
  201. package/lib/id-compressor/index.js +5 -6
  202. package/lib/id-compressor/index.js.map +1 -1
  203. package/lib/id-compressor/persistanceUtilities.d.ts +22 -0
  204. package/lib/id-compressor/persistanceUtilities.d.ts.map +1 -0
  205. package/lib/id-compressor/persistanceUtilities.js +34 -0
  206. package/lib/id-compressor/persistanceUtilities.js.map +1 -0
  207. package/lib/id-compressor/sessionSpaceNormalizer.d.ts +46 -0
  208. package/lib/id-compressor/sessionSpaceNormalizer.d.ts.map +1 -0
  209. package/lib/id-compressor/sessionSpaceNormalizer.js +76 -0
  210. package/lib/id-compressor/sessionSpaceNormalizer.js.map +1 -0
  211. package/lib/id-compressor/sessions.d.ts +115 -0
  212. package/lib/id-compressor/sessions.d.ts.map +1 -0
  213. package/lib/id-compressor/sessions.js +290 -0
  214. package/lib/id-compressor/sessions.js.map +1 -0
  215. package/lib/id-compressor/utilities.d.ts +49 -0
  216. package/lib/id-compressor/utilities.d.ts.map +1 -0
  217. package/lib/id-compressor/utilities.js +148 -0
  218. package/lib/id-compressor/utilities.js.map +1 -0
  219. package/lib/index.d.ts +3 -3
  220. package/lib/index.d.ts.map +1 -1
  221. package/lib/index.js +2 -2
  222. package/lib/index.js.map +1 -1
  223. package/lib/opLifecycle/opCompressor.d.ts.map +1 -1
  224. package/lib/opLifecycle/opCompressor.js +1 -2
  225. package/lib/opLifecycle/opCompressor.js.map +1 -1
  226. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  227. package/lib/opLifecycle/opSplitter.js +1 -2
  228. package/lib/opLifecycle/opSplitter.js.map +1 -1
  229. package/lib/opLifecycle/outbox.d.ts +1 -0
  230. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  231. package/lib/opLifecycle/outbox.js +6 -7
  232. package/lib/opLifecycle/outbox.js.map +1 -1
  233. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  234. package/lib/opLifecycle/remoteMessageProcessor.js +12 -6
  235. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  236. package/lib/packageVersion.d.ts +1 -1
  237. package/lib/packageVersion.js +1 -1
  238. package/lib/packageVersion.js.map +1 -1
  239. package/lib/pendingStateManager.d.ts +12 -5
  240. package/lib/pendingStateManager.d.ts.map +1 -1
  241. package/lib/pendingStateManager.js +21 -7
  242. package/lib/pendingStateManager.js.map +1 -1
  243. package/lib/scheduleManager.d.ts.map +1 -1
  244. package/lib/scheduleManager.js +1 -2
  245. package/lib/scheduleManager.js.map +1 -1
  246. package/lib/summary/index.d.ts +2 -2
  247. package/lib/summary/index.d.ts.map +1 -1
  248. package/lib/summary/index.js +1 -1
  249. package/lib/summary/index.js.map +1 -1
  250. package/lib/summary/orderedClientElection.d.ts +1 -2
  251. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  252. package/lib/summary/orderedClientElection.js +1 -2
  253. package/lib/summary/orderedClientElection.js.map +1 -1
  254. package/lib/summary/runningSummarizer.d.ts +27 -4
  255. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  256. package/lib/summary/runningSummarizer.js +237 -66
  257. package/lib/summary/runningSummarizer.js.map +1 -1
  258. package/lib/summary/summarizer.d.ts +6 -5
  259. package/lib/summary/summarizer.d.ts.map +1 -1
  260. package/lib/summary/summarizer.js +68 -65
  261. package/lib/summary/summarizer.js.map +1 -1
  262. package/lib/summary/summarizerClientElection.d.ts +1 -1
  263. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  264. package/lib/summary/summarizerClientElection.js.map +1 -1
  265. package/lib/summary/summarizerTypes.d.ts +38 -25
  266. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  267. package/lib/summary/summarizerTypes.js.map +1 -1
  268. package/lib/summary/summaryCollection.d.ts +1 -2
  269. package/lib/summary/summaryCollection.d.ts.map +1 -1
  270. package/lib/summary/summaryCollection.js.map +1 -1
  271. package/lib/summary/summaryGenerator.d.ts +9 -3
  272. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  273. package/lib/summary/summaryGenerator.js +43 -39
  274. package/lib/summary/summaryGenerator.js.map +1 -1
  275. package/lib/summary/summaryManager.d.ts +7 -6
  276. package/lib/summary/summaryManager.d.ts.map +1 -1
  277. package/lib/summary/summaryManager.js +23 -16
  278. package/lib/summary/summaryManager.js.map +1 -1
  279. package/package.json +27 -24
  280. package/src/batchTracker.ts +1 -1
  281. package/src/blobManager.ts +57 -146
  282. package/src/containerRuntime.ts +331 -158
  283. package/src/dataStore.ts +1 -2
  284. package/src/dataStoreContext.ts +3 -6
  285. package/src/dataStoreContexts.ts +1 -2
  286. package/src/dataStoreRegistry.ts +1 -1
  287. package/src/dataStores.ts +3 -5
  288. package/src/error.ts +18 -0
  289. package/src/gc/garbageCollection.ts +38 -5
  290. package/src/gc/gcConfigs.ts +4 -2
  291. package/src/gc/gcDefinitions.ts +2 -0
  292. package/src/gc/gcTelemetry.ts +2 -0
  293. package/src/id-compressor/appendOnlySortedMap.ts +25 -86
  294. package/src/id-compressor/finalSpace.ts +67 -0
  295. package/src/id-compressor/idCompressor.ts +455 -1681
  296. package/src/id-compressor/identifiers.ts +42 -0
  297. package/src/id-compressor/index.ts +11 -20
  298. package/src/id-compressor/persistanceUtilities.ts +58 -0
  299. package/src/id-compressor/sessionSpaceNormalizer.ts +83 -0
  300. package/src/id-compressor/sessions.ts +405 -0
  301. package/src/id-compressor/utilities.ts +187 -0
  302. package/src/index.ts +7 -1
  303. package/src/opLifecycle/opCompressor.ts +1 -2
  304. package/src/opLifecycle/opSplitter.ts +4 -4
  305. package/src/opLifecycle/outbox.ts +13 -10
  306. package/src/opLifecycle/remoteMessageProcessor.ts +19 -6
  307. package/src/packageVersion.ts +1 -1
  308. package/src/pendingStateManager.ts +49 -27
  309. package/src/scheduleManager.ts +5 -4
  310. package/src/summary/index.ts +3 -1
  311. package/src/summary/orderedClientElection.ts +6 -4
  312. package/src/summary/runningSummarizer.ts +276 -95
  313. package/src/summary/summarizer.ts +22 -12
  314. package/src/summary/summarizerClientElection.ts +1 -1
  315. package/src/summary/summarizerTypes.ts +40 -25
  316. package/src/summary/summaryCollection.ts +1 -2
  317. package/src/summary/summaryGenerator.ts +49 -52
  318. package/src/summary/summaryManager.ts +33 -11
  319. package/dist/id-compressor/idRange.d.ts +0 -11
  320. package/dist/id-compressor/idRange.d.ts.map +0 -1
  321. package/dist/id-compressor/idRange.js +0 -29
  322. package/dist/id-compressor/idRange.js.map +0 -1
  323. package/dist/id-compressor/numericUuid.d.ts +0 -59
  324. package/dist/id-compressor/numericUuid.d.ts.map +0 -1
  325. package/dist/id-compressor/numericUuid.js +0 -325
  326. package/dist/id-compressor/numericUuid.js.map +0 -1
  327. package/dist/id-compressor/sessionIdNormalizer.d.ts +0 -138
  328. package/dist/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
  329. package/dist/id-compressor/sessionIdNormalizer.js +0 -483
  330. package/dist/id-compressor/sessionIdNormalizer.js.map +0 -1
  331. package/dist/id-compressor/utils.d.ts +0 -57
  332. package/dist/id-compressor/utils.d.ts.map +0 -1
  333. package/dist/id-compressor/utils.js +0 -90
  334. package/dist/id-compressor/utils.js.map +0 -1
  335. package/dist/id-compressor/uuidUtilities.d.ts +0 -28
  336. package/dist/id-compressor/uuidUtilities.d.ts.map +0 -1
  337. package/dist/id-compressor/uuidUtilities.js +0 -104
  338. package/dist/id-compressor/uuidUtilities.js.map +0 -1
  339. package/lib/id-compressor/idRange.d.ts +0 -11
  340. package/lib/id-compressor/idRange.d.ts.map +0 -1
  341. package/lib/id-compressor/idRange.js +0 -25
  342. package/lib/id-compressor/idRange.js.map +0 -1
  343. package/lib/id-compressor/numericUuid.d.ts +0 -59
  344. package/lib/id-compressor/numericUuid.d.ts.map +0 -1
  345. package/lib/id-compressor/numericUuid.js +0 -315
  346. package/lib/id-compressor/numericUuid.js.map +0 -1
  347. package/lib/id-compressor/sessionIdNormalizer.d.ts +0 -138
  348. package/lib/id-compressor/sessionIdNormalizer.d.ts.map +0 -1
  349. package/lib/id-compressor/sessionIdNormalizer.js +0 -479
  350. package/lib/id-compressor/sessionIdNormalizer.js.map +0 -1
  351. package/lib/id-compressor/utils.d.ts +0 -57
  352. package/lib/id-compressor/utils.d.ts.map +0 -1
  353. package/lib/id-compressor/utils.js +0 -79
  354. package/lib/id-compressor/utils.js.map +0 -1
  355. package/lib/id-compressor/uuidUtilities.d.ts +0 -28
  356. package/lib/id-compressor/uuidUtilities.d.ts.map +0 -1
  357. package/lib/id-compressor/uuidUtilities.js +0 -96
  358. package/lib/id-compressor/uuidUtilities.js.map +0 -1
  359. package/src/id-compressor/idRange.ts +0 -35
  360. package/src/id-compressor/numericUuid.ts +0 -383
  361. package/src/id-compressor/sessionIdNormalizer.ts +0 -609
  362. package/src/id-compressor/utils.ts +0 -114
  363. package/src/id-compressor/uuidUtilities.ts +0 -120
@@ -19,14 +19,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
19
19
  return result;
20
20
  };
21
21
  Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.TombstoneResponseHeaderKey = exports.AllowTombstoneRequestHeaderKey = exports.RuntimeHeaders = exports.DefaultSummaryConfiguration = exports.ContainerMessageType = void 0;
22
+ exports.ContainerRuntime = exports.makeLegacySendBatchFn = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.InactiveResponseHeaderKey = exports.TombstoneResponseHeaderKey = exports.AllowInactiveRequestHeaderKey = exports.AllowTombstoneRequestHeaderKey = exports.RuntimeHeaders = exports.DefaultSummaryConfiguration = exports.ContainerMessageType = void 0;
23
23
  const container_definitions_1 = require("@fluidframework/container-definitions");
24
24
  const common_utils_1 = require("@fluidframework/common-utils");
25
25
  const core_utils_1 = require("@fluidframework/core-utils");
26
26
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
27
27
  const driver_definitions_1 = require("@fluidframework/driver-definitions");
28
28
  const driver_utils_1 = require("@fluidframework/driver-utils");
29
- const container_utils_1 = require("@fluidframework/container-utils");
30
29
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
31
30
  const runtime_definitions_1 = require("@fluidframework/runtime-definitions");
32
31
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
@@ -67,6 +66,18 @@ var ContainerMessageType;
67
66
  */
68
67
  ContainerMessageType["IdAllocation"] = "idAllocation";
69
68
  })(ContainerMessageType = exports.ContainerMessageType || (exports.ContainerMessageType = {}));
69
+ /**
70
+ * Utility to implement compat behaviors given an unknown message type
71
+ * The parameters are typed to support compile-time enforcement of handling all known types/behaviors
72
+ *
73
+ * @param _unknownContainerRuntimeMessageType - Typed as never, to ensure all known types have been
74
+ * handled before calling this function (e.g. in a switch statement).
75
+ * @param compatBehavior - Typed redundantly with CompatModeBehavior to ensure handling is added when updating that type
76
+ */
77
+ function compatBehaviorAllowsMessageType(_unknownContainerRuntimeMessageType, compatBehavior) {
78
+ // undefined defaults to same behavior as "FailToProcess"
79
+ return compatBehavior === "Ignore";
80
+ }
70
81
  exports.DefaultSummaryConfiguration = {
71
82
  state: "enabled",
72
83
  minIdleTime: 0,
@@ -93,8 +104,12 @@ var RuntimeHeaders;
93
104
  })(RuntimeHeaders = exports.RuntimeHeaders || (exports.RuntimeHeaders = {}));
94
105
  /** True if a tombstoned object should be returned without erroring */
95
106
  exports.AllowTombstoneRequestHeaderKey = "allowTombstone"; // Belongs in the enum above, but avoiding the breaking change
107
+ /** [IRRELEVANT IF throwOnInactiveLoad OPTION NOT SET] True if an inactive object should be returned without erroring */
108
+ exports.AllowInactiveRequestHeaderKey = "allowInactive"; // Belongs in the enum above, but avoiding the breaking change
96
109
  /** Tombstone error responses will have this header set to true */
97
110
  exports.TombstoneResponseHeaderKey = "isTombstoned";
111
+ /** Inactive error responses will have this header set to true */
112
+ exports.InactiveResponseHeaderKey = "isInactive";
98
113
  /** Default values for Runtime Headers */
99
114
  exports.defaultRuntimeHeaderData = {
100
115
  wait: true,
@@ -225,34 +240,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
225
240
  signalTimestamp: 0,
226
241
  trackingSignalSequenceNumber: undefined,
227
242
  };
228
- this.summarizeOnDemand = (...args) => {
229
- if (this.isSummarizerClient) {
230
- return this.summarizer.summarizeOnDemand(...args);
231
- }
232
- else if (this.summaryManager !== undefined) {
233
- return this.summaryManager.summarizeOnDemand(...args);
234
- }
235
- else {
236
- // If we're not the summarizer, and we don't have a summaryManager, we expect that
237
- // disableSummaries is turned on. We are throwing instead of returning a failure here,
238
- // because it is a misuse of the API rather than an expected failure.
239
- throw new container_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
240
- }
241
- };
242
- this.enqueueSummarize = (...args) => {
243
- if (this.isSummarizerClient) {
244
- return this.summarizer.enqueueSummarize(...args);
245
- }
246
- else if (this.summaryManager !== undefined) {
247
- return this.summaryManager.enqueueSummarize(...args);
248
- }
249
- else {
250
- // If we're not the summarizer, and we don't have a summaryManager, we expect that
251
- // generateSummaries is turned off. We are throwing instead of returning a failure here,
252
- // because it is a misuse of the API rather than an expected failure.
253
- throw new container_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
254
- }
255
- };
256
243
  const { options, clientDetails, connected, baseSnapshot, submitFn, submitBatchFn, submitSummaryFn, submitSignalFn, disposeFn, closeFn, deltaManager, quorum, audience, loader, pendingLocalState, supportedFeatures, } = context;
257
244
  this.innerDeltaManager = deltaManager;
258
245
  this.deltaManager = new deltaManagerSummarizerProxy_1.DeltaManagerSummarizerProxy(this.innerDeltaManager);
@@ -368,7 +355,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
368
355
  // This is a runtime enforcement of what's already explicit in the policy's type itself,
369
356
  // which dictates the value is either undefined or exactly 5 days in ms.
370
357
  // As long as the actual value is less than 5 days, the assumptions GC makes here are valid.
371
- throw new container_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
358
+ throw new telemetry_utils_1.UsageError("Driver's maximumCacheDurationMs policy cannot exceed 5 days");
372
359
  }
373
360
  this.garbageCollector = gc_1.GarbageCollector.create({
374
361
  runtime: this,
@@ -475,8 +462,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
475
462
  false;
476
463
  this.summaryCollection = new summary_1.SummaryCollection(this.deltaManager, this.logger);
477
464
  this.dirtyContainer =
478
- this.attachState !== container_definitions_1.AttachState.Attached ||
479
- this.pendingStateManager.hasPendingMessages();
465
+ this.attachState !== container_definitions_1.AttachState.Attached || this.hasPendingMessages();
480
466
  context.updateDirtyContainerState(this.dirtyContainer);
481
467
  if (this.summariesDisabled) {
482
468
  this.mc.logger.sendTelemetryEvent({ eventName: "SummariesDisabled" });
@@ -524,6 +510,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
524
510
  (0, throttler_1.formExponentialFn)({ coefficient: 20, initialDelay: 0 })), {
525
511
  initialDelayMs: this.initialSummarizerDelayMs,
526
512
  }, this.heuristicsDisabled);
513
+ this.summaryManager.on("summarize", (eventProps) => {
514
+ this.emit("summarize", eventProps);
515
+ });
527
516
  this.summaryManager.start();
528
517
  }
529
518
  }
@@ -632,11 +621,21 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
632
621
  * This object should provide all the functionality that the Container is expected to provide to the loader layer.
633
622
  */
634
623
  static async loadRuntime(params) {
635
- const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, initializeEntryPoint, } = params;
624
+ const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, } = params;
625
+ const initializeEntryPoint = params.initializeEntryPoint ??
626
+ (async (containerRuntime) => ({
627
+ get IFluidRouter() {
628
+ return this;
629
+ },
630
+ async request(req) {
631
+ return containerRuntime.request(req);
632
+ },
633
+ }));
636
634
  // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
637
635
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
638
636
  const backCompatContext = context;
639
637
  const passLogger = backCompatContext.taggedLogger ??
638
+ // eslint-disable-next-line import/no-deprecated
640
639
  new telemetry_utils_1.TaggedLoggerAdapter(backCompatContext.logger);
641
640
  const logger = (0, telemetry_utils_1.createChildLogger)({
642
641
  logger: passLogger,
@@ -680,7 +679,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
680
679
  if (loadSequenceNumberVerification !== "bypass" &&
681
680
  runtimeSequenceNumber !== protocolSequenceNumber) {
682
681
  // "Load from summary, runtime metadata sequenceNumber !== initialSequenceNumber"
683
- const error = new container_utils_1.DataCorruptionError(
682
+ const error = new telemetry_utils_1.DataCorruptionError(
684
683
  // pre-0.58 error message: SummaryMetadataMismatch
685
684
  "Summary metadata mismatch", { runtimeVersion: packageVersion_1.pkgVersion, runtimeSequenceNumber, protocolSequenceNumber });
686
685
  if (loadSequenceNumberVerification === "log") {
@@ -698,7 +697,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
698
697
  idCompressor =
699
698
  serializedIdCompressor !== undefined
700
699
  ? IdCompressor.deserialize(serializedIdCompressor, createSessionId())
701
- : new IdCompressor(createSessionId(), logger);
700
+ : IdCompressor.create(logger);
702
701
  }
703
702
  const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks ?? [], aliases ?? [], {
704
703
  summaryOptions,
@@ -713,6 +712,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
713
712
  enableGroupedBatching,
714
713
  }, containerScope, logger, existing, blobManagerSnapshot, context.storage, idCompressor, requestHandler, undefined, // summaryConfiguration
715
714
  initializeEntryPoint);
715
+ await runtime.blobManager.processStashedChanges();
716
716
  // It's possible to have ops with a reference sequence number of 0. Op sequence numbers start
717
717
  // at 1, so we won't see a replayed saved op with a sequence number of 0.
718
718
  await runtime.pendingStateManager.applyStashedOpsAt(0);
@@ -729,6 +729,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
729
729
  /** @deprecated - The functionality is no longer exposed publicly */
730
730
  get reSubmitFn() {
731
731
  return (type, contents, localOpMetadata, opMetadata) => this.reSubmitCore({ type, contents }, localOpMetadata, opMetadata);
732
+ // Note: compatDetails is not included in this deprecated API
732
733
  }
733
734
  get flushMode() {
734
735
  return this._flushMode;
@@ -879,7 +880,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
879
880
  // We always expect createSubRequest to include a leading slash, but asserting here to protect against
880
881
  // unintentionally modifying the url if that changes.
881
882
  (0, common_utils_1.assert)(subRequest.url.startsWith("/"), 0x126 /* "Expected createSubRequest url to include a leading slash" */);
882
- return dataStore.IFluidRouter.request(subRequest);
883
+ return dataStore.request(subRequest);
883
884
  }
884
885
  return (0, runtime_utils_1.create404Response)(request);
885
886
  }
@@ -987,7 +988,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
987
988
  this.mc.logger.sendTelemetryEvent({
988
989
  eventName: "ReconnectsWithNoProgress",
989
990
  attempts: this.consecutiveReconnects,
990
- pendingMessages: this.pendingStateManager.pendingMessagesCount,
991
+ pendingMessages: this.pendingMessagesCount,
991
992
  });
992
993
  }
993
994
  return this.consecutiveReconnects < this.maxConsecutiveReconnects;
@@ -1047,13 +1048,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1047
1048
  */
1048
1049
  parseOpContent(serializedContent) {
1049
1050
  (0, common_utils_1.assert)(serializedContent !== undefined, 0x6d5 /* content must be defined */);
1050
- const { type, contents } = JSON.parse(serializedContent);
1051
+ const { type, contents, compatDetails } = JSON.parse(serializedContent);
1051
1052
  (0, common_utils_1.assert)(type !== undefined, 0x6d6 /* incorrect op content format */);
1052
- return { type, contents };
1053
+ return { type, contents, compatDetails };
1053
1054
  }
1054
1055
  async applyStashedOp(op) {
1055
1056
  // Need to parse from string for back-compat
1056
- const { type, contents } = this.parseOpContent(op);
1057
+ const { type, contents, compatDetails } = this.parseOpContent(op);
1057
1058
  switch (type) {
1058
1059
  case ContainerMessageType.FluidDataStoreOp:
1059
1060
  return this.dataStores.applyStashedOp(contents);
@@ -1069,8 +1070,22 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1069
1070
  throw new Error("chunkedOp not expected here");
1070
1071
  case ContainerMessageType.Rejoin:
1071
1072
  throw new Error("rejoin not expected here");
1072
- default:
1073
- (0, common_utils_1.unreachableCase)(type, `Unknown ContainerMessageType: ${type}`);
1073
+ default: {
1074
+ // This should be extremely rare for stashed ops.
1075
+ // It would require a newer runtime stashing ops and then an older one applying them,
1076
+ // e.g. if an app rolled back its container version
1077
+ const compatBehavior = compatDetails?.behavior;
1078
+ if (!compatBehaviorAllowsMessageType(type, compatBehavior)) {
1079
+ const error = telemetry_utils_1.DataProcessingError.create("Stashed runtime message of unknown type", "applyStashedOp", undefined /* sequencedMessage */, {
1080
+ messageDetails: JSON.stringify({
1081
+ type,
1082
+ compatBehavior,
1083
+ }),
1084
+ });
1085
+ this.closeFn(error);
1086
+ throw error;
1087
+ }
1088
+ }
1074
1089
  }
1075
1090
  }
1076
1091
  setConnectionState(connected, clientId) {
@@ -1082,24 +1097,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1082
1097
  // Don't propagate "disconnected" event because we didn't propagate the previous "connected" event
1083
1098
  return;
1084
1099
  }
1085
- // If attachment blobs were added while disconnected, we need to delay
1086
- // propagation of the "connected" event until we have uploaded them to
1087
- // ensure we don't submit ops referencing a blob that has not been uploaded
1088
- // Note that the inner (non-proxy) delta manager is needed here to get the readonly information.
1089
- const connecting = connected && !this._connected && !this.innerDeltaManager.readOnlyInfo.readonly;
1090
- if (connecting && this.blobManager.hasPendingOfflineUploads) {
1091
- (0, common_utils_1.assert)(!this.delayConnectClientId, 0x392 /* Connect event delay must be canceled before subsequent connect event */);
1092
- (0, common_utils_1.assert)(!!clientId, 0x393 /* Must have clientId when connecting */);
1093
- this.delayConnectClientId = clientId;
1094
- this.blobManager.onConnected().then(() => {
1095
- // make sure we didn't reconnect before the promise resolved
1096
- if (this.delayConnectClientId === clientId && !this.disposed) {
1097
- this.delayConnectClientId = undefined;
1098
- this.setConnectionStateCore(connected, clientId);
1099
- }
1100
- }, (error) => this.closeFn(error));
1101
- return;
1102
- }
1103
1100
  this.setConnectionStateCore(connected, clientId);
1104
1101
  }
1105
1102
  setConnectionStateCore(connected, clientId) {
@@ -1127,10 +1124,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1127
1124
  if (reconnection) {
1128
1125
  this.consecutiveReconnects++;
1129
1126
  if (!this.shouldContinueReconnecting()) {
1130
- this.closeFn(container_utils_1.DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.", "setConnectionState", undefined, {
1127
+ this.closeFn(telemetry_utils_1.DataProcessingError.create("Runtime detected too many reconnects with no progress syncing local ops.", "setConnectionState", undefined, {
1131
1128
  dataLoss: 1,
1132
1129
  attempts: this.consecutiveReconnects,
1133
- pendingMessages: this.pendingStateManager.pendingMessagesCount,
1130
+ pendingMessages: this.pendingMessagesCount,
1134
1131
  }));
1135
1132
  return;
1136
1133
  }
@@ -1147,23 +1144,23 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1147
1144
  }
1148
1145
  process(messageArg, local) {
1149
1146
  this.verifyNotClosed();
1150
- // Whether or not the message is actually a runtime message.
1147
+ // Whether or not the message appears to be a runtime message from an up-to-date client.
1151
1148
  // It may be a legacy runtime message (ie already unpacked and ContainerMessageType)
1152
1149
  // or something different, like a system message.
1153
- const runtimeMessage = messageArg.type === protocol_definitions_1.MessageType.Operation;
1150
+ const modernRuntimeMessage = messageArg.type === protocol_definitions_1.MessageType.Operation;
1154
1151
  // Do shallow copy of message, as the processing flow will modify it.
1155
1152
  const messageCopy = { ...messageArg };
1156
1153
  for (const message of this.remoteMessageProcessor.process(messageCopy)) {
1157
- this.processCore(message, local, runtimeMessage);
1154
+ this.processCore(message, local, modernRuntimeMessage);
1158
1155
  }
1159
1156
  }
1160
1157
  /**
1161
1158
  * Direct the message to the correct subsystem for processing, and implement other side effects
1162
1159
  * @param message - The unpacked message. Likely a ContainerRuntimeMessage, but could also be a system op
1163
1160
  * @param local - Did this client send the op?
1164
- * @param runtimeMessage - Does this appear like a current ContainerRuntimeMessage? If true, certain validation will occur.
1161
+ * @param modernRuntimeMessage - Does this appear like a current ContainerRuntimeMessage?
1165
1162
  */
1166
- processCore(message, local, runtimeMessage) {
1163
+ processCore(message, local, modernRuntimeMessage) {
1167
1164
  // Surround the actual processing of the operation with messages to the schedule manager indicating
1168
1165
  // the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
1169
1166
  // messages once a batch has been fully processed.
@@ -1171,7 +1168,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1171
1168
  this._processedClientSequenceNumber = message.clientSequenceNumber;
1172
1169
  try {
1173
1170
  let localOpMetadata;
1174
- if (local && runtimeMessage && message.type !== ContainerMessageType.ChunkedOp) {
1171
+ if (local && modernRuntimeMessage && message.type !== ContainerMessageType.ChunkedOp) {
1175
1172
  localOpMetadata = this.pendingStateManager.processPendingLocalMessage(message);
1176
1173
  }
1177
1174
  // If there are no more pending messages after processing a local message,
@@ -1179,43 +1176,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1179
1176
  if (!this.hasPendingMessages()) {
1180
1177
  this.updateDocumentDirtyState(false);
1181
1178
  }
1182
- const type = message.type;
1183
- switch (type) {
1184
- case ContainerMessageType.Attach:
1185
- this.dataStores.processAttachMessage(message, local);
1186
- break;
1187
- case ContainerMessageType.Alias:
1188
- this.processAliasMessage(message, localOpMetadata, local);
1189
- break;
1190
- case ContainerMessageType.FluidDataStoreOp:
1191
- this.dataStores.processFluidDataStoreOp(message, local, localOpMetadata);
1192
- break;
1193
- case ContainerMessageType.BlobAttach:
1194
- this.blobManager.processBlobAttachOp(message, local);
1195
- break;
1196
- case ContainerMessageType.IdAllocation:
1197
- (0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67c /* IdCompressor should be defined if enabled */);
1198
- this.idCompressor.finalizeCreationRange(message.contents);
1199
- break;
1200
- case ContainerMessageType.ChunkedOp:
1201
- case ContainerMessageType.Rejoin:
1202
- break;
1203
- default:
1204
- if (runtimeMessage) {
1205
- const error = container_utils_1.DataProcessingError.create(
1206
- // Former assert 0x3ce
1207
- "Runtime message of unknown type", "OpProcessing", message, {
1208
- local,
1209
- type: message.type,
1210
- contentType: typeof message.contents,
1211
- batch: message.metadata?.batch,
1212
- compression: message.compression,
1213
- });
1214
- this.closeFn(error);
1215
- throw error;
1216
- }
1217
- }
1218
- this.emit("op", message, runtimeMessage);
1179
+ this.validateAndProcessRuntimeMessage(message, localOpMetadata, local, modernRuntimeMessage);
1180
+ this.emit("op", message, modernRuntimeMessage);
1219
1181
  this.scheduleManager.afterOpProcessing(undefined, message);
1220
1182
  if (local) {
1221
1183
  // If we have processed a local op, this means that the container is
@@ -1229,8 +1191,59 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1229
1191
  throw e;
1230
1192
  }
1231
1193
  }
1232
- processAliasMessage(message, localOpMetadata, local) {
1233
- this.dataStores.processAliasMessage(message, localOpMetadata, local);
1194
+ /**
1195
+ * Assuming the given message is also a ContainerRuntimeMessage,
1196
+ * checks its type and dispatches the message to the appropriate handler in the runtime.
1197
+ * Throws a DataProcessingError if the message doesn't conform to the ContainerRuntimeMessage type.
1198
+ */
1199
+ validateAndProcessRuntimeMessage(message, localOpMetadata, local, expectRuntimeMessageType) {
1200
+ // Optimistically extract ContainerRuntimeMessage-specific props from the message
1201
+ const { type: maybeContainerMessageType, compatDetails } = message;
1202
+ switch (maybeContainerMessageType) {
1203
+ case ContainerMessageType.Attach:
1204
+ this.dataStores.processAttachMessage(message, local);
1205
+ break;
1206
+ case ContainerMessageType.Alias:
1207
+ this.dataStores.processAliasMessage(message, localOpMetadata, local);
1208
+ break;
1209
+ case ContainerMessageType.FluidDataStoreOp:
1210
+ this.dataStores.processFluidDataStoreOp(message, local, localOpMetadata);
1211
+ break;
1212
+ case ContainerMessageType.BlobAttach:
1213
+ this.blobManager.processBlobAttachOp(message, local);
1214
+ break;
1215
+ case ContainerMessageType.IdAllocation:
1216
+ (0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67c /* IdCompressor should be defined if enabled */);
1217
+ this.idCompressor.finalizeCreationRange(message.contents);
1218
+ break;
1219
+ case ContainerMessageType.ChunkedOp:
1220
+ case ContainerMessageType.Rejoin:
1221
+ break;
1222
+ default: {
1223
+ // If we didn't necessarily expect a runtime message type, then no worries - just return
1224
+ // e.g. this case applies to system ops, or legacy ops that would have fallen into the above cases anyway.
1225
+ if (!expectRuntimeMessageType) {
1226
+ return;
1227
+ }
1228
+ const compatBehavior = compatDetails?.behavior;
1229
+ if (!compatBehaviorAllowsMessageType(maybeContainerMessageType, compatBehavior)) {
1230
+ const error = telemetry_utils_1.DataProcessingError.create(
1231
+ // Former assert 0x3ce
1232
+ "Runtime message of unknown type", "OpProcessing", message, {
1233
+ local,
1234
+ messageDetails: JSON.stringify({
1235
+ type: message.type,
1236
+ contentType: typeof message.contents,
1237
+ compatBehavior,
1238
+ batch: message.metadata?.batch,
1239
+ compression: message.compression,
1240
+ }),
1241
+ });
1242
+ this.closeFn(error);
1243
+ throw error;
1244
+ }
1245
+ }
1246
+ }
1234
1247
  }
1235
1248
  /**
1236
1249
  * Emits the Signal event and update the perf signal data.
@@ -1331,7 +1344,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1331
1344
  }
1332
1345
  catch (err) {
1333
1346
  const error2 = (0, telemetry_utils_1.wrapError)(err, (message) => {
1334
- return container_utils_1.DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
1347
+ return telemetry_utils_1.DataProcessingError.create(`RollbackError: ${message}`, "checkpointRollback", undefined);
1335
1348
  });
1336
1349
  this.closeFn(error2);
1337
1350
  throw error2;
@@ -1339,7 +1352,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1339
1352
  }
1340
1353
  else {
1341
1354
  // pre-0.58 error message: orderSequentiallyCallbackException
1342
- this.closeFn(new container_utils_1.GenericError("orderSequentially callback exception", error));
1355
+ this.closeFn(new telemetry_utils_1.GenericError("orderSequentially callback exception", error));
1343
1356
  }
1344
1357
  throw error; // throw the original error for the consumer of the runtime
1345
1358
  }
@@ -1368,13 +1381,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1368
1381
  }
1369
1382
  const channel = await context.realize();
1370
1383
  if (channel.entryPoint === undefined) {
1371
- throw new container_utils_1.UsageError("entryPoint must be defined on data store runtime for using getAliasedDataStoreEntryPoint");
1384
+ throw new telemetry_utils_1.UsageError("entryPoint must be defined on data store runtime for using getAliasedDataStoreEntryPoint");
1372
1385
  }
1373
1386
  return channel.entryPoint;
1374
1387
  }
1375
1388
  createDetachedRootDataStore(pkg, rootDataStoreId) {
1376
1389
  if (rootDataStoreId.includes("/")) {
1377
- throw new container_utils_1.UsageError(`Id cannot contain slashes: '${rootDataStoreId}'`);
1390
+ throw new telemetry_utils_1.UsageError(`Id cannot contain slashes: '${rootDataStoreId}'`);
1378
1391
  }
1379
1392
  return this.dataStores.createDetachedDataStoreCore(pkg, true, rootDataStoreId);
1380
1393
  }
@@ -1698,7 +1711,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1698
1711
  * @param options - options controlling how the summary is generated or submitted
1699
1712
  */
1700
1713
  async submitSummary(options) {
1701
- const { fullTree = false, refreshLatestAck, summaryLogger } = options;
1714
+ const { fullTree = false, finalAttempt = false, refreshLatestAck, summaryLogger } = options;
1702
1715
  // The summary number for this summary. This will be updated during the summary process, so get it now and
1703
1716
  // use it for all events logged during this summary.
1704
1717
  const summaryNumber = this.nextSummaryNumber;
@@ -1795,9 +1808,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1795
1808
  error,
1796
1809
  };
1797
1810
  }
1798
- // If validateSummaryBeforeUpload is true, validate that the summary generated by the summarizer nodes is
1799
- // correct before this summary is uploaded.
1811
+ // If validateSummaryBeforeUpload is true, validate that the summary generated is correct before uploading.
1800
1812
  if (this.validateSummaryBeforeUpload) {
1813
+ // Validate that the summaries generated by summarize nodes is correct.
1801
1814
  const validateResult = this.summarizerNode.validateSummary();
1802
1815
  if (!validateResult.success) {
1803
1816
  const { success, ...loggingProps } = validateResult;
@@ -1809,6 +1822,34 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1809
1822
  error,
1810
1823
  };
1811
1824
  }
1825
+ // If there are pending messages, the summary has more data than at the summaryRefSeqNum.
1826
+ if (this.hasPendingMessages()) {
1827
+ // If "SkipFailingIncorrectSummary" option is true, don't fail the summary in the last attempt.
1828
+ // This is a fallback to make progress in documents where there are consistently pending ops in
1829
+ // the summarizer.
1830
+ if (finalAttempt &&
1831
+ this.mc.config.getBoolean("Fluid.Summarizer.SkipFailingIncorrectSummary")) {
1832
+ const error = telemetry_utils_1.DataProcessingError.create("Pending ops during summarization", "submitSummary", undefined, { pendingMessages: this.pendingMessagesCount });
1833
+ summaryNumberLogger.sendErrorEvent({
1834
+ eventName: "SkipFailingIncorrectSummary",
1835
+ referenceSequenceNumber: summaryRefSeqNum,
1836
+ minimumSequenceNumber,
1837
+ }, error);
1838
+ }
1839
+ else {
1840
+ // Default retry delay is 1 second. This can be overridden via config so that we can adjust it
1841
+ // based on telemetry while we decide on a stable number.
1842
+ const retryDelayMs = this.mc.config.getNumber("Fluid.Summarizer.PendingOpsRetryDelayMs") ??
1843
+ 1000;
1844
+ const error = new summary_1.RetriableSummaryError("PendingMessagesInSummary", retryDelayMs / 1000, { count: this.pendingMessagesCount });
1845
+ return {
1846
+ stage: "base",
1847
+ referenceSequenceNumber: summaryRefSeqNum,
1848
+ minimumSequenceNumber,
1849
+ error,
1850
+ };
1851
+ }
1852
+ }
1812
1853
  }
1813
1854
  const { summary: summaryTree, stats: partialStats } = summarizeResult;
1814
1855
  // Now that we have generated the summary, update the message at last summary to the last message processed.
@@ -1929,8 +1970,11 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1929
1970
  }
1930
1971
  }
1931
1972
  }
1973
+ get pendingMessagesCount() {
1974
+ return this.pendingStateManager.pendingMessagesCount + this.outbox.messageCount;
1975
+ }
1932
1976
  hasPendingMessages() {
1933
- return this.pendingStateManager.hasPendingMessages() || !this.outbox.isEmpty;
1977
+ return this.pendingMessagesCount !== 0;
1934
1978
  }
1935
1979
  updateDocumentDirtyState(dirty) {
1936
1980
  if (this.attachState !== container_definitions_1.AttachState.Attached) {
@@ -1958,7 +2002,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1958
2002
  submitDataStoreAliasOp(contents, localOpMetadata) {
1959
2003
  const aliasMessage = contents;
1960
2004
  if (!(0, dataStore_1.isDataStoreAliasMessage)(aliasMessage)) {
1961
- throw new container_utils_1.UsageError("malformedDataStoreAliasMessage");
2005
+ throw new telemetry_utils_1.UsageError("malformedDataStoreAliasMessage");
1962
2006
  }
1963
2007
  this.submit({ type: ContainerMessageType.Alias, contents }, localOpMetadata);
1964
2008
  }
@@ -1974,7 +2018,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1974
2018
  (0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67d /* IdCompressor should be defined if enabled */);
1975
2019
  idRange = this.idCompressor.takeNextCreationRange();
1976
2020
  // Don't include the idRange if there weren't any Ids allocated
1977
- idRange = idRange?.ids?.first !== undefined ? idRange : undefined;
2021
+ idRange = idRange?.ids !== undefined ? idRange : undefined;
1978
2022
  }
1979
2023
  if (idRange !== undefined) {
1980
2024
  const idAllocationMessage = {
@@ -2127,7 +2171,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2127
2171
  if (this.opReentryCallsToReport > 0) {
2128
2172
  this.mc.logger.sendTelemetryEvent({ eventName: "OpReentry" },
2129
2173
  // We need to capture the call stack in order to inspect the source of this usage pattern
2130
- (0, opLifecycle_1.getLongStack)(() => new container_utils_1.UsageError(errorMessage)));
2174
+ (0, opLifecycle_1.getLongStack)(() => new telemetry_utils_1.UsageError(errorMessage)));
2131
2175
  this.opReentryCallsToReport--;
2132
2176
  }
2133
2177
  // Creating ops while processing ops can lead
@@ -2143,7 +2187,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2143
2187
  // The runtime must enforce op coherence by not allowing ops to be submitted
2144
2188
  // while ops are being processed.
2145
2189
  if (this.enableOpReentryCheck) {
2146
- throw new container_utils_1.UsageError(errorMessage);
2190
+ throw new telemetry_utils_1.UsageError(errorMessage);
2147
2191
  }
2148
2192
  }
2149
2193
  }
@@ -2193,8 +2237,27 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2193
2237
  case ContainerMessageType.Rejoin:
2194
2238
  this.submit(message);
2195
2239
  break;
2196
- default:
2197
- (0, common_utils_1.unreachableCase)(message.type, `Unknown ContainerMessageType [type: ${message.type}]`);
2240
+ default: {
2241
+ // This case should be very rare - it would imply an op was stashed from a
2242
+ // future version of runtime code and now is being applied on an older version
2243
+ const compatBehavior = message.compatDetails?.behavior;
2244
+ if (compatBehaviorAllowsMessageType(message.type, compatBehavior)) {
2245
+ this.logger.sendTelemetryEvent({
2246
+ eventName: "resubmitUnrecognizedMessageTypeAllowed",
2247
+ messageDetails: { type: message.type, compatBehavior },
2248
+ });
2249
+ }
2250
+ else {
2251
+ const error = telemetry_utils_1.DataProcessingError.create("Resubmitting runtime message of unknown type", "reSubmitCore", undefined /* sequencedMessage */, {
2252
+ messageDetails: JSON.stringify({
2253
+ type: message.type,
2254
+ compatBehavior,
2255
+ }),
2256
+ });
2257
+ this.closeFn(error);
2258
+ throw error;
2259
+ }
2260
+ }
2198
2261
  }
2199
2262
  }
2200
2263
  rollback(content, localOpMetadata) {
@@ -2207,6 +2270,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2207
2270
  this.dataStores.rollbackDataStoreOp(contents, localOpMetadata);
2208
2271
  break;
2209
2272
  default:
2273
+ // Don't check message.compatDetails because this is for rolling back a local op so the type will be known
2210
2274
  throw new Error(`Can't rollback ${type}`);
2211
2275
  }
2212
2276
  }
@@ -2229,11 +2293,11 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2229
2293
  // It should only be done by the summarizerNode, if required.
2230
2294
  // When fetching from storage we will always get the latest version and do not use the ackHandle.
2231
2295
  const fetchLatestSnapshot = async () => {
2232
- let fetchResult = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
2296
+ let fetchResult = await this.fetchSnapshotFromStorageAndMaybeClose(summaryLogger, {
2233
2297
  eventName: "RefreshLatestSummaryAckFetch",
2234
2298
  ackHandle,
2235
2299
  targetSequenceNumber: summaryRefSeq,
2236
- }, readAndParseBlob);
2300
+ }, readAndParseBlob, null);
2237
2301
  /**
2238
2302
  * back-compat - Older loaders and drivers (pre 2.0.0-internal.1.4) don't have fetchSource as a param in the
2239
2303
  * getVersions API. So, they will not fetch the latest snapshot from network in the previous fetch call. For
@@ -2241,7 +2305,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2241
2305
  * change that started fetching latest snapshot always.
2242
2306
  */
2243
2307
  if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
2244
- fetchResult = await this.fetchSnapshotFromStorageAndClose(summaryLogger, {
2308
+ fetchResult = await this.fetchSnapshotFromStorageAndMaybeClose(summaryLogger, {
2245
2309
  eventName: "RefreshLatestSummaryAckFetchBackCompat",
2246
2310
  ackHandle,
2247
2311
  targetSequenceNumber: summaryRefSeq,
@@ -2258,7 +2322,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2258
2322
  * state.
2259
2323
  */
2260
2324
  if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
2261
- const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
2325
+ const error = telemetry_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
2262
2326
  ackHandle,
2263
2327
  summaryRefSeq,
2264
2328
  fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
@@ -2286,9 +2350,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2286
2350
  */
2287
2351
  async refreshLatestSummaryAckFromServer(summaryLogger) {
2288
2352
  const readAndParseBlob = async (id) => (0, driver_utils_1.readAndParse)(this.storage, id);
2289
- const { snapshotTree, versionId, latestSnapshotRefSeq } = await this.fetchLatestSnapshotFromStorage(summaryLogger, {
2353
+ const { snapshotTree, versionId, latestSnapshotRefSeq } = await this.fetchSnapshotFromStorageAndMaybeClose(summaryLogger, {
2290
2354
  eventName: "RefreshLatestSummaryFromServerFetch",
2291
- }, readAndParseBlob);
2355
+ }, readAndParseBlob, null);
2292
2356
  const fetchLatestSnapshot = {
2293
2357
  snapshotTree,
2294
2358
  snapshotRefSeq: latestSnapshotRefSeq,
@@ -2298,10 +2362,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2298
2362
  await this.garbageCollector.refreshLatestSummary(undefined /* proposalHandle */, result, readAndParseBlob);
2299
2363
  return { latestSnapshotRefSeq, latestSnapshotVersionId: versionId };
2300
2364
  }
2301
- async fetchLatestSnapshotFromStorage(logger, event, readAndParseBlob) {
2302
- return this.fetchSnapshotFromStorageAndClose(logger, event, readAndParseBlob, null /* latest */);
2303
- }
2304
- async fetchSnapshotFromStorageAndClose(logger, event, readAndParseBlob, versionId) {
2365
+ /**
2366
+ * Downloads snapshot from storage with the given versionId or latest if versionId is null.
2367
+ * By default, it also closes the container after downloading the snapshot. However, this may be
2368
+ * overridden via options.
2369
+ */
2370
+ async fetchSnapshotFromStorageAndMaybeClose(logger, event, readAndParseBlob, versionId) {
2305
2371
  const snapshotResults = await telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
2306
2372
  const stats = {};
2307
2373
  const trace = common_utils_1.Trace.start();
@@ -2332,7 +2398,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2332
2398
  message: "Stopping fetch from storage",
2333
2399
  versionId: versionId != null ? versionId : undefined,
2334
2400
  closeSummarizerDelayMs: this.closeSummarizerDelayMs,
2335
- }, new container_utils_1.GenericError("Restarting summarizer instead of refreshing"));
2401
+ }, new telemetry_utils_1.GenericError("Restarting summarizer instead of refreshing"));
2336
2402
  // Delay before restarting summarizer to prevent the summarizer from restarting too frequently.
2337
2403
  await (0, common_utils_1.delay)(this.closeSummarizerDelayMs);
2338
2404
  this._summarizer?.stop("latestSummaryStateStale");
@@ -2345,17 +2411,49 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2345
2411
  this.verifyNotClosed();
2346
2412
  const waitBlobsToAttach = props?.notifyImminentClosure;
2347
2413
  if (this._orderSequentiallyCalls !== 0) {
2348
- throw new container_utils_1.UsageError("can't get state during orderSequentially");
2414
+ throw new telemetry_utils_1.UsageError("can't get state during orderSequentially");
2349
2415
  }
2350
2416
  const pendingAttachmentBlobs = await this.blobManager.getPendingBlobs(waitBlobsToAttach);
2417
+ if (!pendingAttachmentBlobs && !this.hasPendingMessages()) {
2418
+ return; // no pending state to save
2419
+ }
2351
2420
  // Flush pending batch.
2352
2421
  // getPendingLocalState() is only exposed through Container.closeAndGetPendingLocalState(), so it's safe
2353
2422
  // to close current batch.
2354
2423
  this.flush();
2355
- return {
2424
+ const pendingState = {
2356
2425
  pending: this.pendingStateManager.getLocalState(),
2357
2426
  pendingAttachmentBlobs,
2358
2427
  };
2428
+ return pendingState;
2429
+ }
2430
+ summarizeOnDemand(options) {
2431
+ if (this.isSummarizerClient) {
2432
+ return this.summarizer.summarizeOnDemand(options);
2433
+ }
2434
+ else if (this.summaryManager !== undefined) {
2435
+ return this.summaryManager.summarizeOnDemand(options);
2436
+ }
2437
+ else {
2438
+ // If we're not the summarizer, and we don't have a summaryManager, we expect that
2439
+ // disableSummaries is turned on. We are throwing instead of returning a failure here,
2440
+ // because it is a misuse of the API rather than an expected failure.
2441
+ throw new telemetry_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
2442
+ }
2443
+ }
2444
+ enqueueSummarize(options) {
2445
+ if (this.isSummarizerClient) {
2446
+ return this.summarizer.enqueueSummarize(options);
2447
+ }
2448
+ else if (this.summaryManager !== undefined) {
2449
+ return this.summaryManager.enqueueSummarize(options);
2450
+ }
2451
+ else {
2452
+ // If we're not the summarizer, and we don't have a summaryManager, we expect that
2453
+ // generateSummaries is turned off. We are throwing instead of returning a failure here,
2454
+ // because it is a misuse of the API rather than an expected failure.
2455
+ throw new telemetry_utils_1.UsageError(`Can't summarize, disableSummaries: ${this.summariesDisabled}`);
2456
+ }
2359
2457
  }
2360
2458
  /**
2361
2459
  * * Forms a function that will request a Summarizer.
@@ -2378,7 +2476,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2378
2476
  const fluidObject = await (0, runtime_utils_1.requestFluidObject)(loaderRouter, request);
2379
2477
  const summarizer = fluidObject.ISummarizer;
2380
2478
  if (!summarizer) {
2381
- throw new container_utils_1.UsageError("Fluid object does not implement ISummarizer");
2479
+ throw new telemetry_utils_1.UsageError("Fluid object does not implement ISummarizer");
2382
2480
  }
2383
2481
  return summarizer;
2384
2482
  };
@@ -2387,11 +2485,11 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2387
2485
  // eslint-disable-next-line no-restricted-syntax
2388
2486
  for (const prop in configuration) {
2389
2487
  if (typeof configuration[prop] === "number" && configuration[prop] < 0) {
2390
- throw new container_utils_1.UsageError(`Summary heuristic configuration property "${prop}" cannot be less than 0`);
2488
+ throw new telemetry_utils_1.UsageError(`Summary heuristic configuration property "${prop}" cannot be less than 0`);
2391
2489
  }
2392
2490
  }
2393
2491
  if (configuration.minIdleTime > configuration.maxIdleTime) {
2394
- throw new container_utils_1.UsageError(`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`);
2492
+ throw new telemetry_utils_1.UsageError(`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`);
2395
2493
  }
2396
2494
  }
2397
2495
  get groupedBatchingEnabled() {