@fluidframework/container-runtime 2.0.0-dev.2.2.0.111723 → 2.0.0-dev.3.1.0.125672

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 (365) hide show
  1. package/.eslintrc.js +21 -10
  2. package/.mocharc.js +2 -2
  3. package/api-extractor.json +2 -2
  4. package/dist/batchTracker.d.ts +1 -2
  5. package/dist/batchTracker.d.ts.map +1 -1
  6. package/dist/batchTracker.js +2 -1
  7. package/dist/batchTracker.js.map +1 -1
  8. package/dist/blobManager.d.ts +62 -28
  9. package/dist/blobManager.d.ts.map +1 -1
  10. package/dist/blobManager.js +256 -102
  11. package/dist/blobManager.js.map +1 -1
  12. package/dist/connectionTelemetry.d.ts.map +1 -1
  13. package/dist/connectionTelemetry.js +11 -9
  14. package/dist/connectionTelemetry.js.map +1 -1
  15. package/dist/containerHandleContext.d.ts.map +1 -1
  16. package/dist/containerHandleContext.js +3 -1
  17. package/dist/containerHandleContext.js.map +1 -1
  18. package/dist/containerRuntime.d.ts +110 -78
  19. package/dist/containerRuntime.d.ts.map +1 -1
  20. package/dist/containerRuntime.js +336 -331
  21. package/dist/containerRuntime.js.map +1 -1
  22. package/dist/dataStore.d.ts.map +1 -1
  23. package/dist/dataStore.js +11 -9
  24. package/dist/dataStore.js.map +1 -1
  25. package/dist/dataStoreContext.d.ts +2 -1
  26. package/dist/dataStoreContext.d.ts.map +1 -1
  27. package/dist/dataStoreContext.js +40 -23
  28. package/dist/dataStoreContext.js.map +1 -1
  29. package/dist/dataStoreContexts.d.ts.map +1 -1
  30. package/dist/dataStoreContexts.js +7 -3
  31. package/dist/dataStoreContexts.js.map +1 -1
  32. package/dist/dataStoreRegistry.d.ts.map +1 -1
  33. package/dist/dataStoreRegistry.js +3 -1
  34. package/dist/dataStoreRegistry.js.map +1 -1
  35. package/dist/dataStores.d.ts +12 -9
  36. package/dist/dataStores.d.ts.map +1 -1
  37. package/dist/dataStores.js +69 -46
  38. package/dist/dataStores.js.map +1 -1
  39. package/dist/deltaScheduler.d.ts.map +1 -1
  40. package/dist/deltaScheduler.js +8 -3
  41. package/dist/deltaScheduler.js.map +1 -1
  42. package/dist/garbageCollection.d.ts +57 -42
  43. package/dist/garbageCollection.d.ts.map +1 -1
  44. package/dist/garbageCollection.js +371 -239
  45. package/dist/garbageCollection.js.map +1 -1
  46. package/dist/garbageCollectionConstants.d.ts +23 -0
  47. package/dist/garbageCollectionConstants.d.ts.map +1 -0
  48. package/dist/garbageCollectionConstants.js +36 -0
  49. package/dist/garbageCollectionConstants.js.map +1 -0
  50. package/dist/garbageCollectionHelpers.d.ts +15 -0
  51. package/dist/garbageCollectionHelpers.d.ts.map +1 -0
  52. package/dist/garbageCollectionHelpers.js +27 -0
  53. package/dist/garbageCollectionHelpers.js.map +1 -0
  54. package/dist/gcSweepReadyUsageDetection.d.ts +5 -5
  55. package/dist/gcSweepReadyUsageDetection.d.ts.map +1 -1
  56. package/dist/gcSweepReadyUsageDetection.js +15 -11
  57. package/dist/gcSweepReadyUsageDetection.js.map +1 -1
  58. package/dist/index.d.ts +4 -3
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +5 -6
  61. package/dist/index.js.map +1 -1
  62. package/dist/opLifecycle/batchManager.d.ts +42 -0
  63. package/dist/opLifecycle/batchManager.d.ts.map +1 -0
  64. package/dist/opLifecycle/batchManager.js +124 -0
  65. package/dist/opLifecycle/batchManager.js.map +1 -0
  66. package/dist/opLifecycle/definitions.d.ts +64 -0
  67. package/dist/opLifecycle/definitions.d.ts.map +1 -0
  68. package/dist/opLifecycle/definitions.js +7 -0
  69. package/dist/opLifecycle/definitions.js.map +1 -0
  70. package/dist/opLifecycle/index.d.ts +12 -0
  71. package/dist/opLifecycle/index.d.ts.map +1 -0
  72. package/dist/opLifecycle/index.js +22 -0
  73. package/dist/opLifecycle/index.js.map +1 -0
  74. package/dist/{opCompressor.d.ts → opLifecycle/opCompressor.d.ts} +3 -3
  75. package/dist/opLifecycle/opCompressor.d.ts.map +1 -0
  76. package/dist/opLifecycle/opCompressor.js +67 -0
  77. package/dist/opLifecycle/opCompressor.js.map +1 -0
  78. package/dist/{opDecompressor.d.ts → opLifecycle/opDecompressor.d.ts} +2 -1
  79. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -0
  80. package/dist/{opDecompressor.js → opLifecycle/opDecompressor.js} +37 -21
  81. package/dist/opLifecycle/opDecompressor.js.map +1 -0
  82. package/dist/opLifecycle/opSplitter.d.ts +49 -0
  83. package/dist/opLifecycle/opSplitter.d.ts.map +1 -0
  84. package/dist/opLifecycle/opSplitter.js +173 -0
  85. package/dist/opLifecycle/opSplitter.js.map +1 -0
  86. package/dist/opLifecycle/outbox.d.ts +52 -0
  87. package/dist/opLifecycle/outbox.d.ts.map +1 -0
  88. package/dist/opLifecycle/outbox.js +164 -0
  89. package/dist/opLifecycle/outbox.js.map +1 -0
  90. package/dist/opLifecycle/remoteMessageProcessor.d.ts +26 -0
  91. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
  92. package/dist/opLifecycle/remoteMessageProcessor.js +96 -0
  93. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -0
  94. package/dist/opProperties.d.ts.map +1 -1
  95. package/dist/opProperties.js +1 -3
  96. package/dist/opProperties.js.map +1 -1
  97. package/dist/orderedClientElection.d.ts.map +1 -1
  98. package/dist/orderedClientElection.js +10 -4
  99. package/dist/orderedClientElection.js.map +1 -1
  100. package/dist/packageVersion.d.ts +1 -1
  101. package/dist/packageVersion.js +1 -1
  102. package/dist/packageVersion.js.map +1 -1
  103. package/dist/pendingStateManager.d.ts +4 -13
  104. package/dist/pendingStateManager.d.ts.map +1 -1
  105. package/dist/pendingStateManager.js +134 -161
  106. package/dist/pendingStateManager.js.map +1 -1
  107. package/dist/runWhileConnectedCoordinator.d.ts.map +1 -1
  108. package/dist/runWhileConnectedCoordinator.js.map +1 -1
  109. package/dist/runningSummarizer.d.ts.map +1 -1
  110. package/dist/runningSummarizer.js +34 -22
  111. package/dist/runningSummarizer.js.map +1 -1
  112. package/dist/scheduleManager.d.ts +0 -1
  113. package/dist/scheduleManager.d.ts.map +1 -1
  114. package/dist/scheduleManager.js +11 -21
  115. package/dist/scheduleManager.js.map +1 -1
  116. package/dist/serializedSnapshotStorage.d.ts.map +1 -1
  117. package/dist/serializedSnapshotStorage.js +3 -1
  118. package/dist/serializedSnapshotStorage.js.map +1 -1
  119. package/dist/summarizer.d.ts +2 -3
  120. package/dist/summarizer.d.ts.map +1 -1
  121. package/dist/summarizer.js +39 -18
  122. package/dist/summarizer.js.map +1 -1
  123. package/dist/summarizerClientElection.d.ts +1 -2
  124. package/dist/summarizerClientElection.d.ts.map +1 -1
  125. package/dist/summarizerClientElection.js +3 -30
  126. package/dist/summarizerClientElection.js.map +1 -1
  127. package/dist/summarizerHandle.d.ts.map +1 -1
  128. package/dist/summarizerHandle.js.map +1 -1
  129. package/dist/summarizerHeuristics.d.ts.map +1 -1
  130. package/dist/summarizerHeuristics.js +6 -9
  131. package/dist/summarizerHeuristics.js.map +1 -1
  132. package/dist/summarizerTypes.d.ts +22 -25
  133. package/dist/summarizerTypes.d.ts.map +1 -1
  134. package/dist/summarizerTypes.js.map +1 -1
  135. package/dist/summaryCollection.d.ts.map +1 -1
  136. package/dist/summaryCollection.js +18 -8
  137. package/dist/summaryCollection.js.map +1 -1
  138. package/dist/summaryFormat.d.ts.map +1 -1
  139. package/dist/summaryFormat.js +18 -11
  140. package/dist/summaryFormat.js.map +1 -1
  141. package/dist/summaryGenerator.d.ts.map +1 -1
  142. package/dist/summaryGenerator.js +32 -14
  143. package/dist/summaryGenerator.js.map +1 -1
  144. package/dist/summaryManager.d.ts.map +1 -1
  145. package/dist/summaryManager.js +21 -9
  146. package/dist/summaryManager.js.map +1 -1
  147. package/dist/throttler.d.ts +2 -2
  148. package/dist/throttler.d.ts.map +1 -1
  149. package/dist/throttler.js +4 -4
  150. package/dist/throttler.js.map +1 -1
  151. package/garbageCollection.md +15 -2
  152. package/lib/batchTracker.d.ts +1 -2
  153. package/lib/batchTracker.d.ts.map +1 -1
  154. package/lib/batchTracker.js +2 -1
  155. package/lib/batchTracker.js.map +1 -1
  156. package/lib/blobManager.d.ts +62 -28
  157. package/lib/blobManager.d.ts.map +1 -1
  158. package/lib/blobManager.js +259 -105
  159. package/lib/blobManager.js.map +1 -1
  160. package/lib/connectionTelemetry.d.ts.map +1 -1
  161. package/lib/connectionTelemetry.js +11 -9
  162. package/lib/connectionTelemetry.js.map +1 -1
  163. package/lib/containerHandleContext.d.ts.map +1 -1
  164. package/lib/containerHandleContext.js +3 -1
  165. package/lib/containerHandleContext.js.map +1 -1
  166. package/lib/containerRuntime.d.ts +110 -78
  167. package/lib/containerRuntime.d.ts.map +1 -1
  168. package/lib/containerRuntime.js +340 -334
  169. package/lib/containerRuntime.js.map +1 -1
  170. package/lib/dataStore.d.ts.map +1 -1
  171. package/lib/dataStore.js +11 -9
  172. package/lib/dataStore.js.map +1 -1
  173. package/lib/dataStoreContext.d.ts +2 -1
  174. package/lib/dataStoreContext.d.ts.map +1 -1
  175. package/lib/dataStoreContext.js +41 -24
  176. package/lib/dataStoreContext.js.map +1 -1
  177. package/lib/dataStoreContexts.d.ts.map +1 -1
  178. package/lib/dataStoreContexts.js +7 -3
  179. package/lib/dataStoreContexts.js.map +1 -1
  180. package/lib/dataStoreRegistry.d.ts.map +1 -1
  181. package/lib/dataStoreRegistry.js +3 -1
  182. package/lib/dataStoreRegistry.js.map +1 -1
  183. package/lib/dataStores.d.ts +12 -9
  184. package/lib/dataStores.d.ts.map +1 -1
  185. package/lib/dataStores.js +75 -52
  186. package/lib/dataStores.js.map +1 -1
  187. package/lib/deltaScheduler.d.ts.map +1 -1
  188. package/lib/deltaScheduler.js +9 -4
  189. package/lib/deltaScheduler.js.map +1 -1
  190. package/lib/garbageCollection.d.ts +57 -42
  191. package/lib/garbageCollection.d.ts.map +1 -1
  192. package/lib/garbageCollection.js +364 -232
  193. package/lib/garbageCollection.js.map +1 -1
  194. package/lib/garbageCollectionConstants.d.ts +23 -0
  195. package/lib/garbageCollectionConstants.d.ts.map +1 -0
  196. package/lib/garbageCollectionConstants.js +33 -0
  197. package/lib/garbageCollectionConstants.js.map +1 -0
  198. package/lib/garbageCollectionHelpers.d.ts +15 -0
  199. package/lib/garbageCollectionHelpers.d.ts.map +1 -0
  200. package/lib/garbageCollectionHelpers.js +23 -0
  201. package/lib/garbageCollectionHelpers.js.map +1 -0
  202. package/lib/gcSweepReadyUsageDetection.d.ts +5 -5
  203. package/lib/gcSweepReadyUsageDetection.d.ts.map +1 -1
  204. package/lib/gcSweepReadyUsageDetection.js +15 -11
  205. package/lib/gcSweepReadyUsageDetection.js.map +1 -1
  206. package/lib/index.d.ts +4 -3
  207. package/lib/index.d.ts.map +1 -1
  208. package/lib/index.js +3 -3
  209. package/lib/index.js.map +1 -1
  210. package/lib/opLifecycle/batchManager.d.ts +42 -0
  211. package/lib/opLifecycle/batchManager.d.ts.map +1 -0
  212. package/lib/opLifecycle/batchManager.js +120 -0
  213. package/lib/opLifecycle/batchManager.js.map +1 -0
  214. package/lib/opLifecycle/definitions.d.ts +64 -0
  215. package/lib/opLifecycle/definitions.d.ts.map +1 -0
  216. package/lib/opLifecycle/definitions.js +6 -0
  217. package/lib/opLifecycle/definitions.js.map +1 -0
  218. package/lib/opLifecycle/index.d.ts +12 -0
  219. package/lib/opLifecycle/index.d.ts.map +1 -0
  220. package/lib/opLifecycle/index.js +11 -0
  221. package/lib/opLifecycle/index.js.map +1 -0
  222. package/lib/{opCompressor.d.ts → opLifecycle/opCompressor.d.ts} +3 -3
  223. package/lib/opLifecycle/opCompressor.d.ts.map +1 -0
  224. package/lib/opLifecycle/opCompressor.js +63 -0
  225. package/lib/opLifecycle/opCompressor.js.map +1 -0
  226. package/lib/{opDecompressor.d.ts → opLifecycle/opDecompressor.d.ts} +2 -1
  227. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -0
  228. package/lib/{opDecompressor.js → opLifecycle/opDecompressor.js} +37 -21
  229. package/lib/opLifecycle/opDecompressor.js.map +1 -0
  230. package/lib/opLifecycle/opSplitter.d.ts +49 -0
  231. package/lib/opLifecycle/opSplitter.d.ts.map +1 -0
  232. package/lib/opLifecycle/opSplitter.js +168 -0
  233. package/lib/opLifecycle/opSplitter.js.map +1 -0
  234. package/lib/opLifecycle/outbox.d.ts +52 -0
  235. package/lib/opLifecycle/outbox.d.ts.map +1 -0
  236. package/lib/opLifecycle/outbox.js +160 -0
  237. package/lib/opLifecycle/outbox.js.map +1 -0
  238. package/lib/opLifecycle/remoteMessageProcessor.d.ts +26 -0
  239. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -0
  240. package/lib/opLifecycle/remoteMessageProcessor.js +91 -0
  241. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -0
  242. package/lib/opProperties.d.ts.map +1 -1
  243. package/lib/opProperties.js +1 -3
  244. package/lib/opProperties.js.map +1 -1
  245. package/lib/orderedClientElection.d.ts.map +1 -1
  246. package/lib/orderedClientElection.js +10 -4
  247. package/lib/orderedClientElection.js.map +1 -1
  248. package/lib/packageVersion.d.ts +1 -1
  249. package/lib/packageVersion.js +1 -1
  250. package/lib/packageVersion.js.map +1 -1
  251. package/lib/pendingStateManager.d.ts +4 -13
  252. package/lib/pendingStateManager.d.ts.map +1 -1
  253. package/lib/pendingStateManager.js +134 -161
  254. package/lib/pendingStateManager.js.map +1 -1
  255. package/lib/runWhileConnectedCoordinator.d.ts.map +1 -1
  256. package/lib/runWhileConnectedCoordinator.js.map +1 -1
  257. package/lib/runningSummarizer.d.ts.map +1 -1
  258. package/lib/runningSummarizer.js +35 -23
  259. package/lib/runningSummarizer.js.map +1 -1
  260. package/lib/scheduleManager.d.ts +0 -1
  261. package/lib/scheduleManager.d.ts.map +1 -1
  262. package/lib/scheduleManager.js +11 -21
  263. package/lib/scheduleManager.js.map +1 -1
  264. package/lib/serializedSnapshotStorage.d.ts.map +1 -1
  265. package/lib/serializedSnapshotStorage.js +3 -1
  266. package/lib/serializedSnapshotStorage.js.map +1 -1
  267. package/lib/summarizer.d.ts +2 -3
  268. package/lib/summarizer.d.ts.map +1 -1
  269. package/lib/summarizer.js +39 -18
  270. package/lib/summarizer.js.map +1 -1
  271. package/lib/summarizerClientElection.d.ts +1 -2
  272. package/lib/summarizerClientElection.d.ts.map +1 -1
  273. package/lib/summarizerClientElection.js +3 -30
  274. package/lib/summarizerClientElection.js.map +1 -1
  275. package/lib/summarizerHandle.d.ts.map +1 -1
  276. package/lib/summarizerHandle.js.map +1 -1
  277. package/lib/summarizerHeuristics.d.ts.map +1 -1
  278. package/lib/summarizerHeuristics.js +6 -9
  279. package/lib/summarizerHeuristics.js.map +1 -1
  280. package/lib/summarizerTypes.d.ts +22 -25
  281. package/lib/summarizerTypes.d.ts.map +1 -1
  282. package/lib/summarizerTypes.js.map +1 -1
  283. package/lib/summaryCollection.d.ts.map +1 -1
  284. package/lib/summaryCollection.js +18 -8
  285. package/lib/summaryCollection.js.map +1 -1
  286. package/lib/summaryFormat.d.ts.map +1 -1
  287. package/lib/summaryFormat.js +20 -13
  288. package/lib/summaryFormat.js.map +1 -1
  289. package/lib/summaryGenerator.d.ts.map +1 -1
  290. package/lib/summaryGenerator.js +32 -14
  291. package/lib/summaryGenerator.js.map +1 -1
  292. package/lib/summaryManager.d.ts.map +1 -1
  293. package/lib/summaryManager.js +21 -9
  294. package/lib/summaryManager.js.map +1 -1
  295. package/lib/throttler.d.ts +2 -2
  296. package/lib/throttler.d.ts.map +1 -1
  297. package/lib/throttler.js +4 -4
  298. package/lib/throttler.js.map +1 -1
  299. package/package.json +28 -38
  300. package/prettier.config.cjs +1 -1
  301. package/src/batchTracker.ts +55 -50
  302. package/src/blobManager.ts +802 -541
  303. package/src/connectionTelemetry.ts +280 -249
  304. package/src/containerHandleContext.ts +27 -29
  305. package/src/containerRuntime.ts +3125 -2982
  306. package/src/dataStore.ts +172 -159
  307. package/src/dataStoreContext.ts +1049 -992
  308. package/src/dataStoreContexts.ts +178 -161
  309. package/src/dataStoreRegistry.ts +25 -20
  310. package/src/dataStores.ts +785 -711
  311. package/src/deltaScheduler.ts +158 -150
  312. package/src/garbageCollection.ts +1797 -1558
  313. package/src/garbageCollectionConstants.ts +38 -0
  314. package/src/garbageCollectionHelpers.ts +37 -0
  315. package/src/gcSweepReadyUsageDetection.ts +90 -84
  316. package/src/index.ts +68 -69
  317. package/src/opLifecycle/batchManager.ts +167 -0
  318. package/src/opLifecycle/definitions.ts +70 -0
  319. package/src/opLifecycle/index.ts +18 -0
  320. package/src/opLifecycle/opCompressor.ts +82 -0
  321. package/src/opLifecycle/opDecompressor.ts +124 -0
  322. package/src/opLifecycle/opSplitter.ts +238 -0
  323. package/src/opLifecycle/outbox.ts +228 -0
  324. package/src/opLifecycle/remoteMessageProcessor.ts +106 -0
  325. package/src/opProperties.ts +11 -9
  326. package/src/orderedClientElection.ts +489 -457
  327. package/src/packageVersion.ts +1 -1
  328. package/src/pendingStateManager.ts +379 -381
  329. package/src/runWhileConnectedCoordinator.ts +78 -71
  330. package/src/runningSummarizer.ts +619 -582
  331. package/src/scheduleManager.ts +299 -280
  332. package/src/serializedSnapshotStorage.ts +116 -111
  333. package/src/summarizer.ts +417 -381
  334. package/src/summarizerClientElection.ts +107 -129
  335. package/src/summarizerHandle.ts +11 -9
  336. package/src/summarizerHeuristics.ts +183 -186
  337. package/src/summarizerTypes.ts +344 -333
  338. package/src/summaryCollection.ts +378 -349
  339. package/src/summaryFormat.ts +146 -127
  340. package/src/summaryGenerator.ts +464 -406
  341. package/src/summaryManager.ts +377 -348
  342. package/src/throttler.ts +131 -122
  343. package/tsconfig.esnext.json +6 -6
  344. package/tsconfig.json +9 -13
  345. package/dist/batchManager.d.ts +0 -42
  346. package/dist/batchManager.d.ts.map +0 -1
  347. package/dist/batchManager.js +0 -83
  348. package/dist/batchManager.js.map +0 -1
  349. package/dist/opCompressor.d.ts.map +0 -1
  350. package/dist/opCompressor.js +0 -50
  351. package/dist/opCompressor.js.map +0 -1
  352. package/dist/opDecompressor.d.ts.map +0 -1
  353. package/dist/opDecompressor.js.map +0 -1
  354. package/lib/batchManager.d.ts +0 -42
  355. package/lib/batchManager.d.ts.map +0 -1
  356. package/lib/batchManager.js +0 -79
  357. package/lib/batchManager.js.map +0 -1
  358. package/lib/opCompressor.d.ts.map +0 -1
  359. package/lib/opCompressor.js +0 -46
  360. package/lib/opCompressor.js.map +0 -1
  361. package/lib/opDecompressor.d.ts.map +0 -1
  362. package/lib/opDecompressor.js.map +0 -1
  363. package/src/batchManager.ts +0 -108
  364. package/src/opCompressor.ts +0 -59
  365. package/src/opDecompressor.ts +0 -82
