@fluidframework/container-runtime 2.40.0-336023 → 2.40.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/CHANGELOG.md +14 -0
- package/api-report/container-runtime.legacy.alpha.api.md +4 -0
- package/container-runtime.test-files.tar +0 -0
- package/dist/blobManager/blobManager.d.ts +31 -8
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +90 -17
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/channelCollection.d.ts +8 -2
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +29 -6
- package/dist/channelCollection.js.map +1 -1
- package/dist/compatUtils.d.ts +19 -10
- package/dist/compatUtils.d.ts.map +1 -1
- package/dist/compatUtils.js +39 -32
- package/dist/compatUtils.js.map +1 -1
- package/dist/containerRuntime.d.ts +29 -13
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +139 -149
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +12 -4
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +37 -18
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -0
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +20 -7
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +16 -20
- package/dist/opLifecycle/outbox.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 +22 -8
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +11 -16
- package/dist/pendingStateManager.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts +31 -8
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +91 -18
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/channelCollection.d.ts +8 -2
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +29 -6
- package/lib/channelCollection.js.map +1 -1
- package/lib/compatUtils.d.ts +19 -10
- package/lib/compatUtils.d.ts.map +1 -1
- package/lib/compatUtils.js +36 -29
- package/lib/compatUtils.js.map +1 -1
- package/lib/containerRuntime.d.ts +29 -13
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +60 -70
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +12 -4
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +38 -19
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -0
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +20 -7
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +16 -20
- package/lib/opLifecycle/outbox.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 +22 -8
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +11 -16
- package/lib/pendingStateManager.js.map +1 -1
- package/package.json +18 -18
- package/src/blobManager/blobManager.ts +141 -33
- package/src/channelCollection.ts +42 -6
- package/src/compatUtils.ts +53 -30
- package/src/containerRuntime.ts +102 -81
- package/src/dataStoreContext.ts +44 -25
- package/src/index.ts +1 -0
- package/src/opLifecycle/index.ts +1 -0
- package/src/opLifecycle/outbox.ts +42 -33
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +37 -20
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @fluidframework/container-runtime
|
|
2
2
|
|
|
3
|
+
## 2.40.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- IFluidHandleInternal.bind has been deprecated ([#24553](https://github.com/microsoft/FluidFramework/pull/24553)) [8a4362a7ed](https://github.com/microsoft/FluidFramework/commit/8a4362a7edef3a97fee13c9d23bea49448ba2a6a)
|
|
8
|
+
|
|
9
|
+
Handle binding is an internal concept used to make sure objects attach to the Container graph when their handle is stored in a DDS which is itself attached.
|
|
10
|
+
The source of the "bind" operation has been assumed to be any handle, but only one implementation is actually supported (`SharedObjectHandle`, not exported itself).
|
|
11
|
+
|
|
12
|
+
So the `bind` function is now deprecated on the `IFluidHandleInterface`, moving instead to internal types supporting the one valid implementation.
|
|
13
|
+
It's also deprecated on the various exported handle implementations that don't support it (each is either no-op, pass-through, or throwing).
|
|
14
|
+
|
|
15
|
+
No replacement is offered, this API was never meant to be called from outside of the Fluid Framework.
|
|
16
|
+
|
|
3
17
|
## 2.33.0
|
|
4
18
|
|
|
5
19
|
Dependency updates only.
|
|
@@ -338,6 +338,7 @@ export interface LoadContainerRuntimeParams {
|
|
|
338
338
|
containerScope?: FluidObject;
|
|
339
339
|
context: IContainerContext;
|
|
340
340
|
existing: boolean;
|
|
341
|
+
minVersionForCollab?: MinimumVersionForCollab;
|
|
341
342
|
provideEntryPoint: (containerRuntime: IContainerRuntime) => Promise<FluidObject>;
|
|
342
343
|
registryEntries: NamedFluidDataStoreRegistryEntries;
|
|
343
344
|
// @deprecated
|
|
@@ -345,6 +346,9 @@ export interface LoadContainerRuntimeParams {
|
|
|
345
346
|
runtimeOptions?: IContainerRuntimeOptions;
|
|
346
347
|
}
|
|
347
348
|
|
|
349
|
+
// @alpha @legacy
|
|
350
|
+
export type MinimumVersionForCollab = `${1 | 2}.${bigint}.${bigint}` | `${1 | 2}.${bigint}.${bigint}-${string}`;
|
|
351
|
+
|
|
348
352
|
// @alpha @deprecated @legacy (undocumented)
|
|
349
353
|
export type OmitAttributesVersions<T> = Omit<T, "snapshotFormatVersion" | "summaryFormatVersion">;
|
|
350
354
|
|
|
Binary file
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
6
5
|
import { IContainerRuntime, IContainerRuntimeEvents } from "@fluidframework/container-runtime-definitions/internal";
|
|
7
|
-
import type {
|
|
6
|
+
import type { IEventProvider, IFluidHandleContext, IFluidHandleInternal, IFluidHandleInternalPayloadPending, ILocalFluidHandle, ILocalFluidHandleEvents, Listenable, PayloadState } from "@fluidframework/core-interfaces/internal";
|
|
8
7
|
import { IDocumentStorageService, ICreateBlobResponse } from "@fluidframework/driver-definitions/internal";
|
|
9
8
|
import { IGarbageCollectionData, ISummaryTreeWithStats, ITelemetryContext, type ISequencedMessageEnvelope } from "@fluidframework/runtime-definitions/internal";
|
|
10
9
|
import { FluidHandleBase } from "@fluidframework/runtime-utils/internal";
|
|
@@ -16,7 +15,7 @@ import { type IBlobManagerLoadInfo } from "./blobManagerSnapSum.js";
|
|
|
16
15
|
* DataObject.request() recognizes requests in the form of `/blobs/<id>`
|
|
17
16
|
* and loads blob.
|
|
18
17
|
*/
|
|
19
|
-
export declare class BlobHandle extends FluidHandleBase<ArrayBufferLike> implements IFluidHandleInternalPayloadPending<ArrayBufferLike> {
|
|
18
|
+
export declare class BlobHandle extends FluidHandleBase<ArrayBufferLike> implements ILocalFluidHandle<ArrayBufferLike>, IFluidHandleInternalPayloadPending<ArrayBufferLike> {
|
|
20
19
|
readonly path: string;
|
|
21
20
|
readonly routeContext: IFluidHandleContext;
|
|
22
21
|
get: () => Promise<ArrayBufferLike>;
|
|
@@ -24,12 +23,27 @@ export declare class BlobHandle extends FluidHandleBase<ArrayBufferLike> impleme
|
|
|
24
23
|
private readonly onAttachGraph?;
|
|
25
24
|
private attached;
|
|
26
25
|
get isAttached(): boolean;
|
|
26
|
+
private _events;
|
|
27
|
+
get events(): Listenable<ILocalFluidHandleEvents>;
|
|
28
|
+
private _state;
|
|
29
|
+
get payloadState(): PayloadState;
|
|
30
|
+
/**
|
|
31
|
+
* The error property starts undefined, signalling that there has been no error yet.
|
|
32
|
+
* If an error occurs, the property will contain the error.
|
|
33
|
+
*/
|
|
34
|
+
private _payloadShareError;
|
|
35
|
+
get payloadShareError(): unknown;
|
|
27
36
|
readonly absolutePath: string;
|
|
28
37
|
constructor(path: string, routeContext: IFluidHandleContext, get: () => Promise<ArrayBufferLike>, payloadPending: boolean, onAttachGraph?: (() => void) | undefined);
|
|
38
|
+
readonly notifyShared: () => void;
|
|
39
|
+
readonly notifyFailed: (error: unknown) => void;
|
|
29
40
|
attachGraph(): void;
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated No replacement provided. Arbitrary handles may not serve as a bind source.
|
|
43
|
+
*/
|
|
30
44
|
bind(handle: IFluidHandleInternal): void;
|
|
31
45
|
}
|
|
32
|
-
export type IBlobManagerRuntime = Pick<IContainerRuntime, "attachState" | "connected" | "baseLogger" | "clientDetails" | "disposed"> &
|
|
46
|
+
export type IBlobManagerRuntime = Pick<IContainerRuntime, "attachState" | "connected" | "baseLogger" | "clientDetails" | "disposed"> & IEventProvider<IContainerRuntimeEvents>;
|
|
33
47
|
export interface IPendingBlobs {
|
|
34
48
|
[localId: string]: {
|
|
35
49
|
blob: string;
|
|
@@ -39,14 +53,14 @@ export interface IPendingBlobs {
|
|
|
39
53
|
acked?: boolean;
|
|
40
54
|
};
|
|
41
55
|
}
|
|
42
|
-
export interface IBlobManagerEvents
|
|
43
|
-
|
|
56
|
+
export interface IBlobManagerEvents {
|
|
57
|
+
noPendingBlobs: () => void;
|
|
44
58
|
}
|
|
45
59
|
export declare const blobManagerBasePath: "_blobs";
|
|
46
60
|
export declare class BlobManager {
|
|
47
61
|
private readonly mc;
|
|
48
62
|
private readonly publicEvents;
|
|
49
|
-
get events():
|
|
63
|
+
get events(): Listenable<IBlobManagerEvents>;
|
|
50
64
|
private readonly internalEvents;
|
|
51
65
|
/**
|
|
52
66
|
* Map of local IDs to storage IDs. Contains identity entries (storageId → storageId) for storage IDs. All requested IDs should
|
|
@@ -76,6 +90,7 @@ export declare class BlobManager {
|
|
|
76
90
|
private readonly localBlobIdGenerator;
|
|
77
91
|
private readonly pendingStashedBlobs;
|
|
78
92
|
readonly stashedBlobsUploadP: Promise<(void | ICreateBlobResponse)[]>;
|
|
93
|
+
private readonly createBlobPayloadPending;
|
|
79
94
|
constructor(props: {
|
|
80
95
|
readonly routeContext: IFluidHandleContext;
|
|
81
96
|
blobManagerLoadInfo: IBlobManagerLoadInfo;
|
|
@@ -103,10 +118,18 @@ export declare class BlobManager {
|
|
|
103
118
|
private createAbortError;
|
|
104
119
|
hasPendingStashedUploads(): boolean;
|
|
105
120
|
hasBlob(blobId: string): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Retrieve the blob with the given local blob id.
|
|
123
|
+
* @param blobId - The local blob id. Likely coming from a handle.
|
|
124
|
+
* @param payloadPending - Whether we suspect the payload may be pending and not available yet.
|
|
125
|
+
* @returns A promise which resolves to the blob contents
|
|
126
|
+
*/
|
|
106
127
|
getBlob(blobId: string, payloadPending: boolean): Promise<ArrayBufferLike>;
|
|
107
128
|
private getBlobHandle;
|
|
108
129
|
private createBlobDetached;
|
|
109
|
-
createBlob(blob: ArrayBufferLike, signal?: AbortSignal): Promise<
|
|
130
|
+
createBlob(blob: ArrayBufferLike, signal?: AbortSignal): Promise<IFluidHandleInternalPayloadPending<ArrayBufferLike>>;
|
|
131
|
+
private createBlobLegacy;
|
|
132
|
+
private createBlobWithPayloadPending;
|
|
110
133
|
private uploadBlob;
|
|
111
134
|
/**
|
|
112
135
|
* Set up a mapping in the redirect table from fromId to toId. Also, notify the runtime that a reference is added
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../../src/blobManager/blobManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../../src/blobManager/blobManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,15 @@ class BlobHandle extends internal_3.FluidHandleBase {
|
|
|
24
24
|
get isAttached() {
|
|
25
25
|
return this.routeContext.isAttached && this.attached;
|
|
26
26
|
}
|
|
27
|
+
get events() {
|
|
28
|
+
return (this._events ??= (0, client_utils_1.createEmitter)());
|
|
29
|
+
}
|
|
30
|
+
get payloadState() {
|
|
31
|
+
return this._state;
|
|
32
|
+
}
|
|
33
|
+
get payloadShareError() {
|
|
34
|
+
return this._payloadShareError;
|
|
35
|
+
}
|
|
27
36
|
constructor(path, routeContext, get, payloadPending, onAttachGraph) {
|
|
28
37
|
super();
|
|
29
38
|
this.path = path;
|
|
@@ -32,6 +41,15 @@ class BlobHandle extends internal_3.FluidHandleBase {
|
|
|
32
41
|
this.payloadPending = payloadPending;
|
|
33
42
|
this.onAttachGraph = onAttachGraph;
|
|
34
43
|
this.attached = false;
|
|
44
|
+
this._state = "pending";
|
|
45
|
+
this.notifyShared = () => {
|
|
46
|
+
this._state = "shared";
|
|
47
|
+
this._events?.emit("payloadShared");
|
|
48
|
+
};
|
|
49
|
+
this.notifyFailed = (error) => {
|
|
50
|
+
this._payloadShareError = error;
|
|
51
|
+
this._events?.emit("payloadShareFailed", error);
|
|
52
|
+
};
|
|
35
53
|
this.absolutePath = (0, internal_3.generateHandleContextPath)(path, this.routeContext);
|
|
36
54
|
}
|
|
37
55
|
attachGraph() {
|
|
@@ -40,6 +58,10 @@ class BlobHandle extends internal_3.FluidHandleBase {
|
|
|
40
58
|
this.onAttachGraph?.();
|
|
41
59
|
}
|
|
42
60
|
}
|
|
61
|
+
// eslint-disable-next-line jsdoc/require-description
|
|
62
|
+
/**
|
|
63
|
+
* @deprecated No replacement provided. Arbitrary handles may not serve as a bind source.
|
|
64
|
+
*/
|
|
43
65
|
bind(handle) {
|
|
44
66
|
throw new Error("Cannot bind to blob handle");
|
|
45
67
|
}
|
|
@@ -57,8 +79,8 @@ class BlobManager {
|
|
|
57
79
|
return this.publicEvents;
|
|
58
80
|
}
|
|
59
81
|
constructor(props) {
|
|
60
|
-
this.publicEvents =
|
|
61
|
-
this.internalEvents =
|
|
82
|
+
this.publicEvents = (0, client_utils_1.createEmitter)();
|
|
83
|
+
this.internalEvents = (0, client_utils_1.createEmitter)();
|
|
62
84
|
/**
|
|
63
85
|
* Blobs which we have not yet seen a BlobAttach op round-trip and not yet attached to a DDS.
|
|
64
86
|
*/
|
|
@@ -71,13 +93,14 @@ class BlobManager {
|
|
|
71
93
|
this.opsInFlight = new Map();
|
|
72
94
|
this.stopAttaching = false;
|
|
73
95
|
this.pendingStashedBlobs = new Map();
|
|
74
|
-
const { routeContext, blobManagerLoadInfo, storage, sendBlobAttachOp, blobRequested, isBlobDeleted, runtime, stashedBlobs, localBlobIdGenerator, } = props;
|
|
96
|
+
const { routeContext, blobManagerLoadInfo, storage, sendBlobAttachOp, blobRequested, isBlobDeleted, runtime, stashedBlobs, localBlobIdGenerator, createBlobPayloadPending, } = props;
|
|
75
97
|
this.routeContext = routeContext;
|
|
76
98
|
this.storage = storage;
|
|
77
99
|
this.blobRequested = blobRequested;
|
|
78
100
|
this.isBlobDeleted = isBlobDeleted;
|
|
79
101
|
this.runtime = runtime;
|
|
80
102
|
this.localBlobIdGenerator = localBlobIdGenerator ?? uuid_1.v4;
|
|
103
|
+
this.createBlobPayloadPending = createBlobPayloadPending;
|
|
81
104
|
this.mc = (0, internal_4.createChildMonitoringContext)({
|
|
82
105
|
logger: this.runtime.baseLogger,
|
|
83
106
|
namespace: "BlobManager",
|
|
@@ -169,6 +192,12 @@ class BlobManager {
|
|
|
169
192
|
hasBlob(blobId) {
|
|
170
193
|
return this.redirectTable.get(blobId) !== undefined;
|
|
171
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Retrieve the blob with the given local blob id.
|
|
197
|
+
* @param blobId - The local blob id. Likely coming from a handle.
|
|
198
|
+
* @param payloadPending - Whether we suspect the payload may be pending and not available yet.
|
|
199
|
+
* @returns A promise which resolves to the blob contents
|
|
200
|
+
*/
|
|
172
201
|
async getBlob(blobId, payloadPending) {
|
|
173
202
|
// Verify that the blob is not deleted, i.e., it has not been garbage collected. If it is, this will throw
|
|
174
203
|
// an error, failing the call.
|
|
@@ -191,7 +220,9 @@ class BlobManager {
|
|
|
191
220
|
else {
|
|
192
221
|
const attachedStorageId = this.redirectTable.get(blobId);
|
|
193
222
|
if (!payloadPending) {
|
|
194
|
-
|
|
223
|
+
// Only blob handles explicitly marked with pending payload are permitted to exist without
|
|
224
|
+
// yet knowing their storage id. Otherwise they must already be associated with a storage id.
|
|
225
|
+
(0, internal_1.assert)(attachedStorageId !== undefined, 0x11f /* "requesting unknown blobs" */);
|
|
195
226
|
}
|
|
196
227
|
// If we didn't find it in the redirectTable, assume the attach op is coming eventually and wait.
|
|
197
228
|
// We do this even if the local client doesn't have the blob payloadPending flag enabled, in case a
|
|
@@ -222,11 +253,11 @@ class BlobManager {
|
|
|
222
253
|
getBlobHandle(localId) {
|
|
223
254
|
(0, internal_1.assert)(this.redirectTable.has(localId) || this.pendingBlobs.has(localId), 0x384 /* requesting handle for unknown blob */);
|
|
224
255
|
const pending = this.pendingBlobs.get(localId);
|
|
225
|
-
// Create a callback function for once the
|
|
256
|
+
// Create a callback function for once the handle has been attached
|
|
226
257
|
const callback = pending
|
|
227
258
|
? () => {
|
|
228
259
|
pending.attached = true;
|
|
229
|
-
// Notify listeners (e.g. serialization process) that
|
|
260
|
+
// Notify listeners (e.g. serialization process) that handle has been attached
|
|
230
261
|
this.internalEvents.emit("handleAttached", pending);
|
|
231
262
|
this.deletePendingBlobMaybe(localId);
|
|
232
263
|
}
|
|
@@ -251,6 +282,11 @@ class BlobManager {
|
|
|
251
282
|
await new Promise((resolve) => this.runtime.once("attached", resolve));
|
|
252
283
|
}
|
|
253
284
|
(0, internal_1.assert)(this.runtime.attachState === container_definitions_1.AttachState.Attached, 0x385 /* For clarity and paranoid defense against adding future attachment states */);
|
|
285
|
+
return this.createBlobPayloadPending
|
|
286
|
+
? this.createBlobWithPayloadPending(blob)
|
|
287
|
+
: this.createBlobLegacy(blob, signal);
|
|
288
|
+
}
|
|
289
|
+
async createBlobLegacy(blob, signal) {
|
|
254
290
|
if (signal?.aborted) {
|
|
255
291
|
throw this.createAbortError();
|
|
256
292
|
}
|
|
@@ -277,6 +313,36 @@ class BlobManager {
|
|
|
277
313
|
signal?.removeEventListener("abort", abortListener);
|
|
278
314
|
});
|
|
279
315
|
}
|
|
316
|
+
createBlobWithPayloadPending(blob) {
|
|
317
|
+
const localId = this.localBlobIdGenerator();
|
|
318
|
+
const blobHandle = new BlobHandle(getGCNodePathFromBlobId(localId), this.routeContext, async () => blob, true, // payloadPending
|
|
319
|
+
() => {
|
|
320
|
+
const pendingEntry = {
|
|
321
|
+
blob,
|
|
322
|
+
handleP: new internal_1.Deferred(),
|
|
323
|
+
uploadP: this.uploadBlob(localId, blob),
|
|
324
|
+
attached: true,
|
|
325
|
+
acked: false,
|
|
326
|
+
opsent: false,
|
|
327
|
+
};
|
|
328
|
+
this.pendingBlobs.set(localId, pendingEntry);
|
|
329
|
+
});
|
|
330
|
+
const onProcessedBlobAttach = (_localId, _storageId) => {
|
|
331
|
+
if (_localId === localId) {
|
|
332
|
+
this.internalEvents.off("processedBlobAttach", onProcessedBlobAttach);
|
|
333
|
+
blobHandle.notifyShared();
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
this.internalEvents.on("processedBlobAttach", onProcessedBlobAttach);
|
|
337
|
+
const onUploadFailed = (_localId, error) => {
|
|
338
|
+
if (_localId === localId) {
|
|
339
|
+
this.internalEvents.off("uploadFailed", onUploadFailed);
|
|
340
|
+
blobHandle.notifyFailed(error);
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
this.internalEvents.on("uploadFailed", onUploadFailed);
|
|
344
|
+
return blobHandle;
|
|
345
|
+
}
|
|
280
346
|
async uploadBlob(localId, blob) {
|
|
281
347
|
return (0, internal_2.runWithRetry)(async () => {
|
|
282
348
|
try {
|
|
@@ -305,6 +371,7 @@ class BlobManager {
|
|
|
305
371
|
// the promise but not throw any error outside.
|
|
306
372
|
this.pendingBlobs.get(localId)?.handleP.reject(error);
|
|
307
373
|
this.deletePendingBlob(localId);
|
|
374
|
+
this.internalEvents.emit("uploadFailed", localId, error);
|
|
308
375
|
});
|
|
309
376
|
}
|
|
310
377
|
/**
|
|
@@ -366,7 +433,9 @@ class BlobManager {
|
|
|
366
433
|
// an existing blob, we don't have to wait for the op to be ack'd since this step has already
|
|
367
434
|
// happened before and so, the server won't delete it.
|
|
368
435
|
this.setRedirection(localId, response.id);
|
|
369
|
-
|
|
436
|
+
const blobHandle = this.getBlobHandle(localId);
|
|
437
|
+
blobHandle.notifyShared();
|
|
438
|
+
entry.handleP.resolve(blobHandle);
|
|
370
439
|
this.deletePendingBlobMaybe(localId);
|
|
371
440
|
}
|
|
372
441
|
else {
|
|
@@ -421,8 +490,8 @@ class BlobManager {
|
|
|
421
490
|
}
|
|
422
491
|
// set identity (id -> id) entry
|
|
423
492
|
this.setRedirection(blobId, blobId);
|
|
493
|
+
(0, internal_1.assert)(localId !== undefined, 0x50e /* local ID not present in blob attach message */);
|
|
424
494
|
if (local) {
|
|
425
|
-
(0, internal_1.assert)(localId !== undefined, 0x50e /* local ID not present in blob attach message */);
|
|
426
495
|
const waitingBlobs = this.opsInFlight.get(blobId);
|
|
427
496
|
if (waitingBlobs !== undefined) {
|
|
428
497
|
// For each op corresponding to this storage ID that we are waiting for, resolve the pending blob.
|
|
@@ -433,7 +502,9 @@ class BlobManager {
|
|
|
433
502
|
(0, internal_1.assert)(entry !== undefined, 0x38f /* local online BlobAttach op with no pending blob entry */);
|
|
434
503
|
this.setRedirection(pendingLocalId, blobId);
|
|
435
504
|
entry.acked = true;
|
|
436
|
-
|
|
505
|
+
const blobHandle = this.getBlobHandle(pendingLocalId);
|
|
506
|
+
blobHandle.notifyShared();
|
|
507
|
+
entry.handleP.resolve(blobHandle);
|
|
437
508
|
this.deletePendingBlobMaybe(pendingLocalId);
|
|
438
509
|
}
|
|
439
510
|
this.opsInFlight.delete(blobId);
|
|
@@ -441,7 +512,9 @@ class BlobManager {
|
|
|
441
512
|
const localEntry = this.pendingBlobs.get(localId);
|
|
442
513
|
if (localEntry) {
|
|
443
514
|
localEntry.acked = true;
|
|
444
|
-
|
|
515
|
+
const blobHandle = this.getBlobHandle(localId);
|
|
516
|
+
blobHandle.notifyShared();
|
|
517
|
+
localEntry.handleP.resolve(blobHandle);
|
|
445
518
|
this.deletePendingBlobMaybe(localId);
|
|
446
519
|
}
|
|
447
520
|
}
|
|
@@ -583,7 +656,7 @@ class BlobManager {
|
|
|
583
656
|
const localBlobs = new Set();
|
|
584
657
|
// This while is used to stash blobs created while attaching and getting blobs
|
|
585
658
|
while (localBlobs.size < this.pendingBlobs.size) {
|
|
586
|
-
const
|
|
659
|
+
const attachHandlesP = [];
|
|
587
660
|
for (const [localId, entry] of this.pendingBlobs) {
|
|
588
661
|
if (!localBlobs.has(entry)) {
|
|
589
662
|
localBlobs.add(entry);
|
|
@@ -598,15 +671,15 @@ class BlobManager {
|
|
|
598
671
|
// original createBlob call) and let them attach the blob. This is a lie we told since the upload
|
|
599
672
|
// hasn't finished yet, but it's fine since we will retry on rehydration.
|
|
600
673
|
entry.handleP.resolve(this.getBlobHandle(localId));
|
|
601
|
-
// Array of promises that will resolve when
|
|
602
|
-
|
|
674
|
+
// Array of promises that will resolve when handles get attached.
|
|
675
|
+
attachHandlesP.push(new Promise((resolve, reject) => {
|
|
603
676
|
stopBlobAttachingSignal?.addEventListener("abort", () => {
|
|
604
677
|
this.stopAttaching = true;
|
|
605
678
|
reject(new Error("Operation aborted"));
|
|
606
679
|
}, { once: true });
|
|
607
|
-
const
|
|
680
|
+
const onHandleAttached = (attachedEntry) => {
|
|
608
681
|
if (attachedEntry === entry) {
|
|
609
|
-
this.internalEvents.off("handleAttached",
|
|
682
|
+
this.internalEvents.off("handleAttached", onHandleAttached);
|
|
610
683
|
resolve();
|
|
611
684
|
}
|
|
612
685
|
};
|
|
@@ -614,14 +687,14 @@ class BlobManager {
|
|
|
614
687
|
resolve();
|
|
615
688
|
}
|
|
616
689
|
else {
|
|
617
|
-
this.internalEvents.on("handleAttached",
|
|
690
|
+
this.internalEvents.on("handleAttached", onHandleAttached);
|
|
618
691
|
}
|
|
619
692
|
}));
|
|
620
693
|
}
|
|
621
694
|
}
|
|
622
695
|
// Wait for all blobs to be attached. This is important, otherwise serialized container
|
|
623
696
|
// could send the blobAttach op without any op that references the blob, making it useless.
|
|
624
|
-
await Promise.allSettled(
|
|
697
|
+
await Promise.allSettled(attachHandlesP);
|
|
625
698
|
}
|
|
626
699
|
for (const [localId, entry] of this.pendingBlobs) {
|
|
627
700
|
if (stopBlobAttachingSignal?.aborted && !entry.attached) {
|