@fluidframework/container-runtime 2.23.0-325054 → 2.30.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 +52 -0
- package/api-report/container-runtime.legacy.alpha.api.md +0 -246
- package/dist/blobManager/blobManager.d.ts +11 -9
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +38 -39
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.d.ts +2 -4
- package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/dist/blobManager/blobManagerSnapSum.js +6 -6
- package/dist/blobManager/blobManagerSnapSum.js.map +1 -1
- package/dist/channelCollection.d.ts +1 -7
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +1 -26
- package/dist/channelCollection.js.map +1 -1
- package/dist/connectionTelemetry.d.ts +0 -43
- package/dist/connectionTelemetry.d.ts.map +1 -1
- package/dist/connectionTelemetry.js.map +1 -1
- package/dist/containerRuntime.d.ts +21 -141
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +49 -290
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +0 -13
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +2 -25
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/gc/garbageCollection.d.ts.map +1 -1
- package/dist/gc/garbageCollection.js +2 -20
- package/dist/gc/garbageCollection.js.map +1 -1
- package/dist/gc/gcConfigs.d.ts.map +1 -1
- package/dist/gc/gcConfigs.js +0 -2
- package/dist/gc/gcConfigs.js.map +1 -1
- package/dist/gc/gcDefinitions.d.ts +8 -24
- package/dist/gc/gcDefinitions.d.ts.map +1 -1
- package/dist/gc/gcDefinitions.js +1 -3
- package/dist/gc/gcDefinitions.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +1 -4
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/dist/gc/gcSummaryStateTracker.js +0 -1
- package/dist/gc/gcSummaryStateTracker.js.map +1 -1
- package/dist/gc/gcTelemetry.d.ts.map +1 -1
- package/dist/gc/gcTelemetry.js +4 -16
- package/dist/gc/gcTelemetry.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +0 -29
- package/dist/messageTypes.d.ts.map +1 -1
- package/dist/messageTypes.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/signalTelemetryProcessing.d.ts +33 -0
- package/dist/signalTelemetryProcessing.d.ts.map +1 -0
- package/dist/signalTelemetryProcessing.js +149 -0
- package/dist/signalTelemetryProcessing.js.map +1 -0
- package/dist/summary/documentSchema.d.ts +7 -31
- package/dist/summary/documentSchema.d.ts.map +1 -1
- package/dist/summary/documentSchema.js +2 -18
- package/dist/summary/documentSchema.js.map +1 -1
- package/dist/summary/index.d.ts +2 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +7 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/orderedClientElection.d.ts +1 -3
- package/dist/summary/orderedClientElection.d.ts.map +1 -1
- package/dist/summary/orderedClientElection.js.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.d.ts +1 -3
- package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/dist/summary/runWhileConnectedCoordinator.js +2 -7
- package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +1 -2
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +4 -23
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts +2 -5
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +3 -11
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerClientElection.d.ts.map +1 -1
- package/dist/summary/summarizerClientElection.js +0 -1
- package/dist/summary/summarizerClientElection.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +1 -1
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +109 -22
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryFormat.d.ts +3 -9
- package/dist/summary/summaryFormat.d.ts.map +1 -1
- package/dist/summary/summaryFormat.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +3 -9
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/dist/summary/summaryHelpers.d.ts +19 -0
- package/dist/summary/summaryHelpers.d.ts.map +1 -0
- package/dist/summary/summaryHelpers.js +90 -0
- package/dist/summary/summaryHelpers.js.map +1 -0
- package/dist/summary/summaryManager.d.ts.map +1 -1
- package/dist/summary/summaryManager.js +0 -2
- package/dist/summary/summaryManager.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts +11 -9
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +37 -37
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.d.ts +2 -4
- package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
- package/lib/blobManager/blobManagerSnapSum.js +6 -6
- package/lib/blobManager/blobManagerSnapSum.js.map +1 -1
- package/lib/channelCollection.d.ts +1 -7
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +2 -29
- package/lib/channelCollection.js.map +1 -1
- package/lib/connectionTelemetry.d.ts +0 -43
- package/lib/connectionTelemetry.d.ts.map +1 -1
- package/lib/connectionTelemetry.js.map +1 -1
- package/lib/containerRuntime.d.ts +21 -141
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +51 -298
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +0 -13
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +2 -25
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/gc/garbageCollection.d.ts.map +1 -1
- package/lib/gc/garbageCollection.js +3 -23
- package/lib/gc/garbageCollection.js.map +1 -1
- package/lib/gc/gcConfigs.d.ts.map +1 -1
- package/lib/gc/gcConfigs.js +0 -2
- package/lib/gc/gcConfigs.js.map +1 -1
- package/lib/gc/gcDefinitions.d.ts +8 -24
- package/lib/gc/gcDefinitions.d.ts.map +1 -1
- package/lib/gc/gcDefinitions.js +1 -3
- package/lib/gc/gcDefinitions.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +1 -4
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
- package/lib/gc/gcSummaryStateTracker.js +0 -1
- package/lib/gc/gcSummaryStateTracker.js.map +1 -1
- package/lib/gc/gcTelemetry.d.ts.map +1 -1
- package/lib/gc/gcTelemetry.js +5 -19
- package/lib/gc/gcTelemetry.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +0 -29
- package/lib/messageTypes.d.ts.map +1 -1
- package/lib/messageTypes.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/signalTelemetryProcessing.d.ts +33 -0
- package/lib/signalTelemetryProcessing.d.ts.map +1 -0
- package/lib/signalTelemetryProcessing.js +145 -0
- package/lib/signalTelemetryProcessing.js.map +1 -0
- package/lib/summary/documentSchema.d.ts +7 -31
- package/lib/summary/documentSchema.d.ts.map +1 -1
- package/lib/summary/documentSchema.js +2 -18
- package/lib/summary/documentSchema.js.map +1 -1
- package/lib/summary/index.d.ts +2 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -0
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/orderedClientElection.d.ts +1 -3
- package/lib/summary/orderedClientElection.d.ts.map +1 -1
- package/lib/summary/orderedClientElection.js.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.d.ts +1 -3
- package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
- package/lib/summary/runWhileConnectedCoordinator.js +2 -7
- package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +1 -2
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +4 -23
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts +2 -5
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +3 -11
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerClientElection.d.ts.map +1 -1
- package/lib/summary/summarizerClientElection.js +0 -1
- package/lib/summary/summarizerClientElection.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +1 -1
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +109 -22
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryFormat.d.ts +3 -9
- package/lib/summary/summaryFormat.d.ts.map +1 -1
- package/lib/summary/summaryFormat.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +3 -9
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/lib/summary/summaryHelpers.d.ts +19 -0
- package/lib/summary/summaryHelpers.d.ts.map +1 -0
- package/lib/summary/summaryHelpers.js +84 -0
- package/lib/summary/summaryHelpers.js.map +1 -0
- package/lib/summary/summaryManager.d.ts.map +1 -1
- package/lib/summary/summaryManager.js +0 -2
- package/lib/summary/summaryManager.js.map +1 -1
- package/package.json +27 -20
- package/src/blobManager/blobManager.ts +70 -62
- package/src/blobManager/blobManagerSnapSum.ts +7 -9
- package/src/channelCollection.ts +3 -31
- package/src/connectionTelemetry.ts +0 -51
- package/src/containerRuntime.ts +111 -522
- package/src/dataStoreContext.ts +2 -32
- package/src/gc/garbageCollection.ts +9 -26
- package/src/gc/gcConfigs.ts +3 -6
- package/src/gc/gcDefinitions.ts +10 -28
- package/src/gc/gcHelpers.ts +0 -5
- package/src/gc/gcSummaryStateTracker.ts +1 -2
- package/src/gc/gcTelemetry.ts +6 -13
- package/src/index.ts +6 -6
- package/src/messageTypes.ts +0 -2
- package/src/packageVersion.ts +1 -1
- package/src/signalTelemetryProcessing.ts +233 -0
- package/src/summary/documentSchema.ts +7 -38
- package/src/summary/index.ts +12 -0
- package/src/summary/orderedClientElection.ts +1 -3
- package/src/summary/runWhileConnectedCoordinator.ts +3 -8
- package/src/summary/runningSummarizer.ts +12 -20
- package/src/summary/summarizer.ts +6 -18
- package/src/summary/summarizerClientElection.ts +0 -2
- package/src/summary/summarizerHeuristics.ts +1 -2
- package/src/summary/summarizerTypes.ts +119 -23
- package/src/summary/summaryFormat.ts +4 -13
- package/src/summary/summaryGenerator.ts +1 -8
- package/src/summary/summaryHelpers.ts +118 -0
- package/src/summary/summaryManager.ts +0 -2
|
@@ -13,11 +13,13 @@ import {
|
|
|
13
13
|
IContainerRuntime,
|
|
14
14
|
IContainerRuntimeEvents,
|
|
15
15
|
} from "@fluidframework/container-runtime-definitions/internal";
|
|
16
|
-
import {
|
|
16
|
+
import type {
|
|
17
|
+
IEvent,
|
|
18
|
+
IEventProvider,
|
|
17
19
|
IFluidHandleContext,
|
|
18
|
-
|
|
20
|
+
IFluidHandleInternal,
|
|
19
21
|
} from "@fluidframework/core-interfaces/internal";
|
|
20
|
-
import { assert, Deferred
|
|
22
|
+
import { assert, Deferred } from "@fluidframework/core-utils/internal";
|
|
21
23
|
import {
|
|
22
24
|
IDocumentStorageService,
|
|
23
25
|
ICreateBlobResponse,
|
|
@@ -50,7 +52,6 @@ import {
|
|
|
50
52
|
getStorageIds,
|
|
51
53
|
summarizeBlobManagerState,
|
|
52
54
|
toRedirectTable,
|
|
53
|
-
// eslint-disable-next-line import/no-deprecated
|
|
54
55
|
type IBlobManagerLoadInfo,
|
|
55
56
|
} from "./blobManagerSnapSum.js";
|
|
56
57
|
|
|
@@ -118,7 +119,7 @@ interface PendingBlob {
|
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
export interface IPendingBlobs {
|
|
121
|
-
[
|
|
122
|
+
[localId: string]: {
|
|
122
123
|
blob: string;
|
|
123
124
|
storageId?: string;
|
|
124
125
|
uploadTime?: number;
|
|
@@ -127,10 +128,14 @@ export interface IPendingBlobs {
|
|
|
127
128
|
};
|
|
128
129
|
}
|
|
129
130
|
|
|
130
|
-
export interface IBlobManagerEvents {
|
|
131
|
+
export interface IBlobManagerEvents extends IEvent {
|
|
131
132
|
(event: "noPendingBlobs", listener: () => void);
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
interface IBlobManagerInternalEvents extends IEvent {
|
|
136
|
+
(event: "blobAttached", listener: (pending: PendingBlob) => void);
|
|
137
|
+
}
|
|
138
|
+
|
|
134
139
|
const stashedPendingBlobOverrides: Pick<
|
|
135
140
|
PendingBlob,
|
|
136
141
|
"stashedUpload" | "storageId" | "minTTLInSeconds" | "uploadTime"
|
|
@@ -143,11 +148,17 @@ const stashedPendingBlobOverrides: Pick<
|
|
|
143
148
|
|
|
144
149
|
export const blobManagerBasePath = "_blobs" as const;
|
|
145
150
|
|
|
146
|
-
export class BlobManager
|
|
151
|
+
export class BlobManager {
|
|
147
152
|
private readonly mc: MonitoringContext;
|
|
148
153
|
|
|
154
|
+
private readonly publicEvents = new TypedEventEmitter<IBlobManagerEvents>();
|
|
155
|
+
public get events(): IEventProvider<IBlobManagerEvents> {
|
|
156
|
+
return this.publicEvents;
|
|
157
|
+
}
|
|
158
|
+
private readonly internalEvents = new TypedEventEmitter<IBlobManagerInternalEvents>();
|
|
159
|
+
|
|
149
160
|
/**
|
|
150
|
-
* Map of local IDs to storage IDs. Contains identity entries (
|
|
161
|
+
* Map of local IDs to storage IDs. Contains identity entries (storageId → storageId) for storage IDs. All requested IDs should
|
|
151
162
|
* be a key in this map. Blobs created while the container is detached are stored in IDetachedBlobStorage which
|
|
152
163
|
* gives local IDs; the storage IDs are filled in at attach time.
|
|
153
164
|
* Note: It contains mappings from all clients, i.e., from remote clients as well. local ID comes from the client
|
|
@@ -171,7 +182,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
171
182
|
private stopAttaching: boolean = false;
|
|
172
183
|
|
|
173
184
|
private readonly routeContext: IFluidHandleContext;
|
|
174
|
-
private readonly
|
|
185
|
+
private readonly storage: IDocumentStorageService;
|
|
175
186
|
// Called when a blob node is requested. blobPath is the path of the blob's node in GC's graph.
|
|
176
187
|
// blobPath's format - `/<basePath>/<blobId>`.
|
|
177
188
|
private readonly blobRequested: (blobPath: string) => void;
|
|
@@ -186,9 +197,9 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
186
197
|
|
|
187
198
|
constructor(props: {
|
|
188
199
|
readonly routeContext: IFluidHandleContext;
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
readonly
|
|
200
|
+
|
|
201
|
+
blobManagerLoadInfo: IBlobManagerLoadInfo;
|
|
202
|
+
readonly storage: IDocumentStorageService;
|
|
192
203
|
/**
|
|
193
204
|
* Submit a BlobAttach op. When a blob is uploaded, there is a short grace period before which the blob is
|
|
194
205
|
* deleted. The BlobAttach op notifies the server that blob is in use. The server will then not delete the
|
|
@@ -210,11 +221,10 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
210
221
|
stashedBlobs: IPendingBlobs | undefined;
|
|
211
222
|
readonly localBlobIdGenerator?: (() => string) | undefined;
|
|
212
223
|
}) {
|
|
213
|
-
super();
|
|
214
224
|
const {
|
|
215
225
|
routeContext,
|
|
216
|
-
|
|
217
|
-
|
|
226
|
+
blobManagerLoadInfo,
|
|
227
|
+
storage,
|
|
218
228
|
sendBlobAttachOp,
|
|
219
229
|
blobRequested,
|
|
220
230
|
isBlobDeleted,
|
|
@@ -223,7 +233,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
223
233
|
localBlobIdGenerator,
|
|
224
234
|
} = props;
|
|
225
235
|
this.routeContext = routeContext;
|
|
226
|
-
this.
|
|
236
|
+
this.storage = storage;
|
|
227
237
|
this.blobRequested = blobRequested;
|
|
228
238
|
this.isBlobDeleted = isBlobDeleted;
|
|
229
239
|
this.runtime = runtime;
|
|
@@ -234,7 +244,11 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
234
244
|
namespace: "BlobManager",
|
|
235
245
|
});
|
|
236
246
|
|
|
237
|
-
this.redirectTable = toRedirectTable(
|
|
247
|
+
this.redirectTable = toRedirectTable(
|
|
248
|
+
blobManagerLoadInfo,
|
|
249
|
+
this.mc.logger,
|
|
250
|
+
this.runtime.attachState,
|
|
251
|
+
);
|
|
238
252
|
|
|
239
253
|
// Begin uploading stashed blobs from previous container instance
|
|
240
254
|
for (const [localId, entry] of Object.entries(stashedBlobs ?? {})) {
|
|
@@ -268,13 +282,11 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
268
282
|
});
|
|
269
283
|
}
|
|
270
284
|
|
|
271
|
-
this.stashedBlobsUploadP =
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
{ start: true, end: true },
|
|
277
|
-
),
|
|
285
|
+
this.stashedBlobsUploadP = PerformanceEvent.timedExecAsync(
|
|
286
|
+
this.mc.logger,
|
|
287
|
+
{ eventName: "BlobUploadProcessStashedChanges", count: this.pendingStashedBlobs.size },
|
|
288
|
+
async () => Promise.all(this.pendingStashedBlobs.values()),
|
|
289
|
+
{ start: true, end: true },
|
|
278
290
|
).finally(() => {
|
|
279
291
|
this.pendingStashedBlobs.clear();
|
|
280
292
|
});
|
|
@@ -308,12 +320,12 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
308
320
|
}
|
|
309
321
|
}
|
|
310
322
|
pendingEntry.opsent = true;
|
|
311
|
-
|
|
323
|
+
sendBlobAttachOp(localId, blobId);
|
|
312
324
|
};
|
|
313
325
|
}
|
|
314
326
|
|
|
315
327
|
public get allBlobsAttached(): boolean {
|
|
316
|
-
for (const
|
|
328
|
+
for (const entry of this.pendingBlobs.values()) {
|
|
317
329
|
if (entry.attached === false) {
|
|
318
330
|
return false;
|
|
319
331
|
}
|
|
@@ -370,40 +382,38 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
370
382
|
this.mc.logger,
|
|
371
383
|
{ eventName: "AttachmentReadBlob", id: storageId },
|
|
372
384
|
async (event) => {
|
|
373
|
-
return this.
|
|
374
|
-
.
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
event.cancel({ category: "generic" });
|
|
379
|
-
}
|
|
385
|
+
return this.storage.readBlob(storageId).catch((error) => {
|
|
386
|
+
if (this.runtime.disposed) {
|
|
387
|
+
// If the runtime is disposed, this is not an error we care to track, it's expected behavior.
|
|
388
|
+
event.cancel({ category: "generic" });
|
|
389
|
+
}
|
|
380
390
|
|
|
381
|
-
|
|
382
|
-
|
|
391
|
+
throw error;
|
|
392
|
+
});
|
|
383
393
|
},
|
|
384
394
|
{ end: true, cancel: "error" },
|
|
385
395
|
);
|
|
386
396
|
}
|
|
387
397
|
|
|
388
|
-
private getBlobHandle(
|
|
398
|
+
private getBlobHandle(localId: string): BlobHandle {
|
|
389
399
|
assert(
|
|
390
|
-
this.redirectTable.has(
|
|
400
|
+
this.redirectTable.has(localId) || this.pendingBlobs.has(localId),
|
|
391
401
|
0x384 /* requesting handle for unknown blob */,
|
|
392
402
|
);
|
|
393
|
-
const pending = this.pendingBlobs.get(
|
|
403
|
+
const pending = this.pendingBlobs.get(localId);
|
|
394
404
|
// Create a callback function for once the blob has been attached
|
|
395
405
|
const callback = pending
|
|
396
406
|
? () => {
|
|
397
407
|
pending.attached = true;
|
|
398
408
|
// Notify listeners (e.g. serialization process) that blob has been attached
|
|
399
|
-
this.emit("blobAttached", pending);
|
|
400
|
-
this.deletePendingBlobMaybe(
|
|
409
|
+
this.internalEvents.emit("blobAttached", pending);
|
|
410
|
+
this.deletePendingBlobMaybe(localId);
|
|
401
411
|
}
|
|
402
412
|
: undefined;
|
|
403
413
|
return new BlobHandle(
|
|
404
|
-
getGCNodePathFromBlobId(
|
|
414
|
+
getGCNodePathFromBlobId(localId),
|
|
405
415
|
this.routeContext,
|
|
406
|
-
async () => this.getBlob(
|
|
416
|
+
async () => this.getBlob(localId),
|
|
407
417
|
callback,
|
|
408
418
|
);
|
|
409
419
|
}
|
|
@@ -413,7 +423,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
413
423
|
): Promise<IFluidHandleInternal<ArrayBufferLike>> {
|
|
414
424
|
// Blobs created while the container is detached are stored in IDetachedBlobStorage.
|
|
415
425
|
// The 'IDocumentStorageService.createBlob()' call below will respond with a localId.
|
|
416
|
-
const response = await this.
|
|
426
|
+
const response = await this.storage.createBlob(blob);
|
|
417
427
|
this.setRedirection(response.id, undefined);
|
|
418
428
|
return this.getBlobHandle(response.id);
|
|
419
429
|
}
|
|
@@ -472,7 +482,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
472
482
|
return runWithRetry(
|
|
473
483
|
async () => {
|
|
474
484
|
try {
|
|
475
|
-
return await this.
|
|
485
|
+
return await this.storage.createBlob(blob);
|
|
476
486
|
} catch (error) {
|
|
477
487
|
const entry = this.pendingBlobs.get(localId);
|
|
478
488
|
assert(
|
|
@@ -520,18 +530,18 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
520
530
|
this.redirectTable.set(fromId, toId);
|
|
521
531
|
}
|
|
522
532
|
|
|
523
|
-
private deletePendingBlobMaybe(
|
|
524
|
-
if (this.pendingBlobs.has(
|
|
525
|
-
const entry = this.pendingBlobs.get(
|
|
533
|
+
private deletePendingBlobMaybe(localId: string): void {
|
|
534
|
+
if (this.pendingBlobs.has(localId)) {
|
|
535
|
+
const entry = this.pendingBlobs.get(localId);
|
|
526
536
|
if (entry?.attached && entry?.acked) {
|
|
527
|
-
this.deletePendingBlob(
|
|
537
|
+
this.deletePendingBlob(localId);
|
|
528
538
|
}
|
|
529
539
|
}
|
|
530
540
|
}
|
|
531
541
|
|
|
532
542
|
private deletePendingBlob(id: string): void {
|
|
533
543
|
if (this.pendingBlobs.delete(id) && !this.hasPendingBlobs) {
|
|
534
|
-
this.emit("noPendingBlobs");
|
|
544
|
+
this.publicEvents.emit("noPendingBlobs");
|
|
535
545
|
}
|
|
536
546
|
}
|
|
537
547
|
|
|
@@ -833,7 +843,7 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
833
843
|
// This while is used to stash blobs created while attaching and getting blobs
|
|
834
844
|
while (localBlobs.size < this.pendingBlobs.size) {
|
|
835
845
|
const attachBlobsP: Promise<void>[] = [];
|
|
836
|
-
for (const [
|
|
846
|
+
for (const [localId, entry] of this.pendingBlobs) {
|
|
837
847
|
if (!localBlobs.has(entry)) {
|
|
838
848
|
localBlobs.add(entry);
|
|
839
849
|
// In order to follow natural blob creation flow we need to:
|
|
@@ -841,12 +851,12 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
841
851
|
// 2 resolve the blob handle
|
|
842
852
|
// 3 wait for op referencing the blob
|
|
843
853
|
if (!entry.opsent) {
|
|
844
|
-
this.sendBlobAttachOp(
|
|
854
|
+
this.sendBlobAttachOp(localId, entry.storageId);
|
|
845
855
|
}
|
|
846
856
|
// Resolving the blob handle to let hosts continue with their operations (it will resolve
|
|
847
857
|
// original createBlob call) and let them attach the blob. This is a lie we told since the upload
|
|
848
858
|
// hasn't finished yet, but it's fine since we will retry on rehydration.
|
|
849
|
-
entry.handleP.resolve(this.getBlobHandle(
|
|
859
|
+
entry.handleP.resolve(this.getBlobHandle(localId));
|
|
850
860
|
// Array of promises that will resolve when blobs get attached.
|
|
851
861
|
attachBlobsP.push(
|
|
852
862
|
new Promise<void>((resolve, reject) => {
|
|
@@ -858,16 +868,16 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
858
868
|
},
|
|
859
869
|
{ once: true },
|
|
860
870
|
);
|
|
861
|
-
const onBlobAttached = (attachedEntry): void => {
|
|
871
|
+
const onBlobAttached = (attachedEntry: PendingBlob): void => {
|
|
862
872
|
if (attachedEntry === entry) {
|
|
863
|
-
this.off("blobAttached", onBlobAttached);
|
|
873
|
+
this.internalEvents.off("blobAttached", onBlobAttached);
|
|
864
874
|
resolve();
|
|
865
875
|
}
|
|
866
876
|
};
|
|
867
877
|
if (entry.attached) {
|
|
868
878
|
resolve();
|
|
869
879
|
} else {
|
|
870
|
-
this.on("blobAttached", onBlobAttached);
|
|
880
|
+
this.internalEvents.on("blobAttached", onBlobAttached);
|
|
871
881
|
}
|
|
872
882
|
}),
|
|
873
883
|
);
|
|
@@ -875,21 +885,19 @@ export class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
875
885
|
}
|
|
876
886
|
// Wait for all blobs to be attached. This is important, otherwise serialized container
|
|
877
887
|
// could send the blobAttach op without any op that references the blob, making it useless.
|
|
878
|
-
await Promise.allSettled(attachBlobsP)
|
|
879
|
-
return undefined;
|
|
880
|
-
});
|
|
888
|
+
await Promise.allSettled(attachBlobsP);
|
|
881
889
|
}
|
|
882
890
|
|
|
883
|
-
for (const [
|
|
891
|
+
for (const [localId, entry] of this.pendingBlobs) {
|
|
884
892
|
if (stopBlobAttachingSignal?.aborted && !entry.attached) {
|
|
885
893
|
this.mc.logger.sendTelemetryEvent({
|
|
886
894
|
eventName: "UnableToStashBlob",
|
|
887
|
-
id,
|
|
895
|
+
id: localId,
|
|
888
896
|
});
|
|
889
897
|
continue;
|
|
890
898
|
}
|
|
891
899
|
assert(entry.attached === true, 0x790 /* stashed blob should be attached */);
|
|
892
|
-
blobs[
|
|
900
|
+
blobs[localId] = {
|
|
893
901
|
blob: bufferToString(entry.blob, "base64"),
|
|
894
902
|
storageId: entry.storageId,
|
|
895
903
|
acked: entry.acked,
|
|
@@ -926,7 +934,7 @@ const getBlobIdFromGCNodePath = (nodePath: string): string => {
|
|
|
926
934
|
export const isBlobPath = (path: string): path is `/${typeof blobManagerBasePath}/${string}` =>
|
|
927
935
|
areBlobPathParts(path.split("/"));
|
|
928
936
|
|
|
929
|
-
|
|
937
|
+
const areBlobPathParts = (
|
|
930
938
|
pathParts: string[],
|
|
931
939
|
): pathParts is ["", typeof blobManagerBasePath, string] =>
|
|
932
940
|
pathParts.length === 3 && pathParts[1] === blobManagerBasePath;
|
|
@@ -15,9 +15,7 @@ import type { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/intern
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Information from a snapshot needed to load BlobManager
|
|
18
|
-
* @
|
|
19
|
-
* @alpha
|
|
20
|
-
* @deprecated This type will be moved to internal in 2.30. External usage is not necessary or supported.
|
|
18
|
+
* @internal
|
|
21
19
|
*/
|
|
22
20
|
export interface IBlobManagerLoadInfo {
|
|
23
21
|
ids?: string[];
|
|
@@ -60,21 +58,21 @@ const loadV1 = async (
|
|
|
60
58
|
};
|
|
61
59
|
|
|
62
60
|
export const toRedirectTable = (
|
|
63
|
-
|
|
61
|
+
blobManagerLoadInfo: IBlobManagerLoadInfo,
|
|
64
62
|
logger: ITelemetryLoggerExt,
|
|
65
63
|
attachState: AttachState,
|
|
66
64
|
): Map<string, string | undefined> => {
|
|
67
65
|
logger.sendTelemetryEvent({
|
|
68
66
|
eventName: "AttachmentBlobsLoaded",
|
|
69
|
-
count:
|
|
70
|
-
redirectTable:
|
|
67
|
+
count: blobManagerLoadInfo.ids?.length ?? 0,
|
|
68
|
+
redirectTable: blobManagerLoadInfo.redirectTable?.length,
|
|
71
69
|
});
|
|
72
|
-
const redirectTable = new Map<string, string | undefined>(
|
|
70
|
+
const redirectTable = new Map<string, string | undefined>(blobManagerLoadInfo.redirectTable);
|
|
73
71
|
const detached = attachState !== AttachState.Attached;
|
|
74
|
-
if (
|
|
72
|
+
if (blobManagerLoadInfo.ids) {
|
|
75
73
|
// If we are detached, we don't have storage IDs yet, so set to undefined
|
|
76
74
|
// Otherwise, set identity (id -> id) entries.
|
|
77
|
-
for (const entry of
|
|
75
|
+
for (const entry of blobManagerLoadInfo.ids) {
|
|
78
76
|
redirectTable.set(entry, detached ? undefined : entry);
|
|
79
77
|
}
|
|
80
78
|
}
|
package/src/channelCollection.ts
CHANGED
|
@@ -76,7 +76,6 @@ import {
|
|
|
76
76
|
import { v4 as uuid } from "uuid";
|
|
77
77
|
|
|
78
78
|
import {
|
|
79
|
-
// eslint-disable-next-line import/no-deprecated
|
|
80
79
|
DeletedResponseHeaderKey,
|
|
81
80
|
RuntimeHeaderData,
|
|
82
81
|
defaultRuntimeHeaderData,
|
|
@@ -97,12 +96,10 @@ import {
|
|
|
97
96
|
} from "./dataStoreContext.js";
|
|
98
97
|
import { DataStoreContexts } from "./dataStoreContexts.js";
|
|
99
98
|
import { FluidDataStoreRegistry } from "./dataStoreRegistry.js";
|
|
100
|
-
// eslint-disable-next-line import/no-deprecated
|
|
101
99
|
import { GCNodeType, IGCNodeUpdatedProps, urlToGCNodePath } from "./gc/index.js";
|
|
102
100
|
import { ContainerMessageType, LocalContainerRuntimeMessage } from "./messageTypes.js";
|
|
103
101
|
import { StorageServiceWithAttachBlobs } from "./storageServiceWithAttachBlobs.js";
|
|
104
102
|
import {
|
|
105
|
-
// eslint-disable-next-line import/no-deprecated
|
|
106
103
|
IContainerRuntimeMetadata,
|
|
107
104
|
nonDataStorePaths,
|
|
108
105
|
rootHasIsolatedChannels,
|
|
@@ -860,29 +857,6 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
860
857
|
}
|
|
861
858
|
}
|
|
862
859
|
|
|
863
|
-
/**
|
|
864
|
-
* This is still here for back-compat purposes because channel collection implements
|
|
865
|
-
* IFluidDataStoreChannel. Once it is removed from the interface, this method can be removed.
|
|
866
|
-
* Container runtime calls `processMessages` instead.
|
|
867
|
-
*/
|
|
868
|
-
public process(
|
|
869
|
-
message: ISequencedDocumentMessage,
|
|
870
|
-
local: boolean,
|
|
871
|
-
localOpMetadata: unknown,
|
|
872
|
-
): void {
|
|
873
|
-
this.processMessages({
|
|
874
|
-
envelope: message,
|
|
875
|
-
messagesContent: [
|
|
876
|
-
{
|
|
877
|
-
contents: message.contents,
|
|
878
|
-
localOpMetadata,
|
|
879
|
-
clientSequenceNumber: message.clientSequenceNumber,
|
|
880
|
-
},
|
|
881
|
-
],
|
|
882
|
-
local,
|
|
883
|
-
});
|
|
884
|
-
}
|
|
885
|
-
|
|
886
860
|
/**
|
|
887
861
|
* Process channel messages. The messages here are contiguous channel type messages in a batch. Bunch
|
|
888
862
|
* of contiguous messages for a data store should be sent to it together.
|
|
@@ -996,7 +970,6 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
996
970
|
// The requested data store has been deleted by gc. Create a 404 response exception.
|
|
997
971
|
throw responseToException(
|
|
998
972
|
createResponseError(404, "DataStore was deleted", originalRequest, {
|
|
999
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1000
973
|
[DeletedResponseHeaderKey]: true,
|
|
1001
974
|
}),
|
|
1002
975
|
originalRequest,
|
|
@@ -1487,7 +1460,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
1487
1460
|
* Called by GC to determine if a node is for a data store or for an object within a data store (for e.g. DDS).
|
|
1488
1461
|
* @returns the GC node type if the node belongs to a data store or object within data store, undefined otherwise.
|
|
1489
1462
|
*/
|
|
1490
|
-
|
|
1463
|
+
|
|
1491
1464
|
public getGCNodeType(nodePath: string): GCNodeType | undefined {
|
|
1492
1465
|
const pathParts = nodePath.split("/");
|
|
1493
1466
|
if (!this.contexts.has(pathParts[1])) {
|
|
@@ -1497,10 +1470,9 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
1497
1470
|
// Data stores paths are of the format "/dataStoreId".
|
|
1498
1471
|
// Sub data store paths are of the format "/dataStoreId/subPath/...".
|
|
1499
1472
|
if (pathParts.length === 2) {
|
|
1500
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1501
1473
|
return GCNodeType.DataStore;
|
|
1502
1474
|
}
|
|
1503
|
-
|
|
1475
|
+
|
|
1504
1476
|
return GCNodeType.SubDataStore;
|
|
1505
1477
|
}
|
|
1506
1478
|
|
|
@@ -1565,7 +1537,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
|
|
|
1565
1537
|
|
|
1566
1538
|
export function getSummaryForDatastores(
|
|
1567
1539
|
snapshot: ISnapshotTree | undefined,
|
|
1568
|
-
|
|
1540
|
+
|
|
1569
1541
|
metadata?: IContainerRuntimeMetadata,
|
|
1570
1542
|
): ISnapshotTree | undefined {
|
|
1571
1543
|
if (!snapshot) {
|
|
@@ -457,57 +457,6 @@ class OpPerfTelemetry {
|
|
|
457
457
|
}
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
|
-
export interface IPerfSignalReport {
|
|
461
|
-
/**
|
|
462
|
-
* Identifier to track broadcast signals being submitted in order to
|
|
463
|
-
* allow collection of data around the roundtrip of signal messages.
|
|
464
|
-
*/
|
|
465
|
-
broadcastSignalSequenceNumber: number;
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Accumulates the total number of broadcast signals sent during the current signal latency measurement window.
|
|
469
|
-
* This value represents the total number of signals sent since the latency measurement began and is used
|
|
470
|
-
* logged in telemetry when the latency measurement completes.
|
|
471
|
-
*/
|
|
472
|
-
totalSignalsSentInLatencyWindow: number;
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* Counts the number of broadcast signals sent since the last latency measurement was initiated.
|
|
476
|
-
* This counter increments with each broadcast signal sent. When a new latency measurement starts,
|
|
477
|
-
* this counter is added to `totalSignalsSentInLatencyWindow` and then reset to zero.
|
|
478
|
-
*/
|
|
479
|
-
signalsSentSinceLastLatencyMeasurement: number;
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* Number of signals that were expected but not received.
|
|
483
|
-
*/
|
|
484
|
-
signalsLost: number;
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* Number of signals received out of order/non-sequentially.
|
|
488
|
-
*/
|
|
489
|
-
signalsOutOfOrder: number;
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Timestamp before submitting the signal we will trace.
|
|
493
|
-
*/
|
|
494
|
-
signalTimestamp: number;
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Signal we will trace for roundtrip latency.
|
|
498
|
-
*/
|
|
499
|
-
roundTripSignalSequenceNumber: number | undefined;
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Next expected signal sequence number to be received.
|
|
503
|
-
*/
|
|
504
|
-
trackingSignalSequenceNumber: number | undefined;
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* Inclusive lower bound of signal monitoring window.
|
|
508
|
-
*/
|
|
509
|
-
minimumTrackingSignalSequenceNumber: number | undefined;
|
|
510
|
-
}
|
|
511
460
|
|
|
512
461
|
/**
|
|
513
462
|
* Starts monitoring and generation of telemetry related to op performance.
|