@fluidframework/container-runtime 2.0.0-internal.1.0.0.82693 → 2.0.0-internal.1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/.mocharc.js +12 -0
  2. package/dist/batchTracker.js +1 -1
  3. package/dist/batchTracker.js.map +1 -1
  4. package/dist/blobManager.d.ts +7 -1
  5. package/dist/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager.js +34 -17
  7. package/dist/blobManager.js.map +1 -1
  8. package/dist/containerRuntime.d.ts +3 -104
  9. package/dist/containerRuntime.d.ts.map +1 -1
  10. package/dist/containerRuntime.js +83 -395
  11. package/dist/containerRuntime.js.map +1 -1
  12. package/dist/dataStore.d.ts +1 -1
  13. package/dist/dataStore.d.ts.map +1 -1
  14. package/dist/dataStore.js +2 -3
  15. package/dist/dataStore.js.map +1 -1
  16. package/dist/dataStoreContext.d.ts +3 -5
  17. package/dist/dataStoreContext.d.ts.map +1 -1
  18. package/dist/dataStoreContext.js +13 -23
  19. package/dist/dataStoreContext.js.map +1 -1
  20. package/dist/dataStores.d.ts +1 -1
  21. package/dist/dataStores.d.ts.map +1 -1
  22. package/dist/dataStores.js +3 -8
  23. package/dist/dataStores.js.map +1 -1
  24. package/dist/garbageCollection.d.ts +37 -6
  25. package/dist/garbageCollection.d.ts.map +1 -1
  26. package/dist/garbageCollection.js +61 -65
  27. package/dist/garbageCollection.js.map +1 -1
  28. package/dist/index.d.ts +2 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +3 -2
  31. package/dist/index.js.map +1 -1
  32. package/dist/packageVersion.d.ts +1 -1
  33. package/dist/packageVersion.d.ts.map +1 -1
  34. package/dist/packageVersion.js +1 -1
  35. package/dist/packageVersion.js.map +1 -1
  36. package/dist/pendingStateManager.d.ts.map +1 -1
  37. package/dist/pendingStateManager.js +15 -2
  38. package/dist/pendingStateManager.js.map +1 -1
  39. package/dist/runningSummarizer.d.ts +14 -0
  40. package/dist/runningSummarizer.d.ts.map +1 -1
  41. package/dist/runningSummarizer.js +25 -0
  42. package/dist/runningSummarizer.js.map +1 -1
  43. package/dist/scheduleManager.d.ts +28 -0
  44. package/dist/scheduleManager.d.ts.map +1 -0
  45. package/dist/scheduleManager.js +235 -0
  46. package/dist/scheduleManager.js.map +1 -0
  47. package/dist/summarizer.d.ts.map +1 -1
  48. package/dist/summarizer.js +33 -3
  49. package/dist/summarizer.js.map +1 -1
  50. package/dist/summaryCollection.js +1 -1
  51. package/dist/summaryCollection.js.map +1 -1
  52. package/dist/summaryGenerator.js +1 -1
  53. package/dist/summaryGenerator.js.map +1 -1
  54. package/dist/summaryManager.d.ts.map +1 -1
  55. package/dist/summaryManager.js +20 -5
  56. package/dist/summaryManager.js.map +1 -1
  57. package/lib/batchTracker.js +1 -1
  58. package/lib/batchTracker.js.map +1 -1
  59. package/lib/blobManager.d.ts +7 -1
  60. package/lib/blobManager.d.ts.map +1 -1
  61. package/lib/blobManager.js +35 -18
  62. package/lib/blobManager.js.map +1 -1
  63. package/lib/containerRuntime.d.ts +3 -104
  64. package/lib/containerRuntime.d.ts.map +1 -1
  65. package/lib/containerRuntime.js +84 -395
  66. package/lib/containerRuntime.js.map +1 -1
  67. package/lib/dataStore.d.ts +1 -1
  68. package/lib/dataStore.d.ts.map +1 -1
  69. package/lib/dataStore.js +2 -3
  70. package/lib/dataStore.js.map +1 -1
  71. package/lib/dataStoreContext.d.ts +3 -5
  72. package/lib/dataStoreContext.d.ts.map +1 -1
  73. package/lib/dataStoreContext.js +13 -23
  74. package/lib/dataStoreContext.js.map +1 -1
  75. package/lib/dataStores.d.ts +1 -1
  76. package/lib/dataStores.d.ts.map +1 -1
  77. package/lib/dataStores.js +3 -8
  78. package/lib/dataStores.js.map +1 -1
  79. package/lib/garbageCollection.d.ts +37 -6
  80. package/lib/garbageCollection.d.ts.map +1 -1
  81. package/lib/garbageCollection.js +47 -52
  82. package/lib/garbageCollection.js.map +1 -1
  83. package/lib/index.d.ts +2 -1
  84. package/lib/index.d.ts.map +1 -1
  85. package/lib/index.js +2 -1
  86. package/lib/index.js.map +1 -1
  87. package/lib/packageVersion.d.ts +1 -1
  88. package/lib/packageVersion.d.ts.map +1 -1
  89. package/lib/packageVersion.js +1 -1
  90. package/lib/packageVersion.js.map +1 -1
  91. package/lib/pendingStateManager.d.ts.map +1 -1
  92. package/lib/pendingStateManager.js +15 -2
  93. package/lib/pendingStateManager.js.map +1 -1
  94. package/lib/runningSummarizer.d.ts +14 -0
  95. package/lib/runningSummarizer.d.ts.map +1 -1
  96. package/lib/runningSummarizer.js +25 -0
  97. package/lib/runningSummarizer.js.map +1 -1
  98. package/lib/scheduleManager.d.ts +28 -0
  99. package/lib/scheduleManager.d.ts.map +1 -0
  100. package/lib/scheduleManager.js +231 -0
  101. package/lib/scheduleManager.js.map +1 -0
  102. package/lib/summarizer.d.ts.map +1 -1
  103. package/lib/summarizer.js +35 -5
  104. package/lib/summarizer.js.map +1 -1
  105. package/lib/summaryCollection.js +1 -1
  106. package/lib/summaryCollection.js.map +1 -1
  107. package/lib/summaryGenerator.js +1 -1
  108. package/lib/summaryGenerator.js.map +1 -1
  109. package/lib/summaryManager.d.ts.map +1 -1
  110. package/lib/summaryManager.js +20 -5
  111. package/lib/summaryManager.js.map +1 -1
  112. package/package.json +32 -19
  113. package/src/batchTracker.ts +1 -1
  114. package/src/blobManager.ts +43 -17
  115. package/src/containerRuntime.ts +113 -547
  116. package/src/dataStore.ts +1 -4
  117. package/src/dataStoreContext.ts +10 -25
  118. package/src/dataStores.ts +13 -19
  119. package/src/garbageCollection.ts +64 -69
  120. package/src/index.ts +1 -2
  121. package/src/packageVersion.ts +1 -1
  122. package/src/pendingStateManager.ts +18 -2
  123. package/src/runningSummarizer.ts +33 -1
  124. package/src/scheduleManager.ts +294 -0
  125. package/src/summarizer.ts +46 -10
  126. package/src/summaryCollection.ts +1 -1
  127. package/src/summaryGenerator.ts +1 -1
  128. package/src/summaryManager.ts +20 -5
