@fluidframework/container-runtime 2.0.0-dev.4.1.0.148229 → 2.0.0-dev.4.3.0.157531

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 (314) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +69 -0
  3. package/dist/blobManager.d.ts +6 -14
  4. package/dist/blobManager.d.ts.map +1 -1
  5. package/dist/blobManager.js +50 -37
  6. package/dist/blobManager.js.map +1 -1
  7. package/dist/containerRuntime.d.ts +47 -4
  8. package/dist/containerRuntime.d.ts.map +1 -1
  9. package/dist/containerRuntime.js +203 -49
  10. package/dist/containerRuntime.js.map +1 -1
  11. package/dist/dataStoreContext.d.ts +2 -1
  12. package/dist/dataStoreContext.d.ts.map +1 -1
  13. package/dist/dataStoreContext.js +3 -0
  14. package/dist/dataStoreContext.js.map +1 -1
  15. package/dist/dataStores.d.ts +5 -5
  16. package/dist/dataStores.d.ts.map +1 -1
  17. package/dist/dataStores.js +3 -6
  18. package/dist/dataStores.js.map +1 -1
  19. package/dist/gc/garbageCollection.d.ts.map +1 -1
  20. package/dist/gc/garbageCollection.js +5 -5
  21. package/dist/gc/garbageCollection.js.map +1 -1
  22. package/dist/gc/gcConfigs.d.ts.map +1 -1
  23. package/dist/gc/gcConfigs.js +1 -3
  24. package/dist/gc/gcConfigs.js.map +1 -1
  25. package/dist/gc/gcDefinitions.js +1 -1
  26. package/dist/gc/gcDefinitions.js.map +1 -1
  27. package/dist/gc/gcHelpers.d.ts.map +1 -1
  28. package/dist/gc/gcHelpers.js +6 -6
  29. package/dist/gc/gcHelpers.js.map +1 -1
  30. package/dist/id-compressor/appendOnlySortedMap.d.ts +146 -0
  31. package/dist/id-compressor/appendOnlySortedMap.d.ts.map +1 -0
  32. package/dist/id-compressor/appendOnlySortedMap.js +360 -0
  33. package/dist/id-compressor/appendOnlySortedMap.js.map +1 -0
  34. package/dist/id-compressor/idCompressor.d.ts +279 -0
  35. package/dist/id-compressor/idCompressor.d.ts.map +1 -0
  36. package/dist/id-compressor/idCompressor.js +1258 -0
  37. package/dist/id-compressor/idCompressor.js.map +1 -0
  38. package/dist/id-compressor/idRange.d.ts +11 -0
  39. package/dist/id-compressor/idRange.d.ts.map +1 -0
  40. package/dist/id-compressor/idRange.js +29 -0
  41. package/dist/id-compressor/idRange.js.map +1 -0
  42. package/dist/id-compressor/index.d.ts +14 -0
  43. package/dist/id-compressor/index.d.ts.map +1 -0
  44. package/dist/id-compressor/index.js +38 -0
  45. package/dist/id-compressor/index.js.map +1 -0
  46. package/dist/id-compressor/numericUuid.d.ts +59 -0
  47. package/dist/id-compressor/numericUuid.d.ts.map +1 -0
  48. package/dist/id-compressor/numericUuid.js +325 -0
  49. package/dist/id-compressor/numericUuid.js.map +1 -0
  50. package/dist/id-compressor/sessionIdNormalizer.d.ts +138 -0
  51. package/dist/id-compressor/sessionIdNormalizer.d.ts.map +1 -0
  52. package/dist/id-compressor/sessionIdNormalizer.js +488 -0
  53. package/dist/id-compressor/sessionIdNormalizer.js.map +1 -0
  54. package/dist/id-compressor/utils.d.ts +57 -0
  55. package/dist/id-compressor/utils.d.ts.map +1 -0
  56. package/dist/id-compressor/utils.js +90 -0
  57. package/dist/id-compressor/utils.js.map +1 -0
  58. package/dist/id-compressor/uuidUtilities.d.ts +30 -0
  59. package/dist/id-compressor/uuidUtilities.d.ts.map +1 -0
  60. package/dist/id-compressor/uuidUtilities.js +106 -0
  61. package/dist/id-compressor/uuidUtilities.js.map +1 -0
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +5 -1
  65. package/dist/index.js.map +1 -1
  66. package/dist/opLifecycle/batchManager.d.ts +9 -2
  67. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  68. package/dist/opLifecycle/batchManager.js +21 -2
  69. package/dist/opLifecycle/batchManager.js.map +1 -1
  70. package/dist/opLifecycle/index.d.ts +2 -1
  71. package/dist/opLifecycle/index.d.ts.map +1 -1
  72. package/dist/opLifecycle/index.js +3 -1
  73. package/dist/opLifecycle/index.js.map +1 -1
  74. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  75. package/dist/opLifecycle/opDecompressor.js +2 -1
  76. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  77. package/dist/opLifecycle/opGroupingManager.d.ts +14 -0
  78. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -0
  79. package/dist/opLifecycle/opGroupingManager.js +61 -0
  80. package/dist/opLifecycle/opGroupingManager.js.map +1 -0
  81. package/dist/opLifecycle/opSplitter.d.ts +1 -1
  82. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  83. package/dist/opLifecycle/opSplitter.js +5 -6
  84. package/dist/opLifecycle/opSplitter.js.map +1 -1
  85. package/dist/opLifecycle/outbox.d.ts +4 -2
  86. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  87. package/dist/opLifecycle/outbox.js +37 -25
  88. package/dist/opLifecycle/outbox.js.map +1 -1
  89. package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -2
  90. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  91. package/dist/opLifecycle/remoteMessageProcessor.js +30 -20
  92. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  93. package/dist/packageVersion.d.ts +1 -1
  94. package/dist/packageVersion.js +1 -1
  95. package/dist/packageVersion.js.map +1 -1
  96. package/dist/pendingStateManager.d.ts +1 -1
  97. package/dist/pendingStateManager.d.ts.map +1 -1
  98. package/dist/pendingStateManager.js +11 -3
  99. package/dist/pendingStateManager.js.map +1 -1
  100. package/dist/summary/index.d.ts +2 -2
  101. package/dist/summary/index.d.ts.map +1 -1
  102. package/dist/summary/index.js +4 -1
  103. package/dist/summary/index.js.map +1 -1
  104. package/dist/summary/orderedClientElection.d.ts +1 -0
  105. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  106. package/dist/summary/orderedClientElection.js +19 -0
  107. package/dist/summary/orderedClientElection.js.map +1 -1
  108. package/dist/summary/runningSummarizer.d.ts +4 -3
  109. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  110. package/dist/summary/runningSummarizer.js +65 -66
  111. package/dist/summary/runningSummarizer.js.map +1 -1
  112. package/dist/summary/summarizer.d.ts.map +1 -1
  113. package/dist/summary/summarizer.js +1 -5
  114. package/dist/summary/summarizer.js.map +1 -1
  115. package/dist/summary/summarizerHeuristics.d.ts +1 -0
  116. package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
  117. package/dist/summary/summarizerHeuristics.js +3 -0
  118. package/dist/summary/summarizerHeuristics.js.map +1 -1
  119. package/dist/summary/summarizerNode/summarizerNode.js +1 -1
  120. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  121. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +128 -2
  122. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  123. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +4 -3
  124. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  125. package/dist/summary/summarizerTypes.d.ts +14 -2
  126. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  127. package/dist/summary/summarizerTypes.js.map +1 -1
  128. package/dist/summary/summaryFormat.d.ts +3 -0
  129. package/dist/summary/summaryFormat.d.ts.map +1 -1
  130. package/dist/summary/summaryFormat.js +3 -1
  131. package/dist/summary/summaryFormat.js.map +1 -1
  132. package/dist/summary/summaryGenerator.d.ts +28 -2
  133. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  134. package/dist/summary/summaryGenerator.js +19 -16
  135. package/dist/summary/summaryGenerator.js.map +1 -1
  136. package/dist/summary/summaryManager.d.ts.map +1 -1
  137. package/dist/summary/summaryManager.js +2 -0
  138. package/dist/summary/summaryManager.js.map +1 -1
  139. package/lib/blobManager.d.ts +6 -14
  140. package/lib/blobManager.d.ts.map +1 -1
  141. package/lib/blobManager.js +50 -37
  142. package/lib/blobManager.js.map +1 -1
  143. package/lib/containerRuntime.d.ts +47 -4
  144. package/lib/containerRuntime.d.ts.map +1 -1
  145. package/lib/containerRuntime.js +187 -52
  146. package/lib/containerRuntime.js.map +1 -1
  147. package/lib/dataStoreContext.d.ts +2 -1
  148. package/lib/dataStoreContext.d.ts.map +1 -1
  149. package/lib/dataStoreContext.js +3 -0
  150. package/lib/dataStoreContext.js.map +1 -1
  151. package/lib/dataStores.d.ts +5 -5
  152. package/lib/dataStores.d.ts.map +1 -1
  153. package/lib/dataStores.js +3 -6
  154. package/lib/dataStores.js.map +1 -1
  155. package/lib/gc/garbageCollection.d.ts.map +1 -1
  156. package/lib/gc/garbageCollection.js +5 -5
  157. package/lib/gc/garbageCollection.js.map +1 -1
  158. package/lib/gc/gcConfigs.d.ts.map +1 -1
  159. package/lib/gc/gcConfigs.js +1 -3
  160. package/lib/gc/gcConfigs.js.map +1 -1
  161. package/lib/gc/gcDefinitions.js +1 -1
  162. package/lib/gc/gcDefinitions.js.map +1 -1
  163. package/lib/gc/gcHelpers.d.ts.map +1 -1
  164. package/lib/gc/gcHelpers.js +6 -6
  165. package/lib/gc/gcHelpers.js.map +1 -1
  166. package/lib/id-compressor/appendOnlySortedMap.d.ts +146 -0
  167. package/lib/id-compressor/appendOnlySortedMap.d.ts.map +1 -0
  168. package/lib/id-compressor/appendOnlySortedMap.js +355 -0
  169. package/lib/id-compressor/appendOnlySortedMap.js.map +1 -0
  170. package/lib/id-compressor/idCompressor.d.ts +279 -0
  171. package/lib/id-compressor/idCompressor.d.ts.map +1 -0
  172. package/lib/id-compressor/idCompressor.js +1248 -0
  173. package/lib/id-compressor/idCompressor.js.map +1 -0
  174. package/lib/id-compressor/idRange.d.ts +11 -0
  175. package/lib/id-compressor/idRange.d.ts.map +1 -0
  176. package/lib/id-compressor/idRange.js +25 -0
  177. package/lib/id-compressor/idRange.js.map +1 -0
  178. package/lib/id-compressor/index.d.ts +14 -0
  179. package/lib/id-compressor/index.d.ts.map +1 -0
  180. package/lib/id-compressor/index.js +14 -0
  181. package/lib/id-compressor/index.js.map +1 -0
  182. package/lib/id-compressor/numericUuid.d.ts +59 -0
  183. package/lib/id-compressor/numericUuid.d.ts.map +1 -0
  184. package/lib/id-compressor/numericUuid.js +315 -0
  185. package/lib/id-compressor/numericUuid.js.map +1 -0
  186. package/lib/id-compressor/sessionIdNormalizer.d.ts +138 -0
  187. package/lib/id-compressor/sessionIdNormalizer.d.ts.map +1 -0
  188. package/lib/id-compressor/sessionIdNormalizer.js +484 -0
  189. package/lib/id-compressor/sessionIdNormalizer.js.map +1 -0
  190. package/lib/id-compressor/utils.d.ts +57 -0
  191. package/lib/id-compressor/utils.d.ts.map +1 -0
  192. package/lib/id-compressor/utils.js +79 -0
  193. package/lib/id-compressor/utils.js.map +1 -0
  194. package/lib/id-compressor/uuidUtilities.d.ts +30 -0
  195. package/lib/id-compressor/uuidUtilities.d.ts.map +1 -0
  196. package/lib/id-compressor/uuidUtilities.js +98 -0
  197. package/lib/id-compressor/uuidUtilities.js.map +1 -0
  198. package/lib/index.d.ts +1 -0
  199. package/lib/index.d.ts.map +1 -1
  200. package/lib/index.js +1 -0
  201. package/lib/index.js.map +1 -1
  202. package/lib/opLifecycle/batchManager.d.ts +9 -2
  203. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  204. package/lib/opLifecycle/batchManager.js +19 -1
  205. package/lib/opLifecycle/batchManager.js.map +1 -1
  206. package/lib/opLifecycle/index.d.ts +2 -1
  207. package/lib/opLifecycle/index.d.ts.map +1 -1
  208. package/lib/opLifecycle/index.js +1 -0
  209. package/lib/opLifecycle/index.js.map +1 -1
  210. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  211. package/lib/opLifecycle/opDecompressor.js +2 -1
  212. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  213. package/lib/opLifecycle/opGroupingManager.d.ts +14 -0
  214. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -0
  215. package/lib/opLifecycle/opGroupingManager.js +57 -0
  216. package/lib/opLifecycle/opGroupingManager.js.map +1 -0
  217. package/lib/opLifecycle/opSplitter.d.ts +1 -1
  218. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  219. package/lib/opLifecycle/opSplitter.js +5 -6
  220. package/lib/opLifecycle/opSplitter.js.map +1 -1
  221. package/lib/opLifecycle/outbox.d.ts +4 -2
  222. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  223. package/lib/opLifecycle/outbox.js +38 -26
  224. package/lib/opLifecycle/outbox.js.map +1 -1
  225. package/lib/opLifecycle/remoteMessageProcessor.d.ts +4 -2
  226. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  227. package/lib/opLifecycle/remoteMessageProcessor.js +30 -20
  228. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  229. package/lib/packageVersion.d.ts +1 -1
  230. package/lib/packageVersion.js +1 -1
  231. package/lib/packageVersion.js.map +1 -1
  232. package/lib/pendingStateManager.d.ts +1 -1
  233. package/lib/pendingStateManager.d.ts.map +1 -1
  234. package/lib/pendingStateManager.js +11 -3
  235. package/lib/pendingStateManager.js.map +1 -1
  236. package/lib/summary/index.d.ts +2 -2
  237. package/lib/summary/index.d.ts.map +1 -1
  238. package/lib/summary/index.js +2 -1
  239. package/lib/summary/index.js.map +1 -1
  240. package/lib/summary/orderedClientElection.d.ts +1 -0
  241. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  242. package/lib/summary/orderedClientElection.js +19 -0
  243. package/lib/summary/orderedClientElection.js.map +1 -1
  244. package/lib/summary/runningSummarizer.d.ts +4 -3
  245. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  246. package/lib/summary/runningSummarizer.js +65 -66
  247. package/lib/summary/runningSummarizer.js.map +1 -1
  248. package/lib/summary/summarizer.d.ts.map +1 -1
  249. package/lib/summary/summarizer.js +1 -5
  250. package/lib/summary/summarizer.js.map +1 -1
  251. package/lib/summary/summarizerHeuristics.d.ts +1 -0
  252. package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
  253. package/lib/summary/summarizerHeuristics.js +3 -0
  254. package/lib/summary/summarizerHeuristics.js.map +1 -1
  255. package/lib/summary/summarizerNode/summarizerNode.js +1 -1
  256. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  257. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +128 -2
  258. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  259. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
  260. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  261. package/lib/summary/summarizerTypes.d.ts +14 -2
  262. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  263. package/lib/summary/summarizerTypes.js.map +1 -1
  264. package/lib/summary/summaryFormat.d.ts +3 -0
  265. package/lib/summary/summaryFormat.d.ts.map +1 -1
  266. package/lib/summary/summaryFormat.js +2 -0
  267. package/lib/summary/summaryFormat.js.map +1 -1
  268. package/lib/summary/summaryGenerator.d.ts +28 -2
  269. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  270. package/lib/summary/summaryGenerator.js +17 -15
  271. package/lib/summary/summaryGenerator.js.map +1 -1
  272. package/lib/summary/summaryManager.d.ts.map +1 -1
  273. package/lib/summary/summaryManager.js +2 -0
  274. package/lib/summary/summaryManager.js.map +1 -1
  275. package/package.json +29 -17
  276. package/src/blobManager.ts +64 -41
  277. package/src/containerRuntime.ts +294 -65
  278. package/src/dataStoreContext.ts +6 -0
  279. package/src/dataStores.ts +4 -7
  280. package/src/gc/garbageCollection.ts +7 -6
  281. package/src/gc/gcConfigs.ts +1 -3
  282. package/src/gc/gcDefinitions.ts +1 -1
  283. package/src/gc/gcHelpers.ts +9 -6
  284. package/src/id-compressor/README.md +3 -0
  285. package/src/id-compressor/appendOnlySortedMap.ts +427 -0
  286. package/src/id-compressor/idCompressor.ts +1854 -0
  287. package/src/id-compressor/idRange.ts +35 -0
  288. package/src/id-compressor/index.ts +35 -0
  289. package/src/id-compressor/numericUuid.ts +383 -0
  290. package/src/id-compressor/sessionIdNormalizer.ts +609 -0
  291. package/src/id-compressor/utils.ts +114 -0
  292. package/src/id-compressor/uuidUtilities.ts +123 -0
  293. package/src/index.ts +1 -0
  294. package/src/opLifecycle/README.md +119 -0
  295. package/src/opLifecycle/batchManager.ts +35 -2
  296. package/src/opLifecycle/index.ts +2 -1
  297. package/src/opLifecycle/opDecompressor.ts +1 -0
  298. package/src/opLifecycle/opGroupingManager.ts +82 -0
  299. package/src/opLifecycle/opSplitter.ts +1 -5
  300. package/src/opLifecycle/outbox.ts +64 -26
  301. package/src/opLifecycle/remoteMessageProcessor.ts +38 -22
  302. package/src/packageVersion.ts +1 -1
  303. package/src/pendingStateManager.ts +21 -7
  304. package/src/summary/index.ts +2 -1
  305. package/src/summary/orderedClientElection.ts +17 -1
  306. package/src/summary/runningSummarizer.ts +78 -77
  307. package/src/summary/summarizer.ts +0 -8
  308. package/src/summary/summarizerHeuristics.ts +4 -0
  309. package/src/summary/summarizerNode/summarizerNode.ts +1 -1
  310. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +3 -3
  311. package/src/summary/summarizerTypes.ts +20 -3
  312. package/src/summary/summaryFormat.ts +4 -0
  313. package/src/summary/summaryGenerator.ts +22 -16
  314. package/src/summary/summaryManager.ts +2 -0