@@ -1,79 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { OpCompressor } from "./opCompressor";
6
- /**
7
- * Helper class that manages partial batch & rollback.
8
- */
9
- export class BatchManager {
10
- constructor(logger, options) {
11
- this.logger = logger;
12
- this.options = options;
13
- this.pendingBatch = [];
14
- this.batchContentSize = 0;
15
- this.opCompressor = new OpCompressor(logger);
16
- }
17
- get length() { return this.pendingBatch.length; }
18
- push(message) {
19
- var _a, _b, _c, _d, _e, _f;
20
- const contentSize = this.batchContentSize + ((_b = (_a = message.contents) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0);
21
- const opCount = this.pendingBatch.length;
22
- // Attempt to estimate batch size, aka socket message size.
23
- // Each op has pretty large envelope, estimating to be 200 bytes.
24
- // Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.
25
- // Not taking it into account, as compression work should help there - compressed payload will be
26
- // initially stored as base64, and that requires only 2 extra escape characters.
27
- const socketMessageSize = contentSize + 200 * opCount;
28
- // If we were provided soft limit, check for exceeding it.
29
- // But only if we have any ops, as the intention here is to flush existing ops (on exceeding this limit)
30
- // and start over. That's not an option if we have no ops.
31
- // If compression is enabled, the soft and hard limit are ignored and the message will be pushed anyways.
32
- // Cases where the message is still too large will be handled by the maxConsecutiveReconnects path.
33
- if (this.options.softLimit !== undefined
34
- && this.length > 0
35
- && socketMessageSize >= this.options.softLimit
36
- && Infinity === ((_d = (_c = this.options.compressionOptions) === null || _c === void 0 ? void 0 : _c.minimumBatchSizeInBytes) !== null && _d !== void 0 ? _d : Infinity)) {
37
- return false;
38
- }
39
- if (socketMessageSize >= this.options.hardLimit
40
- && Infinity === ((_f = (_e = this.options.compressionOptions) === null || _e === void 0 ? void 0 : _e.minimumBatchSizeInBytes) !== null && _f !== void 0 ? _f : Infinity)) {
41
- return false;
42
- }
43
- this.batchContentSize = contentSize;
44
- this.pendingBatch.push(message);
45
- return true;
46
- }
47
- get empty() { return this.pendingBatch.length === 0; }
48
- popBatch() {
49
- const batch = this.pendingBatch;
50
- const size = this.batchContentSize;
51
- this.pendingBatch = [];
52
- this.batchContentSize = 0;
53
- if (batch.length > 0
54
- && this.options.compressionOptions !== undefined
55
- && this.options.compressionOptions.minimumBatchSizeInBytes < size) {
56
- return this.opCompressor.compressBatch(batch, size);
57
- }
58
- return batch;
59
- }
60
- /**
61
- * Capture the pending state at this point
62
- */
63
- checkpoint() {
64
- const startPoint = this.pendingBatch.length;
65
- return {
66
- rollback: (process) => {
67
- var _a, _b;
68
- for (let i = this.pendingBatch.length; i > startPoint;) {
69
- i--;
70
- const message = this.pendingBatch[i];
71
- this.batchContentSize -= (_b = (_a = message.contents) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
72
- process(message);
73
- }
74
- this.pendingBatch.length = startPoint;
75
- },
76
- };
77
- }
78
- }
79
- //# sourceMappingURL=batchManager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"batchManager.js","sourceRoot":"","sources":["../src/batchManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IBatchMessage } from \"@fluidframework/container-definitions\";\nimport { ContainerRuntimeMessage, ICompressionRuntimeOptions } from \"./containerRuntime\";\nimport { OpCompressor } from \"./opCompressor\";\n\n/**\n * Message type used by BatchManager\n */\nexport type BatchMessage = IBatchMessage & {\n localOpMetadata: unknown;\n deserializedContent: ContainerRuntimeMessage;\n referenceSequenceNumber: number;\n};\n\nexport interface IBatchManagerOptions {\n readonly hardLimit: number;\n readonly softLimit?: number;\n readonly compressionOptions?: ICompressionRuntimeOptions;\n}\n\n/**\n * Helper class that manages partial batch & rollback.\n */\nexport class BatchManager {\n private readonly opCompressor: OpCompressor;\n private pendingBatch: BatchMessage [] = [];\n private batchContentSize = 0;\n\n public get length() { return this.pendingBatch.length; }\n\n constructor(public readonly logger: ITelemetryLogger, public readonly options: IBatchManagerOptions) {\n this.opCompressor = new OpCompressor(logger);\n }\n\n public push(message: BatchMessage): boolean {\n const contentSize = this.batchContentSize + (message.contents?.length ?? 0);\n const opCount = this.pendingBatch.length;\n\n // Attempt to estimate batch size, aka socket message size.\n // Each op has pretty large envelope, estimating to be 200 bytes.\n // Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.\n // Not taking it into account, as compression work should help there - compressed payload will be\n // initially stored as base64, and that requires only 2 extra escape characters.\n const socketMessageSize = contentSize + 200 * opCount;\n\n // If we were provided soft limit, check for exceeding it.\n // But only if we have any ops, as the intention here is to flush existing ops (on exceeding this limit)\n // and start over. That's not an option if we have no ops.\n // If compression is enabled, the soft and hard limit are ignored and the message will be pushed anyways.\n // Cases where the message is still too large will be handled by the maxConsecutiveReconnects path.\n if (this.options.softLimit !== undefined\n && this.length > 0\n && socketMessageSize >= this.options.softLimit\n && Infinity === (this.options.compressionOptions?.minimumBatchSizeInBytes ?? Infinity)) {\n return false;\n }\n\n if (socketMessageSize >= this.options.hardLimit\n && Infinity === (this.options.compressionOptions?.minimumBatchSizeInBytes ?? Infinity)) {\n return false;\n }\n\n this.batchContentSize = contentSize;\n this.pendingBatch.push(message);\n return true;\n }\n\n public get empty() { return this.pendingBatch.length === 0; }\n\n public popBatch() {\n const batch = this.pendingBatch;\n const size = this.batchContentSize;\n this.pendingBatch = [];\n this.batchContentSize = 0;\n\n if (batch.length > 0\n && this.options.compressionOptions !== undefined\n && this.options.compressionOptions.minimumBatchSizeInBytes < size) {\n return this.opCompressor.compressBatch(batch, size);\n }\n\n return batch;\n }\n\n /**\n * Capture the pending state at this point\n */\n public checkpoint() {\n const startPoint = this.pendingBatch.length;\n return {\n rollback: (process: (message: BatchMessage) => void) => {\n for (let i = this.pendingBatch.length; i > startPoint;) {\n i--;\n const message = this.pendingBatch[i];\n this.batchContentSize -= message.contents?.length ?? 0;\n process(message);\n }\n\n this.pendingBatch.length = startPoint;\n },\n };\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"opCompressor.d.ts","sourceRoot":"","sources":["../src/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAItE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;;;GAIG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,oBAAoB,CAAK;gBAErB,MAAM,EAAE,gBAAgB;IAI7B,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,EAAE,MAAM,GAAG,YAAY,EAAE;CAiCtF"}
@@ -1,46 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
- import { IsoBuffer } from "@fluidframework/common-utils";
6
- import { ChildLogger } from "@fluidframework/telemetry-utils";
7
- import { compress } from "lz4js";
8
- import { CompressionAlgorithms } from "./containerRuntime";
9
- /**
10
- * Compresses batches of ops. It generates a single compressed op that contains
11
- * the contents of each op in the batch. It then submits empty ops for each original
12
- * op to reserve sequence numbers.
13
- */
14
- export class OpCompressor {
15
- constructor(logger) {
16
- this.compressedBatchCount = 0;
17
- this.logger = ChildLogger.create(logger, "OpCompressor");
18
- }
19
- compressBatch(batch, originalLength) {
20
- const batchToSend = [];
21
- this.compressedBatchCount++;
22
- const batchedContents = [];
23
- for (const message of batch) {
24
- batchedContents.push(message.deserializedContent);
25
- }
26
- const compressionStart = Date.now();
27
- const contentsAsBuffer = new TextEncoder().encode(JSON.stringify(batchedContents));
28
- const compressedContents = compress(contentsAsBuffer);
29
- const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
30
- const duration = Date.now() - compressionStart;
31
- if (originalLength > 200000 || this.compressedBatchCount % 100) {
32
- this.logger.sendPerformanceEvent({
33
- eventName: "CompressedBatch",
34
- duration,
35
- sizeBeforeCompression: originalLength,
36
- sizeAfterCompression: compressedContent.length,
37
- });
38
- }
39
- batchToSend.push(Object.assign(Object.assign({}, batch[0]), { contents: JSON.stringify({ packedContents: compressedContent }), metadata: Object.assign(Object.assign({}, batch[0].metadata), { compressed: true }), compression: CompressionAlgorithms.lz4 }));
40
- for (const message of batch.slice(1)) {
41
- batchToSend.push(Object.assign(Object.assign({}, message), { contents: undefined }));
42
- }
43
- return batchToSend;
44
- }
45
- }
46
- //# sourceMappingURL=opCompressor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"opCompressor.js","sourceRoot":"","sources":["../src/opCompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,OAAO,EAAE,qBAAqB,EAA2B,MAAM,oBAAoB,CAAC;AAEpF;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAIrB,YAAY,MAAwB;QAF5B,yBAAoB,GAAG,CAAC,CAAC;QAG7B,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC7D,CAAC;IAEM,aAAa,CAAC,KAAqB,EAAE,cAAsB;QAC9D,MAAM,WAAW,GAAmB,EAAE,CAAC;QACvC,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,MAAM,eAAe,GAA8B,EAAE,CAAC;QACtD,KAAK,MAAM,OAAO,IAAI,KAAK,EAAE;YACzB,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;SACrD;QAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACpC,MAAM,gBAAgB,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC;QACnF,MAAM,kBAAkB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QACtD,MAAM,iBAAiB,GAAG,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC;QAE/C,IAAI,cAAc,GAAG,MAAM,IAAI,IAAI,CAAC,oBAAoB,GAAG,GAAG,EAAE;YAC5D,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC;gBAC7B,SAAS,EAAE,iBAAiB;gBAC5B,QAAQ;gBACR,qBAAqB,EAAE,cAAc;gBACrC,oBAAoB,EAAE,iBAAiB,CAAC,MAAM;aACjD,CAAC,CAAC;SACN;QAED,WAAW,CAAC,IAAI,iCAAM,KAAK,CAAC,CAAC,CAAC,KAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,cAAc,EAAE,iBAAiB,EAAE,CAAC,EAC5E,QAAQ,kCAAO,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAE,UAAU,EAAE,IAAI,KAClD,WAAW,EAAE,qBAAqB,CAAC,GAAG,IAAG,CAAC;QAE7D,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YAClC,WAAW,CAAC,IAAI,iCAAM,OAAO,KAAE,QAAQ,EAAE,SAAS,IAAG,CAAC;SACzD;QAED,OAAO,WAAW,CAAC;IACvB,CAAC;CACJ","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IsoBuffer } from \"@fluidframework/common-utils\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { compress } from \"lz4js\";\nimport { BatchMessage } from \"./batchManager\";\nimport { CompressionAlgorithms, ContainerRuntimeMessage } from \"./containerRuntime\";\n\n/**\n * Compresses batches of ops. It generates a single compressed op that contains\n * the contents of each op in the batch. It then submits empty ops for each original\n * op to reserve sequence numbers.\n */\nexport class OpCompressor {\n private readonly logger;\n private compressedBatchCount = 0;\n\n constructor(logger: ITelemetryLogger) {\n this.logger = ChildLogger.create(logger, \"OpCompressor\");\n }\n\n public compressBatch(batch: BatchMessage[], originalLength: number): BatchMessage[] {\n const batchToSend: BatchMessage[] = [];\n this.compressedBatchCount++;\n const batchedContents: ContainerRuntimeMessage[] = [];\n for (const message of batch) {\n batchedContents.push(message.deserializedContent);\n }\n\n const compressionStart = Date.now();\n const contentsAsBuffer = new TextEncoder().encode(JSON.stringify(batchedContents));\n const compressedContents = compress(contentsAsBuffer);\n const compressedContent = IsoBuffer.from(compressedContents).toString(\"base64\");\n const duration = Date.now() - compressionStart;\n\n if (originalLength > 200000 || this.compressedBatchCount % 100) {\n this.logger.sendPerformanceEvent({\n eventName: \"CompressedBatch\",\n duration,\n sizeBeforeCompression: originalLength,\n sizeAfterCompression: compressedContent.length,\n });\n }\n\n batchToSend.push({ ...batch[0], contents: JSON.stringify({ packedContents: compressedContent }),\n metadata: { ...batch[0].metadata, compressed: true },\n compression: CompressionAlgorithms.lz4 });\n\n for (const message of batch.slice(1)) {\n batchToSend.push({ ...message, contents: undefined });\n }\n\n return batchToSend;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"opDecompressor.d.ts","sourceRoot":"","sources":["../src/opDecompressor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAIjF;;;;;;;GAOG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,cAAc,CAAK;IAEpB,cAAc,CAAC,OAAO,EAAE,yBAAyB,GAAG,yBAAyB;CA0DvF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"opDecompressor.js","sourceRoot":"","sources":["../src/opDecompressor.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { decompress } from \"lz4js\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { assert, IsoBuffer, Uint8ArrayToString } from \"@fluidframework/common-utils\";\nimport { CompressionAlgorithms } from \".\";\n\n/**\n * State machine that \"unrolls\" contents of compressed batches of ops after decompressing them.\n * This class relies on some implicit contracts defined below:\n * 1. A compressed batch will have its first message with batch metadata set to true and compressed set to true\n * 2. Messages in the middle of a compressed batch will have neither batch metadata nor the compression property set\n * 3. The final message of a batch will have batch metadata set to false\n * 4. An individually compressed op will have undefined batch metadata and compression set to true\n */\nexport class OpDecompressor {\n private activeBatch = false;\n private rootMessageContents: any | undefined;\n private processedCount = 0;\n\n public processMessage(message: ISequencedDocumentMessage): ISequencedDocumentMessage {\n // We're checking for compression = true or top level compression property so\n // that we can enable compression without waiting on all ordering services\n // to pick up protocol change. Eventually only the top level property should\n // be used.\n if (message.metadata?.batch === true\n && (message.metadata?.compressed || message.compression !== undefined)) {\n // Beginning of a compressed batch\n assert(this.activeBatch === false, \"shouldn't have multiple active batches\");\n if (message.compression) {\n // lz4 is the only supported compression algorithm for now\n assert(message.compression === CompressionAlgorithms.lz4,\n \"lz4 is currently the only supported compression algorithm\");\n }\n\n this.activeBatch = true;\n\n const contents = IsoBuffer.from(message.contents.packedContents, \"base64\");\n const decompressedMessage = decompress(contents);\n const intoString = Uint8ArrayToString(decompressedMessage);\n const asObj = JSON.parse(intoString);\n this.rootMessageContents = asObj;\n\n return { ...message, contents: this.rootMessageContents[this.processedCount++] };\n }\n\n if (this.rootMessageContents !== undefined && message.metadata?.batch === undefined && this.activeBatch) {\n // Continuation of compressed batch\n return { ...message, contents: this.rootMessageContents[this.processedCount++] };\n }\n\n if (this.rootMessageContents !== undefined && message.metadata?.batch === false) {\n // End of compressed batch\n const returnMessage = { ...message,\n contents: this.rootMessageContents[this.processedCount++] };\n\n this.activeBatch = false;\n this.rootMessageContents = undefined;\n this.processedCount = 0;\n\n return returnMessage;\n }\n\n if (message.metadata?.batch === undefined &&\n (message.metadata?.compressed || message.compression === CompressionAlgorithms.lz4)) {\n // Single compressed message\n assert(this.activeBatch === false, \"shouldn't receive compressed message in middle of a batch\");\n\n const contents = IsoBuffer.from(message.contents.packedContents, \"base64\");\n const decompressedMessage = decompress(contents);\n const intoString = new TextDecoder().decode(decompressedMessage);\n const asObj = JSON.parse(intoString);\n\n return { ...message, contents: asObj[0] };\n }\n\n return message;\n }\n}\n"]}
@@ -1,108 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- import { ITelemetryLogger } from "@fluidframework/common-definitions";
7
- import { IBatchMessage } from "@fluidframework/container-definitions";
8
- import { ContainerRuntimeMessage, ICompressionRuntimeOptions } from "./containerRuntime";
9
- import { OpCompressor } from "./opCompressor";
10
-
11
- /**
12
- * Message type used by BatchManager
13
- */
14
- export type BatchMessage = IBatchMessage & {
15
- localOpMetadata: unknown;
16
- deserializedContent: ContainerRuntimeMessage;
17
- referenceSequenceNumber: number;
18
- };
19
-
20
- export interface IBatchManagerOptions {
21
- readonly hardLimit: number;
22
- readonly softLimit?: number;
23
- readonly compressionOptions?: ICompressionRuntimeOptions;
24
- }
25
-
26
- /**
27
- * Helper class that manages partial batch & rollback.
28
- */
29
- export class BatchManager {
30
- private readonly opCompressor: OpCompressor;
31
- private pendingBatch: BatchMessage [] = [];
32
- private batchContentSize = 0;
33
-
34
- public get length() { return this.pendingBatch.length; }
35
-
36
- constructor(public readonly logger: ITelemetryLogger, public readonly options: IBatchManagerOptions) {
37
- this.opCompressor = new OpCompressor(logger);
38
- }
39
-
40
- public push(message: BatchMessage): boolean {
41
- const contentSize = this.batchContentSize + (message.contents?.length ?? 0);
42
- const opCount = this.pendingBatch.length;
43
-
44
- // Attempt to estimate batch size, aka socket message size.
45
- // Each op has pretty large envelope, estimating to be 200 bytes.
46
- // Also content will be strigified, and that adds a lot of overhead due to a lot of escape characters.
47
- // Not taking it into account, as compression work should help there - compressed payload will be
48
- // initially stored as base64, and that requires only 2 extra escape characters.
49
- const socketMessageSize = contentSize + 200 * opCount;
50
-
51
- // If we were provided soft limit, check for exceeding it.
52
- // But only if we have any ops, as the intention here is to flush existing ops (on exceeding this limit)
53
- // and start over. That's not an option if we have no ops.
54
- // If compression is enabled, the soft and hard limit are ignored and the message will be pushed anyways.
55
- // Cases where the message is still too large will be handled by the maxConsecutiveReconnects path.
56
- if (this.options.softLimit !== undefined
57
- && this.length > 0
58
- && socketMessageSize >= this.options.softLimit
59
- && Infinity === (this.options.compressionOptions?.minimumBatchSizeInBytes ?? Infinity)) {
60
- return false;
61
- }
62
-
63
- if (socketMessageSize >= this.options.hardLimit
64
- && Infinity === (this.options.compressionOptions?.minimumBatchSizeInBytes ?? Infinity)) {
65
- return false;
66
- }
67
-
68
- this.batchContentSize = contentSize;
69
- this.pendingBatch.push(message);
70
- return true;
71
- }
72
-
73
- public get empty() { return this.pendingBatch.length === 0; }
74
-
75
- public popBatch() {
76
- const batch = this.pendingBatch;
77
- const size = this.batchContentSize;
78
- this.pendingBatch = [];
79
- this.batchContentSize = 0;
80
-
81
- if (batch.length > 0
82
- && this.options.compressionOptions !== undefined
83
- && this.options.compressionOptions.minimumBatchSizeInBytes < size) {
84
- return this.opCompressor.compressBatch(batch, size);
85
- }
86
-
87
- return batch;
88
- }
89
-
90
- /**
91
- * Capture the pending state at this point
92
- */
93
- public checkpoint() {
94
- const startPoint = this.pendingBatch.length;
95
- return {
96
- rollback: (process: (message: BatchMessage) => void) => {
97
- for (let i = this.pendingBatch.length; i > startPoint;) {
98
- i--;
99
- const message = this.pendingBatch[i];
100
- this.batchContentSize -= message.contents?.length ?? 0;
101
- process(message);
102
- }
103
-
104
- this.pendingBatch.length = startPoint;
105
- },
106
- };
107
- }
108
- }
@@ -1,59 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- import { ITelemetryLogger } from "@fluidframework/common-definitions";
7
- import { IsoBuffer } from "@fluidframework/common-utils";
8
- import { ChildLogger } from "@fluidframework/telemetry-utils";
9
- import { compress } from "lz4js";
10
- import { BatchMessage } from "./batchManager";
11
- import { CompressionAlgorithms, ContainerRuntimeMessage } from "./containerRuntime";
12
-
13
- /**
14
- * Compresses batches of ops. It generates a single compressed op that contains
15
- * the contents of each op in the batch. It then submits empty ops for each original
16
- * op to reserve sequence numbers.
17
- */
18
- export class OpCompressor {
19
- private readonly logger;
20
- private compressedBatchCount = 0;
21
-
22
- constructor(logger: ITelemetryLogger) {
23
- this.logger = ChildLogger.create(logger, "OpCompressor");
24
- }
25
-
26
- public compressBatch(batch: BatchMessage[], originalLength: number): BatchMessage[] {
27
- const batchToSend: BatchMessage[] = [];
28
- this.compressedBatchCount++;
29
- const batchedContents: ContainerRuntimeMessage[] = [];
30
- for (const message of batch) {
31
- batchedContents.push(message.deserializedContent);
32
- }
33
-
34
- const compressionStart = Date.now();
35
- const contentsAsBuffer = new TextEncoder().encode(JSON.stringify(batchedContents));
36
- const compressedContents = compress(contentsAsBuffer);
37
- const compressedContent = IsoBuffer.from(compressedContents).toString("base64");
38
- const duration = Date.now() - compressionStart;
39
-
40
- if (originalLength > 200000 || this.compressedBatchCount % 100) {
41
- this.logger.sendPerformanceEvent({
42
- eventName: "CompressedBatch",
43
- duration,
44
- sizeBeforeCompression: originalLength,
45
- sizeAfterCompression: compressedContent.length,
46
- });
47
- }
48
-
49
- batchToSend.push({ ...batch[0], contents: JSON.stringify({ packedContents: compressedContent }),
50
- metadata: { ...batch[0].metadata, compressed: true },
51
- compression: CompressionAlgorithms.lz4 });
52
-
53
- for (const message of batch.slice(1)) {
54
- batchToSend.push({ ...message, contents: undefined });
55
- }
56
-
57
- return batchToSend;
58
- }
59
- }
@@ -1,82 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- import { decompress } from "lz4js";
7
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
- import { assert, IsoBuffer, Uint8ArrayToString } from "@fluidframework/common-utils";
9
- import { CompressionAlgorithms } from ".";
10
-
11
- /**
12
- * State machine that "unrolls" contents of compressed batches of ops after decompressing them.
13
- * This class relies on some implicit contracts defined below:
14
- * 1. A compressed batch will have its first message with batch metadata set to true and compressed set to true
15
- * 2. Messages in the middle of a compressed batch will have neither batch metadata nor the compression property set
16
- * 3. The final message of a batch will have batch metadata set to false
17
- * 4. An individually compressed op will have undefined batch metadata and compression set to true
18
- */
19
- export class OpDecompressor {
20
- private activeBatch = false;
21
- private rootMessageContents: any | undefined;
22
- private processedCount = 0;
23
-
24
- public processMessage(message: ISequencedDocumentMessage): ISequencedDocumentMessage {
25
- // We're checking for compression = true or top level compression property so
26
- // that we can enable compression without waiting on all ordering services
27
- // to pick up protocol change. Eventually only the top level property should
28
- // be used.
29
- if (message.metadata?.batch === true
30
- && (message.metadata?.compressed || message.compression !== undefined)) {
31
- // Beginning of a compressed batch
32
- assert(this.activeBatch === false, "shouldn't have multiple active batches");
33
- if (message.compression) {
34
- // lz4 is the only supported compression algorithm for now
35
- assert(message.compression === CompressionAlgorithms.lz4,
36
- "lz4 is currently the only supported compression algorithm");
37
- }
38
-
39
- this.activeBatch = true;
40
-
41
- const contents = IsoBuffer.from(message.contents.packedContents, "base64");
42
- const decompressedMessage = decompress(contents);
43
- const intoString = Uint8ArrayToString(decompressedMessage);
44
- const asObj = JSON.parse(intoString);
45
- this.rootMessageContents = asObj;
46
-
47
- return { ...message, contents: this.rootMessageContents[this.processedCount++] };
48
- }
49
-
50
- if (this.rootMessageContents !== undefined && message.metadata?.batch === undefined && this.activeBatch) {
51
- // Continuation of compressed batch
52
- return { ...message, contents: this.rootMessageContents[this.processedCount++] };
53
- }
54
-
55
- if (this.rootMessageContents !== undefined && message.metadata?.batch === false) {
56
- // End of compressed batch
57
- const returnMessage = { ...message,
58
- contents: this.rootMessageContents[this.processedCount++] };
59
-
60
- this.activeBatch = false;
61
- this.rootMessageContents = undefined;
62
- this.processedCount = 0;
63
-
64
- return returnMessage;
65
- }
66
-
67
- if (message.metadata?.batch === undefined &&
68
- (message.metadata?.compressed || message.compression === CompressionAlgorithms.lz4)) {
69
- // Single compressed message
70
- assert(this.activeBatch === false, "shouldn't receive compressed message in middle of a batch");
71
-
72
- const contents = IsoBuffer.from(message.contents.packedContents, "base64");
73
- const decompressedMessage = decompress(contents);
74
- const intoString = new TextDecoder().decode(decompressedMessage);
75
- const asObj = JSON.parse(intoString);
76
-
77
- return { ...message, contents: asObj[0] };
78
- }
79
-
80
- return message;
81
- }
82
- }