@@ -9,7 +9,7 @@ import { IDocumentStorageService } from "@fluidframework/driver-definitions";
9
9
  import { ICreateBlobResponse, ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
10
10
  import { generateHandleContextPath, SummaryTreeBuilder } from "@fluidframework/runtime-utils";
11
11
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
12
- import { assert, Deferred, TypedEventEmitter } from "@fluidframework/common-utils";
12
+ import { assert, bufferToString, Deferred, stringToBuffer, TypedEventEmitter } from "@fluidframework/common-utils";
13
13
  import { IContainerRuntime, IContainerRuntimeEvents } from "@fluidframework/container-runtime-definitions";
14
14
  import { AttachState } from "@fluidframework/container-definitions";
15
15
  import { ChildLogger, PerformanceEvent } from "@fluidframework/telemetry-utils";
@@ -102,6 +102,8 @@ interface PendingBlob {
102
102
  uploadP: Promise<ICreateBlobResponse>;
103
103
  }
104
104
 
105
+ export interface IPendingBlobs { [id: string]: { blob: string; }; }
106
+
105
107
  export class BlobManager {
106
108
  public static readonly basePath = "_blobs";
107
109
  private static readonly redirectTableBlobName = ".redirectTable";
@@ -154,10 +156,22 @@ export class BlobManager {
154
156
  // of the format `/<BlobManager.basePath>/<blobId>`.
155
157
  private readonly gcNodeUpdated: (blobPath: string) => void,
156
158
  private readonly runtime: IBlobManagerRuntime,
159
+ stashedBlobs: IPendingBlobs = {},
157
160
  ) {
158
161
  this.logger = ChildLogger.create(this.runtime.logger, "BlobManager");
159
162
  this.runtime.on("disconnected", () => this.onDisconnected());
160
163
  this.redirectTable = this.load(snapshot);
164
+
165
+ // Begin uploading stashed blobs from previous container instance
166
+ Object.entries(stashedBlobs).forEach(([localId, entry]) => {
167
+ const blob = stringToBuffer(entry.blob, "base64");
168
+ this.pendingBlobs.set(localId, {
169
+ blob,
170
+ status: PendingBlobStatus.OfflinePendingUpload,
171
+ handleP: new Deferred(),
172
+ uploadP: this.uploadBlob(localId, blob),
173
+ });
174
+ });
161
175
  }
162
176
 
163
177
  private get pendingOfflineUploads() {
@@ -219,7 +233,7 @@ export class BlobManager {
219
233
  // For a detached container, entries are inserted into the redirect table with an undefined storage ID.
220
234
  // For an attached container, entries are inserted w/storage ID after the BlobAttach op round-trips.
221
235
  assert(!undefinedValueInTable || this.runtime.attachState === AttachState.Detached && ids.size === 0,
222
- "'redirectTable' must contain only undefined while detached / defined values while attached");
236
+ 0x382 /* 'redirectTable' must contain only undefined while detached / defined values while attached */);
223
237
 
224
238
  return ids as Set<string>;
225
239
  }
@@ -231,7 +245,7 @@ export class BlobManager {
231
245
  }
232
246
  let storageId;
233
247
  if (this.runtime.attachState === AttachState.Detached) {
234
- assert(this.redirectTable.has(blobId), "requesting unknown blobs");
248
+ assert(this.redirectTable.has(blobId), 0x383 /* requesting unknown blobs */);
235
249
 
236
250
  // Blobs created while the container is detached are stored in IDetachedBlobStorage.
237
251
  // The 'IDocumentStorageService.readBlob()' call below will retrieve these via localId.
@@ -256,7 +270,7 @@ export class BlobManager {
256
270
 
257
271
  private getBlobHandle(id: string): IFluidHandle<ArrayBufferLike> {
258
272
  assert(this.redirectTable.has(id) || this.pendingBlobs.has(id),
259
- "requesting handle for unknown blob");
273
+ 0x384 /* requesting handle for unknown blob */);
260
274
  return new BlobHandle(
261
275
  `${BlobManager.basePath}/${id}`,
262
276
  this.routeContext,
@@ -282,7 +296,7 @@ export class BlobManager {
282
296
  await new Promise<void>((resolve) => this.runtime.once("attached", resolve));
283
297
  }
284
298
  assert(this.runtime.attachState === AttachState.Attached,
285
- "For clarity and paranoid defense against adding future attachment states");
299
+ 0x385 /* For clarity and paranoid defense against adding future attachment states */);
286
300
 
287
301
  // Create a local ID for each blob. This is used to support blobs if/when the client goes
288
302
  // offline since we don't have the ID from storage yet. If online flow succeeds this won't be used.
@@ -314,7 +328,7 @@ export class BlobManager {
314
328
  const entry = this.pendingBlobs.get(localId);
315
329
  assert(entry?.status === PendingBlobStatus.OnlinePendingUpload ||
316
330
  entry?.status === PendingBlobStatus.OfflinePendingUpload,
317
- "Must have pending blob entry for uploaded blob");
331
+ 0x386 /* Must have pending blob entry for uploaded blob */);
318
332
  entry.storageId = response.id;
319
333
  if (this.runtime.connected) {
320
334
  if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
@@ -348,7 +362,7 @@ export class BlobManager {
348
362
 
349
363
  private async onUploadReject(localId: string, error) {
350
364
  const entry = this.pendingBlobs.get(localId);
351
- assert(!!entry, "Must have pending blob entry for blob which failed to upload");
365
+ assert(!!entry, 0x387 /* Must have pending blob entry for blob which failed to upload */);
352
366
  if (!this.runtime.connected) {
353
367
  if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
354
368
  this.transitionToOffline(localId);
@@ -363,11 +377,11 @@ export class BlobManager {
363
377
  }
364
378
 
365
379
  private transitionToOffline(localId: string) {
366
- assert(!this.runtime.connected, "Must only transition to offline flow while runtime is disconnected");
380
+ assert(!this.runtime.connected, 0x388 /* Must only transition to offline flow while runtime is disconnected */);
367
381
  const entry = this.pendingBlobs.get(localId);
368
- assert(!!entry, "No pending blob entry");
382
+ assert(!!entry, 0x389 /* No pending blob entry */);
369
383
  assert([PendingBlobStatus.OnlinePendingUpload, PendingBlobStatus.OnlinePendingOp].includes(entry.status),
370
- "Blob must be in online flow to transition to offline flow");
384
+ 0x38a /* Blob must be in online flow to transition to offline flow */);
371
385
 
372
386
  entry.status = entry.status === PendingBlobStatus.OnlinePendingUpload
373
387
  ? PendingBlobStatus.OfflinePendingUpload
@@ -388,14 +402,14 @@ export class BlobManager {
388
402
  * @param metadata - op metadata containing storage and/or local IDs
389
403
  */
390
404
  public reSubmit(metadata: Record<string, unknown> | undefined) {
391
- assert(!!metadata, "Resubmitted ops must have metadata");
405
+ assert(!!metadata, 0x38b /* Resubmitted ops must have metadata */);
392
406
  const { blobId, localId }: { blobId?: string; localId?: string; } = metadata;
393
407
  if (!blobId) {
394
- assert(!!localId, "Submitted BlobAttach ops must have a blobId or localId");
408
+ assert(!!localId, 0x38c /* Submitted BlobAttach ops must have a blobId or localId */);
395
409
  // We submitted this op while offline. The blob should have been uploaded by now.
396
410
  const pendingEntry = this.pendingBlobs.get(localId);
397
411
  assert(pendingEntry?.status === PendingBlobStatus.OfflinePendingOp &&
398
- !!pendingEntry?.storageId, "blob must be uploaded before resubmitting BlobAttach op");
412
+ !!pendingEntry?.storageId, 0x38d /* blob must be uploaded before resubmitting BlobAttach op */);
399
413
  return this.sendBlobAttachOp(pendingEntry.storageId, localId);
400
414
  }
401
415
  return this.sendBlobAttachOp(blobId, localId);
@@ -413,10 +427,13 @@ export class BlobManager {
413
427
  if (message.metadata.localId === undefined) {
414
428
  // Since there is no local ID, we know this op was submitted while online.
415
429
  const waitingBlobs = this.opsInFlight.get(message.metadata.blobId);
416
- assert(!!waitingBlobs, "local online BlobAttach op with no pending blob");
430
+ assert(!!waitingBlobs, 0x38e /* local online BlobAttach op with no pending blob */);
417
431
  waitingBlobs.forEach((localId) => {
418
432
  const pendingBlobEntry = this.pendingBlobs.get(localId);
419
- assert(pendingBlobEntry !== undefined, "local online BlobAttach op with no pending blob entry");
433
+ assert(
434
+ pendingBlobEntry !== undefined,
435
+ 0x38f, /* local online BlobAttach op with no pending blob entry */
436
+ );
420
437
 
421
438
  // It's possible we transitioned to offline flow while waiting for this op.
422
439
  if (pendingBlobEntry.status === PendingBlobStatus.OnlinePendingOp) {
@@ -497,7 +514,7 @@ export class BlobManager {
497
514
  // Note that because of de-duping, there can be multiple localIds that all redirect to the same storageId or
498
515
  // a blob may be referenced via its storageId handle.
499
516
  for (const [localId, storageId] of this.redirectTable) {
500
- assert(!!storageId, "Must be attached to get GC data");
517
+ assert(!!storageId, 0x390 /* Must be attached to get GC data */);
501
518
  // Add node for the localId and add a route to the storageId node. The storageId node will have been
502
519
  // added above when adding nodes for this.blobIds.
503
520
  gcData.gcNodes[this.getBlobGCNodePath(localId)] = [this.getBlobGCNodePath(storageId)];
@@ -554,7 +571,8 @@ export class BlobManager {
554
571
  public setRedirectTable(table: Map<string, string>) {
555
572
  assert(this.runtime.attachState === AttachState.Detached,
556
573
  0x252 /* "redirect table can only be set in detached container" */);
557
- assert(this.redirectTable.size === table.size, "Redirect table size must match BlobManager's local ID count");
574
+ assert(this.redirectTable.size === table.size,
575
+ 0x391 /* Redirect table size must match BlobManager's local ID count */);
558
576
  for (const [localId, storageId] of table) {
559
577
  assert(this.redirectTable.has(localId), 0x254 /* "unrecognized id in redirect table" */);
560
578
  this.redirectTable.set(localId, storageId);
@@ -562,4 +580,12 @@ export class BlobManager {
562
580
  this.redirectTable.set(storageId, storageId);
563
581
  }
564
582
  }
583
+
584
+ public getPendingBlobs(): IPendingBlobs {
585
+ const blobs = {};
586
+ for (const [key, entry] of this.pendingBlobs) {
587
+ blobs[key] = { blob: bufferToString(entry.blob, "base64") };
588
+ }
589
+ return blobs;
590
+ }
565
591
  }