@@ -1,4 +1,23 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
2
21
  Object.defineProperty(exports, "__esModule", { value: true });
3
22
  exports.ContainerRuntime = exports.getDeviceSpec = exports.agentSchedulerId = exports.isRuntimeMessage = exports.RuntimeMessage = exports.CompressionAlgorithms = exports.defaultRuntimeHeaderData = exports.TombstoneResponseHeaderKey = exports.AllowTombstoneRequestHeaderKey = exports.RuntimeHeaders = exports.DefaultSummaryConfiguration = exports.ContainerMessageType = void 0;
4
23
  const container_definitions_1 = require("@fluidframework/container-definitions");
@@ -40,6 +59,12 @@ var ContainerMessageType;
40
59
  ContainerMessageType["Rejoin"] = "rejoin";
41
60
  // Sets the alias of a root data store
42
61
  ContainerMessageType["Alias"] = "alias";
62
+ /**
63
+ * An op containing an IdRange of Ids allocated using the runtime's IdCompressor since
64
+ * the last allocation op was sent.
65
+ * See the [IdCompressor README](./id-compressor/README.md) for more details.
66
+ */
67
+ ContainerMessageType["IdAllocation"] = "idAllocation";
43
68
  })(ContainerMessageType = exports.ContainerMessageType || (exports.ContainerMessageType = {}));
