@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
@@ -28,7 +28,7 @@ import {
28
28
  IContainerRuntime,
29
29
  IContainerRuntimeEvents,
30
30
  } from "@fluidframework/container-runtime-definitions";
31
- import { AttachState } from "@fluidframework/container-definitions";
31
+ import { AttachState, ICriticalContainerError } from "@fluidframework/container-definitions";
32
32
  import {
33
33
  ChildLogger,
34
34
  loggerToMonitoringContext,
@@ -40,6 +40,7 @@ import {
40
40
  ISummaryTreeWithStats,
41
41
  ITelemetryContext,
42
42
  } from "@fluidframework/runtime-definitions";
43
+ import { GenericError } from "@fluidframework/container-utils";
43
44
  import { ContainerRuntime, TombstoneResponseHeaderKey } from "./containerRuntime";
44
45
  import { sendGCUnexpectedUsageEvent, sweepAttachmentBlobsKey, throwOnTombstoneLoadKey } from "./gc";
45
46
  import { Throttler, formExponentialFn, IThrottler } from "./throttler";
@@ -132,14 +133,13 @@ interface PendingBlob {
132
133
  status: PendingBlobStatus;
133
134
  storageId?: string;
134
135
  handleP: Deferred<IFluidHandle<ArrayBufferLike>>;
135
- uploadP: Promise<ICreateBlobResponse>;
136
- localUploadTime?: number;
137
- serverUploadTime?: number;
136
+ uploadP?: Promise<ICreateBlobResponse>;
137
+ uploadTime?: number;
138
138
  minTTLInSeconds?: number;
139
139
  }
140
140
 
141
141
  export interface IPendingBlobs {
142
- [id: string]: { blob: string };
142
+ [id: string]: { blob: string; uploadTime?: number; minTTLInSeconds?: number };
143
143
  }
144
144
 
145
145
  export interface IBlobManagerEvents {
@@ -191,6 +191,8 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
191
191
  */
192
192
  private readonly tombstonedBlobs: Set<string> = new Set();
193
193
 
194
+ private readonly sendBlobAttachOp: (localId: string, storageId?: string) => void;
195
+
194
196
  constructor(
195
197
  private readonly routeContext: IFluidHandleContext,
196
198
  snapshot: IBlobManagerLoadInfo,
@@ -205,7 +207,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
205
207
  * knowledge of which they cannot request the blob from storage. It's important that this op is sequenced
206
208
  * before any ops that reference the local ID, otherwise, an invalid handle could be added to the document.
207
209
  */
208
- private readonly sendBlobAttachOp: (localId: string, storageId?: string) => void,
210
+ sendBlobAttachOp: (localId: string, storageId?: string) => void,
209
211
  // Called when a blob node is requested. blobPath is the path of the blob's node in GC's graph.
210
212
  // blobPath's format - `/<BlobManager.basePath>/<blobId>`.
211
213
  private readonly blobRequested: (blobPath: string) => void,
@@ -214,7 +216,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
214
216
  private readonly isBlobDeleted: (blobPath: string) => boolean,
215
217
  private readonly runtime: IBlobManagerRuntime,
216
218
  stashedBlobs: IPendingBlobs = {},
217
- private readonly getCurrentReferenceTimestampMs: () => number | undefined,
219
+ private readonly closeContainer: (error?: ICriticalContainerError) => void,
218
220
  ) {
219
221
  super();
220
222
  this.mc = loggerToMonitoringContext(ChildLogger.create(this.runtime.logger, "BlobManager"));
@@ -230,6 +232,21 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
230
232
  // Begin uploading stashed blobs from previous container instance
231
233
  Object.entries(stashedBlobs).forEach(([localId, entry]) => {
232
234
  const blob = stringToBuffer(entry.blob, "base64");
235
+ if (entry.minTTLInSeconds && entry.uploadTime) {
236
+ const timeLapseSinceLocalUpload = (Date.now() - entry.uploadTime) / 1000;
237
+ // stashed entries with more than half-life in storage will not be reuploaded
238
+ if (entry.minTTLInSeconds - timeLapseSinceLocalUpload > entry.minTTLInSeconds / 2) {
239
+ this.pendingBlobs.set(localId, {
240
+ blob,
241
+ status: PendingBlobStatus.OfflinePendingOp,
242
+ handleP: new Deferred(),
243
+ uploadP: undefined,
244
+ uploadTime: entry.uploadTime,
245
+ minTTLInSeconds: entry.minTTLInSeconds,
246
+ });
247
+ return;
248
+ }
249
+ }
233
250
  this.pendingBlobs.set(localId, {
234
251
  blob,
235
252
  status: PendingBlobStatus.OfflinePendingUpload,
@@ -237,6 +254,37 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
237
254
  uploadP: this.uploadBlob(localId, blob),
238
255
  });
239
256
  });
257
+
258
+ this.sendBlobAttachOp = (localId: string, blobId?: string) => {
259
+ const pendingEntry = this.pendingBlobs.get(localId);
260
+ if (pendingEntry?.uploadTime && pendingEntry?.minTTLInSeconds) {
261
+ const secondsSinceUpload = (Date.now() - pendingEntry.uploadTime) / 1000;
262
+ const expired = pendingEntry.minTTLInSeconds - secondsSinceUpload < 0;
263
+ this.mc.logger.sendTelemetryEvent({
264
+ eventName: "sendBlobAttach",
265
+ entryStatus: pendingEntry.status,
266
+ secondsSinceUpload,
267
+ minTTLInSeconds: pendingEntry.minTTLInSeconds,
268
+ expired,
269
+ });
270
+ if (expired) {
271
+ // we want to avoid submitting ops with broken handles
272
+ this.closeContainer(
273
+ new GenericError(
274
+ "Trying to submit a BlobAttach for expired blob",
275
+ undefined,
276
+ {
277
+ localId,
278
+ blobId,
279
+ entryStatus: pendingEntry.status,
280
+ secondsSinceUpload,
281
+ },
282
+ ),
283
+ );
284
+ }
285
+ }
286
+ return sendBlobAttachOp(localId, blobId);
287
+ };
240
288
  }
241
289
 
242
290
  private get pendingOfflineUploads() {
@@ -428,9 +476,8 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
428
476
  0x386 /* Must have pending blob entry for uploaded blob */,
429
477
  );
430
478
  entry.storageId = response.id;
431
- entry.localUploadTime = Date.now();
479
+ entry.uploadTime = Date.now();
432
480
  entry.minTTLInSeconds = response.minTTLInSeconds;
433
- entry.serverUploadTime = this.getCurrentReferenceTimestampMs();
434
481
  if (this.runtime.connected) {
435
482
  if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
436
483
  // Send a blob attach op. This serves two purposes:
@@ -438,7 +485,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
438
485
  // until its storage ID is added to the next summary.
439
486
  // 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
440
487
  // blob from the server via the storage ID.
441
- this.logTimeInfo(entry, "sendBlobAttachResolveTTL");
442
488
  this.sendBlobAttachOp(localId, response.id);
443
489
  if (this.storageIds.has(response.id)) {
444
490
  // The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
@@ -512,7 +558,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
512
558
  * is called on reconnection.
513
559
  */
514
560
  if (entry.status !== PendingBlobStatus.OnlinePendingOp) {
515
- this.logTimeInfo(entry, "sendBlobAttachTransitionOfflineTTL");
516
561
  this.sendBlobAttachOp(localId, entry.storageId);
517
562
  }
518
563
 
@@ -534,9 +579,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
534
579
  const { localId, blobId }: { localId?: string; blobId?: string } = metadata;
535
580
  assert(localId !== undefined, 0x50d /* local ID not available on reSubmit */);
536
581
  const pendingEntry = this.pendingBlobs.get(localId);
537
- if (pendingEntry) {
538
- this.logTimeInfo(pendingEntry, "sendBlobAttachResubmitTTL");
539
- }
582
+
540
583
  if (!blobId) {
541
584
  // We submitted this op while offline. The blob should have been uploaded by now.
542
585
  assert(
@@ -549,32 +592,6 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
549
592
  return this.sendBlobAttachOp(localId, blobId);
550
593
  }
551
594
 
552
- private logTimeInfo(pendingEntry: PendingBlob, eventName: string) {
553
- let timeLapseSinceLocalUpload: number = 0;
554
- let timeLapseSinceServerUpload: number = 0;
555
- let expiredUsingLocalTime;
556
- let expiredUsingServerTime;
557
- if (pendingEntry.localUploadTime) {
558
- timeLapseSinceLocalUpload = (Date.now() - pendingEntry.localUploadTime) / 1000;
559
- expiredUsingLocalTime =
560
- (pendingEntry.minTTLInSeconds ?? 0) - timeLapseSinceLocalUpload < 0 ? true : false;
561
- }
562
- if (pendingEntry.serverUploadTime) {
563
- timeLapseSinceServerUpload = (Date.now() - pendingEntry.serverUploadTime) / 1000;
564
- expiredUsingServerTime =
565
- (pendingEntry.minTTLInSeconds ?? 0) - timeLapseSinceServerUpload < 0 ? true : false;
566
- }
567
- this.mc.logger.sendTelemetryEvent({
568
- eventName,
569
- entryStatus: pendingEntry.status,
570
- timeLapseSinceLocalUpload,
571
- timeLapseSinceServerUpload,
572
- minTTLInSeconds: pendingEntry.minTTLInSeconds,
573
- expiredUsingLocalTime,
574
- expiredUsingServerTime,
575
- });
576
- }
577
-
578
595
  public processBlobAttachOp(message: ISequencedDocumentMessage, local: boolean) {
579
596
  const localId = message.metadata?.localId;
580
597
  const blobId = message.metadata?.blobId;
@@ -887,7 +904,13 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
887
904
  public getPendingBlobs(): IPendingBlobs {
888
905
  const blobs = {};
889
906
  for (const [key, entry] of this.pendingBlobs) {
890
- blobs[key] = { blob: bufferToString(entry.blob, "base64") };
907
+ blobs[key] = entry.minTTLInSeconds
908
+ ? {
909
+ blob: bufferToString(entry.blob, "base64"),
910
+ uploadTime: entry.uploadTime,
911
+ minTTLInSeconds: entry.minTTLInSeconds,
912
+ }
913
+ : { blob: bufferToString(entry.blob, "base64") };
891
914
  }
892
915
  return blobs;
893
916
  }