@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.
- package/.mocharc.js +12 -0
- package/dist/batchTracker.js +1 -1
- package/dist/batchTracker.js.map +1 -1
- package/dist/blobManager.d.ts +7 -1
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +34 -17
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +3 -104
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +83 -395
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStore.d.ts +1 -1
- package/dist/dataStore.d.ts.map +1 -1
- package/dist/dataStore.js +2 -3
- package/dist/dataStore.js.map +1 -1
- package/dist/dataStoreContext.d.ts +3 -5
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +13 -23
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/dataStores.d.ts +1 -1
- package/dist/dataStores.d.ts.map +1 -1
- package/dist/dataStores.js +3 -8
- package/dist/dataStores.js.map +1 -1
- package/dist/garbageCollection.d.ts +37 -6
- package/dist/garbageCollection.d.ts.map +1 -1
- package/dist/garbageCollection.js +61 -65
- package/dist/garbageCollection.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +15 -2
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runningSummarizer.d.ts +14 -0
- package/dist/runningSummarizer.d.ts.map +1 -1
- package/dist/runningSummarizer.js +25 -0
- package/dist/runningSummarizer.js.map +1 -1
- package/dist/scheduleManager.d.ts +28 -0
- package/dist/scheduleManager.d.ts.map +1 -0
- package/dist/scheduleManager.js +235 -0
- package/dist/scheduleManager.js.map +1 -0
- package/dist/summarizer.d.ts.map +1 -1
- package/dist/summarizer.js +33 -3
- package/dist/summarizer.js.map +1 -1
- package/dist/summaryCollection.js +1 -1
- package/dist/summaryCollection.js.map +1 -1
- package/dist/summaryGenerator.js +1 -1
- package/dist/summaryGenerator.js.map +1 -1
- package/dist/summaryManager.d.ts.map +1 -1
- package/dist/summaryManager.js +20 -5
- package/dist/summaryManager.js.map +1 -1
- package/lib/batchTracker.js +1 -1
- package/lib/batchTracker.js.map +1 -1
- package/lib/blobManager.d.ts +7 -1
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +35 -18
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +3 -104
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +84 -395
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStore.d.ts +1 -1
- package/lib/dataStore.d.ts.map +1 -1
- package/lib/dataStore.js +2 -3
- package/lib/dataStore.js.map +1 -1
- package/lib/dataStoreContext.d.ts +3 -5
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +13 -23
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/dataStores.d.ts +1 -1
- package/lib/dataStores.d.ts.map +1 -1
- package/lib/dataStores.js +3 -8
- package/lib/dataStores.js.map +1 -1
- package/lib/garbageCollection.d.ts +37 -6
- package/lib/garbageCollection.d.ts.map +1 -1
- package/lib/garbageCollection.js +47 -52
- package/lib/garbageCollection.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +15 -2
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/runningSummarizer.d.ts +14 -0
- package/lib/runningSummarizer.d.ts.map +1 -1
- package/lib/runningSummarizer.js +25 -0
- package/lib/runningSummarizer.js.map +1 -1
- package/lib/scheduleManager.d.ts +28 -0
- package/lib/scheduleManager.d.ts.map +1 -0
- package/lib/scheduleManager.js +231 -0
- package/lib/scheduleManager.js.map +1 -0
- package/lib/summarizer.d.ts.map +1 -1
- package/lib/summarizer.js +35 -5
- package/lib/summarizer.js.map +1 -1
- package/lib/summaryCollection.js +1 -1
- package/lib/summaryCollection.js.map +1 -1
- package/lib/summaryGenerator.js +1 -1
- package/lib/summaryGenerator.js.map +1 -1
- package/lib/summaryManager.d.ts.map +1 -1
- package/lib/summaryManager.js +20 -5
- package/lib/summaryManager.js.map +1 -1
- package/package.json +32 -19
- package/src/batchTracker.ts +1 -1
- package/src/blobManager.ts +43 -17
- package/src/containerRuntime.ts +113 -547
- package/src/dataStore.ts +1 -4
- package/src/dataStoreContext.ts +10 -25
- package/src/dataStores.ts +13 -19
- package/src/garbageCollection.ts +64 -69
- package/src/index.ts +1 -2
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +18 -2
- package/src/runningSummarizer.ts +33 -1
- package/src/scheduleManager.ts +294 -0
- package/src/summarizer.ts +46 -10
- package/src/summaryCollection.ts +1 -1
- package/src/summaryGenerator.ts +1 -1
- package/src/summaryManager.ts +20 -5
package/src/blobManager.ts
CHANGED
|
@@ -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
|
-
|
|
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),
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
382
|
+
assert(!!entry, 0x389 /* No pending blob entry */);
|
|
369
383
|
assert([PendingBlobStatus.OnlinePendingUpload, PendingBlobStatus.OnlinePendingOp].includes(entry.status),
|
|
370
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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(
|
|
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,
|
|
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,
|
|
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
|
}
|