44
69
  exports.DefaultSummaryConfiguration = {
45
70
  state: "enabled",
@@ -48,7 +73,7 @@ exports.DefaultSummaryConfiguration = {
48
73
  maxTime: 60 * 1000,
49
74
  maxOps: 100,
50
75
  minOpsForLastSummaryAttempt: 10,
51
- maxAckWaitTime: 10 * 60 * 1000,
76
+ maxAckWaitTime: 3 * 60 * 1000,
52
77
  maxOpsSinceLastSummary: 7000,
53
78
  initialSummarizerDelayMs: 5 * 1000,
54
79
  nonRuntimeOpWeight: 0.1,
@@ -95,6 +120,12 @@ const defaultCompressionConfig = {
95
120
  compressionAlgorithm: CompressionAlgorithms.lz4,
96
121
  };
97
122
  const defaultChunkSizeInBytes = 204800;
123
+ /**
124
+ * Instead of refreshing from latest because we do not have 100% confidence in the state
125
+ * of the current system, we should close the summarizer and let it recover.
126
+ * This delay's goal is to prevent tight restart loops
127
+ */
128
+ const defaultCloseSummarizerDelayMs = 10000; // 10 seconds
98
129
  /**
99
130
  * @deprecated - use ContainerRuntimeMessage instead
100
131
  */
@@ -143,8 +174,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
143
174
  /**
144
175
  * @internal
145
176
  */
146
- constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, requestHandler, summaryConfiguration, initializeEntryPoint) {
147
- var _a, _b, _c, _d, _e, _f, _g, _h;
177
+ constructor(context, registry, metadata, electedSummarizerData, chunks, dataStoreAliasMap, runtimeOptions, containerScope, logger, existing, blobManagerSnapshot, _storage, idCompressor, requestHandler, summaryConfiguration, initializeEntryPoint) {
178
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
148
179
  if (summaryConfiguration === void 0) { summaryConfiguration = Object.assign(Object.assign({}, exports.DefaultSummaryConfiguration), (_a = runtimeOptions.summaryOptions) === null || _a === void 0 ? void 0 : _a.summaryConfigOverrides); }
149
180
  super();
150
181
  this.context = context;
@@ -206,6 +237,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
206
237
  };
207
238
  this.innerDeltaManager = context.deltaManager;
208
239
  this.deltaManager = new deltaManagerSummarizerProxy_1.DeltaManagerSummarizerProxy(context.deltaManager);
240
+ this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime"));
209
241
  let loadSummaryNumber;
210
242
  // Get the container creation metadata. For new container, we initialize these. For existing containers,
211
243
  // get the values from the metadata blob.
@@ -217,6 +249,9 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
217
249
  // summaryNumber was renamed from summaryCount. For older docs that haven't been opened for a long time,
218
250
  // the count is reset to 0.
219
251
  loadSummaryNumber = (_b = metadata === null || metadata === void 0 ? void 0 : metadata.summaryNumber) !== null && _b !== void 0 ? _b : 0;
252
+ // Enabling the IdCompressor is a one-way operation and we only want to
253
+ // allow new containers to turn it on
254
+ this.idCompressorEnabled = (_c = metadata === null || metadata === void 0 ? void 0 : metadata.idCompressorEnabled) !== null && _c !== void 0 ? _c : false;
220
255
  }
221
256
  else {
222
257
  this.createContainerMetadata = {
@@ -224,12 +259,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
224
259
  createContainerTimestamp: Date.now(),
225
260
  };
226
261
  loadSummaryNumber = 0;
262
+ this.idCompressorEnabled =
263
+ (_d = this.mc.config.getBoolean("Fluid.ContainerRuntime.IdCompressorEnabled")) !== null && _d !== void 0 ? _d : idCompressor !== undefined;
227
264
  }
228
265
  this.nextSummaryNumber = loadSummaryNumber + 1;
229
266
  this.messageAtLastSummary = metadata === null || metadata === void 0 ? void 0 : metadata.message;
230
267
  this._connected = this.context.connected;
231
- this.gcTombstoneEnforcementAllowed = (0, gc_1.shouldAllowGcTombstoneEnforcement)((_c = metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix) === null || _c === void 0 ? void 0 : _c.tombstoneGeneration /* persisted */, this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName] /* current */);
232
- this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(this.logger, "ContainerRuntime"));
268
+ this.gcTombstoneEnforcementAllowed = (0, gc_1.shouldAllowGcTombstoneEnforcement)((_e = metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix) === null || _e === void 0 ? void 0 : _e.tombstoneGeneration /* persisted */, this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName] /* current */);
233
269
  this.mc.logger.sendTelemetryEvent({
234
270
  eventName: "GCFeatureMatrix",
235
271
  metadataValue: JSON.stringify(metadata === null || metadata === void 0 ? void 0 : metadata.gcFeatureMatrix),
@@ -237,11 +273,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
237
273
  gcOptions_gcTombstoneGeneration: this.runtimeOptions.gcOptions[gc_1.gcTombstoneGenerationOptionName],
238
274
  }),
239
275
  });
240
- this.telemetryDocumentId = (_d = metadata === null || metadata === void 0 ? void 0 : metadata.telemetryDocumentId) !== null && _d !== void 0 ? _d : (0, uuid_1.v4)();
276
+ this.telemetryDocumentId = (_f = metadata === null || metadata === void 0 ? void 0 : metadata.telemetryDocumentId) !== null && _f !== void 0 ? _f : (0, uuid_1.v4)();
241
277
  this.disableAttachReorder = this.mc.config.getBoolean("Fluid.ContainerRuntime.disableAttachOpReorder");
242
278
  const disableChunking = this.mc.config.getBoolean("Fluid.ContainerRuntime.CompressionChunkingDisabled");
279
+ const opGroupingManager = new opLifecycle_1.OpGroupingManager(this.groupedBatchingEnabled);
243
280
  const opSplitter = new opLifecycle_1.OpSplitter(chunks, this.context.submitBatchFn, disableChunking === true ? Number.POSITIVE_INFINITY : runtimeOptions.chunkSizeInBytes, runtimeOptions.maxBatchSizeInBytes, this.mc.logger);
244
- this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor(this.mc.logger));
281
+ this.remoteMessageProcessor = new opLifecycle_1.RemoteMessageProcessor(opSplitter, new opLifecycle_1.OpDecompressor(this.mc.logger), opGroupingManager);
245
282
  this.handleContext = new containerHandleContext_1.ContainerFluidHandleContext("", this);
246
283
  if (this.summaryConfiguration.state === "enabled") {
247
284
  this.validateSummaryHeuristicConfiguration(this.summaryConfiguration);
@@ -255,10 +292,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
255
292
  this.heuristicsDisabled = this.isHeuristicsDisabled();
256
293
  this.maxOpsSinceLastSummary = this.getMaxOpsSinceLastSummary();
257
294
  this.initialSummarizerDelayMs = this.getInitialSummarizerDelayMs();
295
+ if (this.idCompressorEnabled) {
296
+ this.idCompressor = idCompressor;
297
+ }
258
298
  this.maxConsecutiveReconnects =
259
- (_e = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _e !== void 0 ? _e : this.defaultMaxConsecutiveReconnects;
299
+ (_g = this.mc.config.getNumber(maxConsecutiveReconnectsKey)) !== null && _g !== void 0 ? _g : this.defaultMaxConsecutiveReconnects;
260
300
  if (runtimeOptions.flushMode === runtime_definitions_1.FlushModeExperimental.Async &&
261
- ((_f = context.supportedFeatures) === null || _f === void 0 ? void 0 : _f.get("referenceSequenceNumbers")) !== true) {
301
+ ((_h = context.supportedFeatures) === null || _h === void 0 ? void 0 : _h.get("referenceSequenceNumbers")) !== true) {
262
302
  // The loader does not support reference sequence numbers, falling back on FlushMode.TurnBased
263
303
  this.mc.logger.sendErrorEvent({ eventName: "FlushModeFallback" });
264
304
  this._flushMode = runtime_definitions_1.FlushMode.TurnBased;
@@ -267,7 +307,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
267
307
  this._flushMode = runtimeOptions.flushMode;
268
308
  }
269
309
  const pendingRuntimeState = context.pendingLocalState;
270
- const maxSnapshotCacheDurationMs = (_h = (_g = this._storage) === null || _g === void 0 ? void 0 : _g.policies) === null || _h === void 0 ? void 0 : _h.maximumCacheDurationMs;
310
+ const maxSnapshotCacheDurationMs = (_k = (_j = this._storage) === null || _j === void 0 ? void 0 : _j.policies) === null || _k === void 0 ? void 0 : _k.maximumCacheDurationMs;
271
311
  if (maxSnapshotCacheDurationMs !== undefined &&
272
312
  maxSnapshotCacheDurationMs > 5 * 24 * 60 * 60 * 1000) {
273
313
  // This is a runtime enforcement of what's already explicit in the policy's type itself,
@@ -324,7 +364,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
324
364
  blobId,
325
365
  });
326
366
  }
327
- }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, () => this.getCurrentReferenceTimestampMs());
367
+ }, (blobPath) => this.garbageCollector.nodeUpdated(blobPath, "Loaded"), (blobPath) => this.garbageCollector.isNodeDeleted(blobPath), this, pendingRuntimeState === null || pendingRuntimeState === void 0 ? void 0 : pendingRuntimeState.pendingAttachmentBlobs, (error) => this.closeFn(error));
328
368
  this.scheduleManager = new scheduleManager_1.ScheduleManager(context.deltaManager, this, () => this.clientId, telemetry_utils_1.ChildLogger.create(this.logger, "ScheduleManager"));
329
369
  this.pendingStateManager = new pendingStateManager_1.PendingStateManager({
330
370
  applyStashedOp: this.applyStashedOp.bind(this),
@@ -355,10 +395,18 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
355
395
  disablePartialFlush: disablePartialFlush === true,
356
396
  },
357
397
  logger: this.mc.logger,
398
+ groupingManager: opGroupingManager,
399
+ getCurrentSequenceNumbers: () => ({
400
+ referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
401
+ clientSequenceNumber: this._processedClientSequenceNumber,
402
+ }),
358
403
  });
359
404
  this.context.quorum.on("removeMember", (clientId) => {
360
405
  this.remoteMessageProcessor.clearPartialMessagesFor(clientId);
361
406
  });
407
+ this.summaryStateUpdateMethod = this.mc.config.getString("Fluid.ContainerRuntime.Test.SummaryStateUpdateMethod");
408
+ const closeSummarizerDelayOverride = this.mc.config.getNumber("Fluid.ContainerRuntime.Test.CloseSummarizerDelayOverrideMs");
409
+ this.closeSummarizerDelayMs = closeSummarizerDelayOverride !== null && closeSummarizerDelayOverride !== void 0 ? closeSummarizerDelayOverride : defaultCloseSummarizerDelayMs;
362
410
  this.summaryCollection = new summary_1.SummaryCollection(this.deltaManager, this.logger);
363
411
  this.dirtyContainer =
364
412
  this.context.attachState !== container_definitions_1.AttachState.Attached ||
@@ -436,7 +484,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
436
484
  disableChunking,
437
485
  disableAttachReorder: this.disableAttachReorder,
438
486
  disablePartialFlush,
439
- }), telemetryDocumentId: this.telemetryDocumentId }));
487
+ idCompressorEnabled: this.idCompressorEnabled,
488
+ summaryStateUpdateMethod: this.summaryStateUpdateMethod,
489
+ closeSummarizerDelayOverride,
490
+ }), telemetryDocumentId: this.telemetryDocumentId, groupedBatchingEnabled: this.groupedBatchingEnabled }));
440
491
  (0, connectionTelemetry_1.ReportOpPerfTelemetry)(this.context.clientId, this.deltaManager, this.logger);
441
492
  (0, batchTracker_1.BindBatchTracker)(this, this.logger);
442
493
  this.entryPoint = new common_utils_1.LazyPromise(async () => {
@@ -495,7 +546,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
495
546
  * This object should provide all the functionality that the Container is expected to provide to the loader layer.
496
547
  */
497
548
  static async loadRuntime(params) {
498
- var _a, _b, _c, _d;
549
+ var _a, _b, _c, _d, _e, _f;
499
550
  const { context, registryEntries, existing, requestHandler, runtimeOptions = {}, containerScope = {}, containerRuntimeCtor = ContainerRuntime, initializeEntryPoint, } = params;
500
551
  // If taggedLogger exists, use it. Otherwise, wrap the vanilla logger:
501
552
  // back-compat: Remove the TaggedLoggerAdapter fallback once all the host are using loader > 0.45
@@ -506,7 +557,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
506
557
  runtimeVersion: packageVersion_1.pkgVersion,
507
558
  },
508
559
  });
509
- const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, } = runtimeOptions;
560
+ const { summaryOptions = {}, gcOptions = {}, loadSequenceNumberVerification = "close", flushMode = defaultFlushMode, compressionOptions = defaultCompressionConfig, maxBatchSizeInBytes = defaultMaxBatchSizeInBytes, enableRuntimeIdCompressor = false, chunkSizeInBytes = defaultChunkSizeInBytes, enableOpReentryCheck = false, enableGroupedBatching = false, } = runtimeOptions;
510
561
  const registry = new dataStoreRegistry_1.FluidDataStoreRegistry(registryEntries);
511
562
  const tryFetchBlob = async (blobName) => {
512
563
  var _a;
@@ -518,11 +569,12 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
518
569
  return (0, driver_utils_1.readAndParse)(context.storage, blobId);
519
570
  }
520
571
  };
521
- const [chunks, metadata, electedSummarizerData, aliases] = await Promise.all([
572
+ const [chunks, metadata, electedSummarizerData, aliases, serializedIdCompressor] = await Promise.all([
522
573
  tryFetchBlob(summary_1.chunksBlobName),
523
574
  tryFetchBlob(summary_1.metadataBlobName),
524
575
  tryFetchBlob(summary_1.electedSummarizerBlobName),
525
576
  tryFetchBlob(summary_1.aliasBlobName),
577
+ tryFetchBlob(summary_1.idCompressorBlobName),
526
578
  ]);
527
579
  const loadExisting = existing === true || context.existing === true;
528
580
  // read snapshot blobs needed for BlobManager to load
@@ -554,6 +606,15 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
554
606
  }
555
607
  }
556
608
  }
609
+ const idCompressorEnabled = (_f = (_e = metadata === null || metadata === void 0 ? void 0 : metadata.idCompressorEnabled) !== null && _e !== void 0 ? _e : runtimeOptions.enableRuntimeIdCompressor) !== null && _f !== void 0 ? _f : false;
610
+ let idCompressor;
611
+ if (idCompressorEnabled) {
612
+ const { IdCompressor, createSessionId } = await Promise.resolve().then(() => __importStar(require("./id-compressor")));
613
+ idCompressor =
614
+ serializedIdCompressor !== undefined
615
+ ? IdCompressor.deserialize(serializedIdCompressor, createSessionId())
616
+ : new IdCompressor(createSessionId(), logger);
617
+ }
557
618
  const runtime = new containerRuntimeCtor(context, registry, metadata, electedSummarizerData, chunks !== null && chunks !== void 0 ? chunks : [], aliases !== null && aliases !== void 0 ? aliases : [], {
558
619
  summaryOptions,
559
620
  gcOptions,
@@ -562,8 +623,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
562
623
  compressionOptions,
563
624
  maxBatchSizeInBytes,
564
625
  chunkSizeInBytes,
626
+ enableRuntimeIdCompressor,
565
627
  enableOpReentryCheck,
566
- }, containerScope, logger, loadExisting, blobManagerSnapshot, context.storage, requestHandler, undefined, // summaryConfiguration
628
+ enableGroupedBatching,
629
+ }, containerScope, logger, loadExisting, blobManagerSnapshot, context.storage, idCompressor, requestHandler, undefined, // summaryConfiguration
567
630
  initializeEntryPoint);
568
631
  // It's possible to have ops with a reference sequence number of 0. Op sequence numbers start
569
632
  // at 1, so we won't see a replayed saved op with a sequence number of 0.
@@ -799,12 +862,17 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
799
862
  summaryNumber: this.nextSummaryNumber++, summaryFormatVersion: 1 }), this.garbageCollector.getMetadata()), {
800
863
  // The last message processed at the time of summary. If there are no new messages, use the message from the
801
864
  // last summary.
802
- message: (_a = (0, summary_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.messageAtLastSummary, telemetryDocumentId: this.telemetryDocumentId });
865
+ message: (_a = (0, summary_1.extractSummaryMetadataMessage)(this.deltaManager.lastMessage)) !== null && _a !== void 0 ? _a : this.messageAtLastSummary, telemetryDocumentId: this.telemetryDocumentId, idCompressorEnabled: this.idCompressorEnabled ? true : undefined });
803
866
  (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.metadataBlobName, JSON.stringify(metadata));
804
867
  }
805
868
  addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext) {
806
869
  var _a;
807
870
  this.addMetadataToSummary(summaryTree);
871
+ if (this.idCompressorEnabled) {
872
+ (0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67a /* IdCompressor should be defined if enabled */);
873
+ const idCompressorState = JSON.stringify(this.idCompressor.serialize(false));
874
+ (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.idCompressorBlobName, idCompressorState);
875
+ }
808
876
  if (this.remoteMessageProcessor.partialMessages.size > 0) {
809
877
  const content = JSON.stringify([...this.remoteMessageProcessor.partialMessages]);
810
878
  (0, runtime_utils_1.addBlobToSummary)(summaryTree, summary_1.chunksBlobName, content);
@@ -886,12 +954,28 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
886
954
  // Officially transition from the old state to the new state.
887
955
  this.updateDocumentDirtyState(newState);
888
956
  }
889
- async applyStashedOp(type, op) {
957
+ /**
958
+ * Updates the runtime's IdCompressor with the stashed state present in the given op. This is a bit of a
959
+ * hack and is unnecessarily expensive. As it stands, every locally stashed op (all ops that get stored in
960
+ * the PendingStateManager) will store their serialized representation locally until ack'd. Upon receiving
961
+ * this stashed state, the IdCompressor blindly deserializes to the stashed state and assumes the session.
962
+ * Technically only the last stashed state is needed to do this correctly, but we would have to write some
963
+ * more hacky code to modify the batch before it gets sent out.
964
+ * @param content - An IdAllocationOp with "stashedState", which is a representation of un-ack'd local state.
965
+ */
966
+ async applyStashedIdAllocationOp(op) {
967
+ const { IdCompressor } = await Promise.resolve().then(() => __importStar(require("./id-compressor")));
968
+ this.idCompressor = IdCompressor.deserialize(op.stashedState);
969
+ }
970
+ async applyStashedOp(type, contents) {
890
971
  switch (type) {
891
972
  case ContainerMessageType.FluidDataStoreOp:
892
- return this.dataStores.applyStashedOp(op);
973
+ return this.dataStores.applyStashedOp(contents);
893
974
  case ContainerMessageType.Attach:
894
- return this.dataStores.applyStashedAttachOp(op);
975
+ return this.dataStores.applyStashedAttachOp(contents);
976
+ case ContainerMessageType.IdAllocation:
977
+ (0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67b /* IdCompressor should be defined if enabled */);
978
+ return this.applyStashedIdAllocationOp(contents);
895
979
  case ContainerMessageType.Alias:
896
980
  case ContainerMessageType.BlobAttach:
897
981
  return;
@@ -970,7 +1054,6 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
970
1054
  await this.pendingStateManager.applyStashedOpsAt(message.sequenceNumber);
971
1055
  }
972
1056
  process(messageArg, local) {
973
- var _a;
974
1057
  this.verifyNotClosed();
975
1058
  // Whether or not the message is actually a runtime message.
976
1059
  // It may be a legacy runtime message (ie already unpacked and ContainerMessageType)
@@ -978,11 +1061,17 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
978
1061
  const runtimeMessage = messageArg.type === protocol_definitions_1.MessageType.Operation;
979
1062
  // Do shallow copy of message, as the processing flow will modify it.
980
1063
  const messageCopy = Object.assign({}, messageArg);
981
- const message = this.remoteMessageProcessor.process(messageCopy);
1064
+ for (const message of this.remoteMessageProcessor.process(messageCopy)) {
1065
+ this.processCore(message, local, runtimeMessage);
1066
+ }
1067
+ }
1068
+ processCore(message, local, runtimeMessage) {
1069
+ var _a;
982
1070
  // Surround the actual processing of the operation with messages to the schedule manager indicating
983
1071
  // the beginning and end. This allows it to emit appropriate events and/or pause the processing of new
984
1072
  // messages once a batch has been fully processed.
985
1073
  this.scheduleManager.beforeOpProcessing(message);
1074
+ this._processedClientSequenceNumber = message.clientSequenceNumber;
986
1075
  try {
987
1076
  let localOpMetadata;
988
1077
  if (local && runtimeMessage && message.type !== ContainerMessageType.ChunkedOp) {
@@ -1007,6 +1096,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1007
1096
  case ContainerMessageType.BlobAttach:
1008
1097
  this.blobManager.processBlobAttachOp(message, local);
1009
1098
  break;
1099
+ case ContainerMessageType.IdAllocation:
1100
+ (0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67c /* IdCompressor should be defined if enabled */);
1101
+ this.idCompressor.finalizeCreationRange(message.contents);
1102
+ break;
1010
1103
  case ContainerMessageType.ChunkedOp:
1011
1104
  case ContainerMessageType.Rejoin:
1012
1105
  break;
@@ -1025,8 +1118,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1025
1118
  throw error;
1026
1119
  }
1027
1120
  }
1028
- // For back-compat, notify only about runtime messages for now.
1029
- if (runtimeMessage) {
1121
+ if (runtimeMessage || this.groupedBatchingEnabled) {
1030
1122
  this.emit("op", message, runtimeMessage);
1031
1123
  }
1032
1124
  this.scheduleManager.afterOpProcessing(undefined, message);
@@ -1317,17 +1409,21 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1317
1409
  fullGC,
1318
1410
  runSweep,
1319
1411
  });
1320
- let gcStats;
1321
- if (runGC) {
1322
- gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
1412
+ try {
1413
+ let gcStats;
1414
+ if (runGC) {
1415
+ gcStats = await this.collectGarbage({ logger: summaryLogger, runSweep, fullGC }, telemetryContext);
1416
+ }
1417
+ const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
1418
+ (0, common_utils_1.assert)(summary.type === protocol_definitions_1.SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
1419
+ return { stats, summary, gcStats };
1420
+ }
1421
+ finally {
1422
+ this.logger.sendTelemetryEvent({
1423
+ eventName: "SummarizeTelemetry",
1424
+ details: telemetryContext.serialize(),
1425
+ });
1323
1426
  }
1324
- const { stats, summary } = await this.summarizerNode.summarize(fullTree, trackState, telemetryContext);
1325
- this.logger.sendTelemetryEvent({
1326
- eventName: "SummarizeTelemetry",
1327
- details: telemetryContext.serialize(),
1328
- });
1329
- (0, common_utils_1.assert)(summary.type === protocol_definitions_1.SummaryType.Tree, 0x12f /* "Container Runtime's summarize should always return a tree" */);
1330
- return { stats, summary, gcStats };
1331
1427
  }
1332
1428
  /**
1333
1429
  * Before GC runs, called by the garbage collector to update any pending GC state. This is mainly used to notify
@@ -1714,6 +1810,35 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1714
1810
  this.verifyNotClosed();
1715
1811
  return this.blobManager.createBlob(blob);
1716
1812
  }
1813
+ maybeSubmitIdAllocationOp(type) {
1814
+ var _a, _b;
1815
+ if (type !== ContainerMessageType.IdAllocation) {
1816
+ let idAllocationBatchMessage;
1817
+ let idRange;
1818
+ if (this.idCompressorEnabled) {
1819
+ (0, common_utils_1.assert)(this.idCompressor !== undefined, 0x67d /* IdCompressor should be defined if enabled */);
1820
+ idRange = this.idCompressor.takeNextCreationRange();
1821
+ // Don't include the idRange if there weren't any Ids allocated
1822
+ idRange = ((_a = idRange === null || idRange === void 0 ? void 0 : idRange.ids) === null || _a === void 0 ? void 0 : _a.first) !== undefined ? idRange : undefined;
1823
+ }
1824
+ if (idRange !== undefined) {
1825
+ const idAllocationMessage = {
1826
+ type: ContainerMessageType.IdAllocation,
1827
+ contents: idRange,
1828
+ };
1829
+ idAllocationBatchMessage = {
1830
+ contents: JSON.stringify(idAllocationMessage),
1831
+ deserializedContent: idAllocationMessage,
1832
+ referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
1833
+ metadata: undefined,
1834
+ localOpMetadata: (_b = this.idCompressor) === null || _b === void 0 ? void 0 : _b.serialize(true),
1835
+ };
1836
+ }
1837
+ if (idAllocationBatchMessage !== undefined) {
1838
+ this.outbox.submit(idAllocationBatchMessage);
1839
+ }
1840
+ }
1841
+ }
1717
1842
  submit(type, contents, localOpMetadata = undefined, metadata = undefined) {
1718
1843
  this.verifyNotClosed();
1719
1844
  this.verifyCanSubmitOps();
@@ -1736,6 +1861,11 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1736
1861
  referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
1737
1862
  };
1738
1863
  try {
1864
+ // Submit an IdAllocation op if any Ids have been generated since
1865
+ // the last op was submitted. Don't submit another if it's an IdAllocation
1866
+ // op as that means we're in resubmission flow and we don't want to send
1867
+ // IdRanges out of order.
1868
+ this.maybeSubmitIdAllocationOp(type);
1739
1869
  // If this is attach message for new data store, and we are in a batch, send this op out of order
1740
1870
  // Is it safe:
1741
1871
  // Yes, this should be safe reordering. Newly created data stores are not visible through API surface.
@@ -1872,6 +2002,7 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1872
2002
  break;
1873
2003
  case ContainerMessageType.Attach:
1874
2004
  case ContainerMessageType.Alias:
2005
+ case ContainerMessageType.IdAllocation:
1875
2006
  this.submit(type, content, localOpMetadata);
1876
2007
  break;
1877
2008
  case ContainerMessageType.ChunkedOp:
@@ -1921,6 +2052,19 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1921
2052
  ackHandle,
1922
2053
  targetSequenceNumber: summaryRefSeq,
1923
2054
  }, readAndParseBlob);
2055
+ /**
2056
+ * back-compat - Older loaders and drivers (pre 2.0.0-internal.1.4) don't have fetchSource as a param in the
2057
+ * getVersions API. So, they will not fetch the latest snapshot from network in the previous fetch call. For
2058
+ * these scenarios, fetch the snapshot corresponding to the ack handle to have the same behavior before the
2059
+ * change that started fetching latest snapshot always.
2060
+ */
2061
+ if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
2062
+ fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
2063
+ eventName: "RefreshLatestSummaryAckFetchBackCompat",
2064
+ ackHandle,
2065
+ targetSequenceNumber: summaryRefSeq,
2066
+ }, readAndParseBlob, ackHandle);
2067
+ }
1924
2068
  /**
1925
2069
  * If the fetched snapshot is older than the one for which the ack was received, close the container.
1926
2070
  * This should never happen because an ack should be sent after the latest summary is updated in the server.
@@ -1932,21 +2076,13 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1932
2076
  * state.
1933
2077
  */
1934
2078
  if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
1935
- /* before failing, let's try to retrieve the latest snapshot for that specific ackHandle */
1936
- fetchResult = await this.fetchSnapshotFromStorage(summaryLogger, {
1937
- eventName: "RefreshLatestSummaryAckFetch",
2079
+ const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
1938
2080
  ackHandle,
1939
- targetSequenceNumber: summaryRefSeq,
1940
- }, readAndParseBlob, ackHandle);
1941
- if (fetchResult.latestSnapshotRefSeq < summaryRefSeq) {
1942
- const error = container_utils_1.DataProcessingError.create("Fetched snapshot is older than the received ack", "RefreshLatestSummaryAck", undefined /* sequencedMessage */, {
1943
- ackHandle,
1944
- summaryRefSeq,
1945
- fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
1946
- });
1947
- this.closeFn(error);
1948
- throw error;
1949
- }
2081
+ summaryRefSeq,
2082
+ fetchedSnapshotRefSeq: fetchResult.latestSnapshotRefSeq,
2083
+ });
2084
+ this.closeFn(error);
2085
+ throw error;
1950
2086
  }
1951
2087
  // In case we had to retrieve the latest snapshot and it is different than summaryRefSeq,
1952
2088
  // wait for the delta manager to catch up before refreshing the latest Summary.
@@ -1984,7 +2120,8 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
1984
2120
  return this.fetchSnapshotFromStorage(logger, event, readAndParseBlob, null /* latest */);
1985
2121
  }
1986
2122
  async fetchSnapshotFromStorage(logger, event, readAndParseBlob, versionId) {
1987
- return telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
2123
+ var _a;
2124
+ const snapshotResults = await telemetry_utils_1.PerformanceEvent.timedExecAsync(logger, event, async (perfEvent) => {
1988
2125
  const stats = {};
1989
2126
  const trace = common_utils_1.Trace.start();
1990
2127
  const versions = await this.storage.getVersions(versionId, 1, "refreshLatestSummaryAckFromServer", versionId === null ? driver_definitions_1.FetchSource.noCache : undefined);
@@ -2003,6 +2140,19 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2003
2140
  latestSnapshotRefSeq,
2004
2141
  };
2005
2142
  });
2143
+ // We choose to close the summarizer after the snapshot cache is updated to avoid
2144
+ // situations which the main client (which is likely to be re-elected as the leader again)
2145
+ // loads the summarizer from cache.
2146
+ if (this.summaryStateUpdateMethod === "restart") {
2147
+ const error = new container_utils_1.GenericError("Restarting summarizer instead of refreshing");
2148
+ this.mc.logger.sendTelemetryEvent(Object.assign(Object.assign({}, event), { eventName: "ClosingSummarizerOnSummaryStale", codePath: event.eventName, message: "Stopping fetch from storage", versionId: versionId != null ? versionId : undefined, closeSummarizerDelayMs: this.closeSummarizerDelayMs }), error);
2149
+ // Delay 10 seconds before restarting summarizer to prevent the summarizer from restarting too frequently.
2150
+ await (0, common_utils_1.delay)(this.closeSummarizerDelayMs);
2151
+ (_a = this._summarizer) === null || _a === void 0 ? void 0 : _a.stop("latestSummaryStateStale");
2152
+ this.closeFn();
2153
+ throw error;
2154
+ }
2155
+ return snapshotResults;
2006
2156
  }
2007
2157
  notifyAttaching() { } // do nothing (deprecated method)
2008
2158
  getPendingLocalState() {
@@ -2055,6 +2205,10 @@ class ContainerRuntime extends common_utils_1.TypedEventEmitter {
2055
2205
  throw new container_utils_1.UsageError(`"minIdleTime" [${configuration.minIdleTime}] cannot be greater than "maxIdleTime" [${configuration.maxIdleTime}]`);
2056
2206
  }
2057
2207
  }
2208
+ get groupedBatchingEnabled() {
2209
+ const killSwitch = this.mc.config.getBoolean("Fluid.ContainerRuntime.DisableGroupedBatching");
2210
+ return killSwitch !== true && this.runtimeOptions.enableGroupedBatching;
2211
+ }
2058
2212
  }
2059
2213
  exports.ContainerRuntime = ContainerRuntime;
2060
2214
  /**