@fluidframework/container-loader 2.0.0-dev-rc.5.0.0.265721 → 2.0.0-dev-rc.5.0.0.268409
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/api-report/{container-loader.api.md → container-loader.alpha.api.md} +7 -17
- package/api-report/container-loader.beta.api.md +40 -0
- package/api-report/container-loader.public.api.md +40 -0
- package/dist/attachment.d.ts +1 -1
- package/dist/attachment.d.ts.map +1 -1
- package/dist/attachment.js.map +1 -1
- package/dist/audience.d.ts +1 -1
- package/dist/audience.d.ts.map +1 -1
- package/dist/audience.js.map +1 -1
- package/dist/catchUpMonitor.js.map +1 -1
- package/dist/connectionManager.d.ts +2 -2
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +3 -4
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +4 -2
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +18 -12
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +2 -2
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +84 -67
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +2 -2
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts +2 -2
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +7 -2
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +2 -2
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/debugLogger.d.ts.map +1 -1
- package/dist/debugLogger.js.map +1 -1
- package/dist/deltaManager.d.ts +4 -4
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +8 -9
- package/dist/deltaManager.js.map +1 -1
- package/dist/loadPaused.js.map +1 -1
- package/dist/loader.d.ts +8 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js.map +1 -1
- package/dist/memoryBlobStorage.d.ts +9 -0
- package/dist/memoryBlobStorage.d.ts.map +1 -0
- package/dist/memoryBlobStorage.js +58 -0
- package/dist/memoryBlobStorage.js.map +1 -0
- package/dist/noopHeuristic.d.ts +1 -1
- package/dist/noopHeuristic.d.ts.map +1 -1
- package/dist/noopHeuristic.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/protocol.d.ts +2 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +4 -4
- package/dist/protocol.js.map +1 -1
- package/dist/protocolTreeDocumentStorageService.d.ts +5 -5
- package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/dist/protocolTreeDocumentStorageService.js.map +1 -1
- package/dist/quorum.d.ts +1 -1
- package/dist/quorum.d.ts.map +1 -1
- package/dist/quorum.js.map +1 -1
- package/dist/retriableDocumentStorageService.d.ts +2 -2
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/dist/serializedStateManager.d.ts +5 -3
- package/dist/serializedStateManager.d.ts.map +1 -1
- package/dist/serializedStateManager.js.map +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +7 -7
- package/dist/utils.js.map +1 -1
- package/lib/attachment.d.ts +1 -1
- package/lib/attachment.d.ts.map +1 -1
- package/lib/attachment.js.map +1 -1
- package/lib/audience.d.ts +1 -1
- package/lib/audience.d.ts.map +1 -1
- package/lib/audience.js.map +1 -1
- package/lib/catchUpMonitor.js.map +1 -1
- package/lib/connectionManager.d.ts +2 -2
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +1 -2
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +4 -2
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +19 -13
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +2 -2
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +26 -9
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +2 -2
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts +2 -2
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +7 -2
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +2 -2
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/debugLogger.d.ts.map +1 -1
- package/lib/debugLogger.js.map +1 -1
- package/lib/deltaManager.d.ts +4 -4
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +1 -2
- package/lib/deltaManager.js.map +1 -1
- package/lib/loadPaused.js.map +1 -1
- package/lib/loader.d.ts +8 -1
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.js.map +1 -1
- package/lib/memoryBlobStorage.d.ts +9 -0
- package/lib/memoryBlobStorage.d.ts.map +1 -0
- package/lib/memoryBlobStorage.js +52 -0
- package/lib/memoryBlobStorage.js.map +1 -0
- package/lib/noopHeuristic.d.ts +1 -1
- package/lib/noopHeuristic.d.ts.map +1 -1
- package/lib/noopHeuristic.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/protocol.d.ts +2 -1
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +1 -1
- package/lib/protocol.js.map +1 -1
- package/lib/protocolTreeDocumentStorageService.d.ts +5 -5
- package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/lib/protocolTreeDocumentStorageService.js.map +1 -1
- package/lib/quorum.d.ts +1 -1
- package/lib/quorum.d.ts.map +1 -1
- package/lib/quorum.js.map +1 -1
- package/lib/retriableDocumentStorageService.d.ts +2 -2
- package/lib/retriableDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/lib/serializedStateManager.d.ts +5 -3
- package/lib/serializedStateManager.d.ts.map +1 -1
- package/lib/serializedStateManager.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/utils.d.ts +2 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +2 -2
- package/lib/utils.js.map +1 -1
- package/package.json +14 -15
- package/src/attachment.ts +3 -1
- package/src/audience.ts +1 -1
- package/src/catchUpMonitor.ts +1 -1
- package/src/connectionManager.ts +16 -16
- package/src/connectionStateHandler.ts +27 -19
- package/src/container.ts +51 -27
- package/src/containerContext.ts +6 -3
- package/src/containerStorageAdapter.ts +7 -6
- package/src/contracts.ts +7 -5
- package/src/debugLogger.ts +2 -3
- package/src/deltaManager.ts +7 -7
- package/src/loadPaused.ts +1 -1
- package/src/loader.ts +9 -1
- package/src/memoryBlobStorage.ts +80 -0
- package/src/noopHeuristic.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +7 -8
- package/src/protocolTreeDocumentStorageService.ts +1 -1
- package/src/quorum.ts +1 -1
- package/src/retriableDocumentStorageService.ts +3 -6
- package/src/serializedStateManager.ts +8 -7
- package/src/utils.ts +6 -7
package/dist/container.js
CHANGED
|
@@ -13,9 +13,10 @@ const container_definitions_1 = require("@fluidframework/container-definitions")
|
|
|
13
13
|
const internal_1 = require("@fluidframework/container-definitions/internal");
|
|
14
14
|
const core_interfaces_1 = require("@fluidframework/core-interfaces");
|
|
15
15
|
const internal_2 = require("@fluidframework/core-utils/internal");
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const internal_4 = require("@fluidframework/
|
|
16
|
+
const driver_definitions_1 = require("@fluidframework/driver-definitions");
|
|
17
|
+
const internal_3 = require("@fluidframework/driver-definitions/internal");
|
|
18
|
+
const internal_4 = require("@fluidframework/driver-utils/internal");
|
|
19
|
+
const internal_5 = require("@fluidframework/telemetry-utils/internal");
|
|
19
20
|
const structured_clone_1 = __importDefault(require("@ungap/structured-clone"));
|
|
20
21
|
const uuid_1 = require("uuid");
|
|
21
22
|
const attachment_js_1 = require("./attachment.js");
|
|
@@ -27,7 +28,9 @@ const containerContext_js_1 = require("./containerContext.js");
|
|
|
27
28
|
const containerStorageAdapter_js_1 = require("./containerStorageAdapter.js");
|
|
28
29
|
const contracts_js_1 = require("./contracts.js");
|
|
29
30
|
const deltaManager_js_1 = require("./deltaManager.js");
|
|
31
|
+
// eslint-disable-next-line import/no-deprecated
|
|
30
32
|
const loader_js_1 = require("./loader.js");
|
|
33
|
+
const memoryBlobStorage_js_1 = require("./memoryBlobStorage.js");
|
|
31
34
|
const noopHeuristic_js_1 = require("./noopHeuristic.js");
|
|
32
35
|
const packageVersion_js_1 = require("./packageVersion.js");
|
|
33
36
|
const protocol_js_1 = require("./protocol.js");
|
|
@@ -58,7 +61,7 @@ const packageNotFactoryError = "Code package does not implement IRuntimeFactory"
|
|
|
58
61
|
async function waitContainerToCatchUp(container) {
|
|
59
62
|
// Make sure we stop waiting if container is closed.
|
|
60
63
|
if (container.closed) {
|
|
61
|
-
throw new
|
|
64
|
+
throw new internal_5.UsageError("waitContainerToCatchUp: Container closed");
|
|
62
65
|
}
|
|
63
66
|
return new Promise((resolve, reject) => {
|
|
64
67
|
const deltaManager = container.deltaManager;
|
|
@@ -66,8 +69,8 @@ async function waitContainerToCatchUp(container) {
|
|
|
66
69
|
container.off("closed", closedCallback);
|
|
67
70
|
const baseMessage = "Container closed while waiting to catch up";
|
|
68
71
|
reject(err !== undefined
|
|
69
|
-
? (0,
|
|
70
|
-
: new
|
|
72
|
+
? (0, internal_5.wrapError)(err, (innerMessage) => new internal_5.GenericError(`${baseMessage}: ${innerMessage}`))
|
|
73
|
+
: new internal_5.GenericError(baseMessage));
|
|
71
74
|
};
|
|
72
75
|
container.on("closed", closedCallback);
|
|
73
76
|
// Depending on config, transition to "connected" state may include the guarantee
|
|
@@ -103,10 +106,10 @@ async function waitContainerToCatchUp(container) {
|
|
|
103
106
|
return;
|
|
104
107
|
}
|
|
105
108
|
const callback = () => {
|
|
106
|
-
container.off(
|
|
109
|
+
container.off(internal_5.connectedEventName, callback);
|
|
107
110
|
waitForOps();
|
|
108
111
|
};
|
|
109
|
-
container.on(
|
|
112
|
+
container.on(internal_5.connectedEventName, callback);
|
|
110
113
|
if (container.connectionState === connectionState_js_1.ConnectionState.Disconnected) {
|
|
111
114
|
container.connect();
|
|
112
115
|
}
|
|
@@ -121,7 +124,7 @@ const getCodeProposal = (quorum) => quorum.get("code") ?? quorum.get("code2");
|
|
|
121
124
|
* @param action - functor to call and measure
|
|
122
125
|
*/
|
|
123
126
|
async function ReportIfTooLong(logger, eventName, action) {
|
|
124
|
-
const event =
|
|
127
|
+
const event = internal_5.PerformanceEvent.start(logger, { eventName });
|
|
125
128
|
const props = await action();
|
|
126
129
|
if (event.duration > 200) {
|
|
127
130
|
event.end(props);
|
|
@@ -129,14 +132,14 @@ async function ReportIfTooLong(logger, eventName, action) {
|
|
|
129
132
|
}
|
|
130
133
|
exports.ReportIfTooLong = ReportIfTooLong;
|
|
131
134
|
const summarizerClientType = "summarizer";
|
|
132
|
-
class Container extends
|
|
135
|
+
class Container extends internal_5.EventEmitterWithErrorHandling {
|
|
133
136
|
/**
|
|
134
137
|
* Load an existing container.
|
|
135
138
|
*/
|
|
136
139
|
static async load(loadProps, createProps) {
|
|
137
140
|
const { version, pendingLocalState, loadMode, resolvedUrl } = loadProps;
|
|
138
141
|
const container = new Container(createProps, loadProps);
|
|
139
|
-
return
|
|
142
|
+
return internal_5.PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "Load", ...loadMode }, async (event) => new Promise((resolve, reject) => {
|
|
140
143
|
const defaultMode = { opsBeforeReturn: "cached" };
|
|
141
144
|
// if we have pendingLocalState, anything we cached is not useful and we shouldn't wait for connection
|
|
142
145
|
// to return container, so ignore this value and use undefined for opsBeforeReturn
|
|
@@ -145,7 +148,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
145
148
|
: loadMode ?? defaultMode;
|
|
146
149
|
const onClosed = (err) => {
|
|
147
150
|
// pre-0.58 error message: containerClosedWithoutErrorDuringLoad
|
|
148
|
-
reject(err ?? new
|
|
151
|
+
reject(err ?? new internal_5.GenericError("Container closed without error during load"));
|
|
149
152
|
};
|
|
150
153
|
container.on("closed", onClosed);
|
|
151
154
|
container
|
|
@@ -157,7 +160,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
157
160
|
event.end({ ...props });
|
|
158
161
|
resolve(container);
|
|
159
162
|
}, (error) => {
|
|
160
|
-
const err = (0,
|
|
163
|
+
const err = (0, internal_5.normalizeError)(error);
|
|
161
164
|
// Depending where error happens, we can be attempting to connect to web socket
|
|
162
165
|
// and continuously retrying (consider offline mode)
|
|
163
166
|
// Host has no container to close, so it's prudent to do it here
|
|
@@ -175,7 +178,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
175
178
|
*/
|
|
176
179
|
static async createDetached(createProps, codeDetails) {
|
|
177
180
|
const container = new Container(createProps);
|
|
178
|
-
return
|
|
181
|
+
return internal_5.PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "CreateDetached" }, async (_event) => {
|
|
179
182
|
await container.createDetached(codeDetails);
|
|
180
183
|
return container;
|
|
181
184
|
}, { start: true, end: true, cancel: "generic" });
|
|
@@ -188,7 +191,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
188
191
|
*/
|
|
189
192
|
static async rehydrateDetachedFromSnapshot(createProps, snapshot) {
|
|
190
193
|
const container = new Container(createProps);
|
|
191
|
-
return
|
|
194
|
+
return internal_5.PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "RehydrateDetachedFromSnapshot" }, async (_event) => {
|
|
192
195
|
const detachedContainerState = (0, utils_js_1.getDetachedContainerStateFromSerializedContainer)(snapshot);
|
|
193
196
|
await container.rehydrateDetachedFromSnapshot(detachedContainerState);
|
|
194
197
|
return container;
|
|
@@ -204,6 +207,14 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
204
207
|
// (calling this.handleDeltaConnectionArg() after setLoaded() call)
|
|
205
208
|
// If this assert fires, it means our logic managing connection flow is wrong, and the logic below is also wrong.
|
|
206
209
|
(0, internal_2.assert)(this.connectionState !== connectionState_js_1.ConnectionState.Connected, 0x969 /* not connected yet */);
|
|
210
|
+
// Track membership changes and update connection state accordingly
|
|
211
|
+
// We do this call here, instead of doing it in initializeProtocolState() due to pendingLocalState.
|
|
212
|
+
// When we load from stashed state, we let connectionStateHandler know about clientId from previous container instance.
|
|
213
|
+
// But we will play trailing ops from snapshot, including potentially playing join & leave ops for that same clientId!
|
|
214
|
+
// In other words, if connectionStateHandler has access to Quorum early in load sequence, it will see events (in stashed ops mode)
|
|
215
|
+
// in the order that is not possible in real life, that it may not expect.
|
|
216
|
+
// Ideally, we should supply pendingLocalState?.clientId here as well, not in constructor, but it does not matter (at least today)
|
|
217
|
+
this.connectionStateHandler.initProtocol(this.protocolHandler);
|
|
207
218
|
// Propagate current connection state through the system.
|
|
208
219
|
const readonly = this.readOnlyInfo.readonly ?? false;
|
|
209
220
|
// This call does not look like needed any more, with delaying all connection-related events past loaded phase.
|
|
@@ -337,7 +348,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
337
348
|
*/
|
|
338
349
|
async getEntryPoint() {
|
|
339
350
|
if (this._disposed) {
|
|
340
|
-
throw new
|
|
351
|
+
throw new internal_5.UsageError("The context is already disposed");
|
|
341
352
|
}
|
|
342
353
|
if (this._runtime !== undefined) {
|
|
343
354
|
return this._runtime.getEntryPoint?.();
|
|
@@ -362,7 +373,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
362
373
|
eventName: "ContainerEventHandlerException",
|
|
363
374
|
name: typeof name === "string" ? name : undefined,
|
|
364
375
|
}, error);
|
|
365
|
-
this.close((0,
|
|
376
|
+
this.close((0, internal_5.normalizeError)(error));
|
|
366
377
|
});
|
|
367
378
|
/**
|
|
368
379
|
* Lifecycle state of the container, used mainly to prevent re-entrancy and telemetry
|
|
@@ -392,14 +403,14 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
392
403
|
this._lifecycleEvents = new client_utils_1.TypedEventEmitter();
|
|
393
404
|
this._disposed = false;
|
|
394
405
|
this.attach = (0, utils_js_1.runSingle)(async (request, attachProps) => {
|
|
395
|
-
await
|
|
406
|
+
await internal_5.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Attach" }, async () => {
|
|
396
407
|
if (this._lifecycleState !== "loaded" ||
|
|
397
408
|
this.attachmentData.state === container_definitions_1.AttachState.Attached) {
|
|
398
409
|
// pre-0.58 error message: containerNotValidForAttach
|
|
399
|
-
throw new
|
|
410
|
+
throw new internal_5.UsageError(`The Container is not in a valid state for attach [${this._lifecycleState}] and [${this.attachState}]`);
|
|
400
411
|
}
|
|
401
412
|
const normalizeErrorAndClose = (error) => {
|
|
402
|
-
const newError = (0,
|
|
413
|
+
const newError = (0, internal_5.normalizeError)(error);
|
|
403
414
|
this.close(newError);
|
|
404
415
|
// add resolved URL on error object so that host has the ability to find this document and delete it
|
|
405
416
|
newError.addTelemetryProperties({
|
|
@@ -436,7 +447,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
436
447
|
const createNewResolvedUrl = await this.urlResolver.resolve(request);
|
|
437
448
|
(0, internal_2.assert)(this.client.details.type !== summarizerClientType &&
|
|
438
449
|
createNewResolvedUrl !== undefined, 0x2c4 /* "client should not be summarizer before container is created" */);
|
|
439
|
-
this.service = await (0,
|
|
450
|
+
this.service = await (0, internal_4.runWithRetry)(async () => this.serviceFactory.createContainer(summary, createNewResolvedUrl, this.subLogger, false), "containerAttach", this.mc.logger, {
|
|
440
451
|
cancel: this._deltaManager.closeAbortController.signal,
|
|
441
452
|
});
|
|
442
453
|
}
|
|
@@ -461,6 +472,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
461
472
|
const snapshotWithBlobs = await attachP;
|
|
462
473
|
this.serializedStateManager.setInitialSnapshot(snapshotWithBlobs);
|
|
463
474
|
if (!this.closed) {
|
|
475
|
+
this.detachedBlobStorage.dispose?.();
|
|
464
476
|
this.handleDeltaConnectionArg(attachProps?.deltaConnection, {
|
|
465
477
|
fetchOpsFromStorage: false,
|
|
466
478
|
reason: { text: "createDetached" },
|
|
@@ -498,7 +510,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
498
510
|
// Tracking alternative ways to handle this in AB#4129.
|
|
499
511
|
this.options = { ...options };
|
|
500
512
|
this.scope = scope;
|
|
501
|
-
this.detachedBlobStorage = detachedBlobStorage;
|
|
513
|
+
this.detachedBlobStorage = detachedBlobStorage ?? (0, memoryBlobStorage_js_1.createMemoryDetachedBlobStorage)();
|
|
502
514
|
this.protocolHandlerBuilder =
|
|
503
515
|
protocolHandlerBuilder ??
|
|
504
516
|
((attributes, quorumSnapshot, sendProposal) => new protocol_js_1.ProtocolHandler(attributes, quorumSnapshot, sendProposal, new audience_js_1.Audience(), (clientId) => this.clientsWhoShouldHaveLeft.has(clientId)));
|
|
@@ -517,7 +529,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
517
529
|
const clientType = `${interactive ? "interactive" : "noninteractive"}${type !== undefined && type !== "" ? `/${type}` : ""}`;
|
|
518
530
|
// Need to use the property getter for docId because for detached flow we don't have the docId initially.
|
|
519
531
|
// We assign the id later so property getter is used.
|
|
520
|
-
this.subLogger = (0,
|
|
532
|
+
this.subLogger = (0, internal_5.createChildLogger)({
|
|
521
533
|
logger: subLogger,
|
|
522
534
|
properties: {
|
|
523
535
|
all: {
|
|
@@ -552,10 +564,13 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
552
564
|
},
|
|
553
565
|
});
|
|
554
566
|
// Prefix all events in this file with container-loader
|
|
555
|
-
this.mc = (0,
|
|
567
|
+
this.mc = (0, internal_5.createChildMonitoringContext)({ logger: this.subLogger, namespace: "Container" });
|
|
556
568
|
this._deltaManager = this.createDeltaManager();
|
|
557
569
|
this.connectionStateHandler = (0, connectionStateHandler_js_1.createConnectionStateHandler)({
|
|
558
570
|
logger: this.mc.logger,
|
|
571
|
+
// WARNING: logger on this context should not including getters like containerConnectionState above (on this.subLogger),
|
|
572
|
+
// as that will result in attempt to dereference this.connectionStateHandler from this call while it's still undefined.
|
|
573
|
+
mc: (0, internal_5.loggerToMonitoringContext)(subLogger),
|
|
559
574
|
connectionStateChanged: (value, oldState, reason) => {
|
|
560
575
|
this.logConnectionStateChangeTelemetry(value, oldState, reason);
|
|
561
576
|
if (this.loaded) {
|
|
@@ -606,7 +621,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
606
621
|
this.clientsWhoShouldHaveLeft.add(clientId);
|
|
607
622
|
},
|
|
608
623
|
onCriticalError: (error) => {
|
|
609
|
-
this.close((0,
|
|
624
|
+
this.close((0, internal_5.normalizeError)(error));
|
|
610
625
|
},
|
|
611
626
|
}, this.deltaManager, pendingLocalState?.clientId);
|
|
612
627
|
this.on(savedContainerEvent, () => {
|
|
@@ -615,14 +630,14 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
615
630
|
// We expose our storage publicly, so it's possible others may call uploadSummaryWithContext() with a
|
|
616
631
|
// non-combined summary tree (in particular, ContainerRuntime.submitSummary). We'll intercept those calls
|
|
617
632
|
// using this callback and fix them up.
|
|
618
|
-
const addProtocolSummaryIfMissing = (summaryTree) => (0,
|
|
633
|
+
const addProtocolSummaryIfMissing = (summaryTree) => (0, internal_4.isCombinedAppAndProtocolSummary)(summaryTree) === true
|
|
619
634
|
? summaryTree
|
|
620
635
|
: (0, utils_js_1.combineAppAndProtocolSummary)(summaryTree, this.captureProtocolSummary());
|
|
621
636
|
// Whether the combined summary tree has been forced on by either the loader option or the monitoring context.
|
|
622
637
|
// Even if not forced on via this flag, combined summaries may still be enabled by service policy.
|
|
623
638
|
const forceEnableSummarizeProtocolTree = this.mc.config.getBoolean("Fluid.Container.summarizeProtocolTree2") ??
|
|
624
639
|
options.summarizeProtocolTree;
|
|
625
|
-
this.storageAdapter = new containerStorageAdapter_js_1.ContainerStorageAdapter(detachedBlobStorage, this.mc.logger, pendingLocalState?.snapshotBlobs, pendingLocalState?.loadedGroupIdSnapshots, addProtocolSummaryIfMissing, forceEnableSummarizeProtocolTree);
|
|
640
|
+
this.storageAdapter = new containerStorageAdapter_js_1.ContainerStorageAdapter(this.detachedBlobStorage, this.mc.logger, pendingLocalState?.snapshotBlobs, pendingLocalState?.loadedGroupIdSnapshots, addProtocolSummaryIfMissing, forceEnableSummarizeProtocolTree);
|
|
626
641
|
const offlineLoadEnabled = (this.isInteractiveClient &&
|
|
627
642
|
this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad")) ??
|
|
628
643
|
options.enableOfflineLoad === true;
|
|
@@ -771,7 +786,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
771
786
|
}
|
|
772
787
|
async getPendingLocalStateCore(props) {
|
|
773
788
|
if (this.closed || this._disposed) {
|
|
774
|
-
throw new
|
|
789
|
+
throw new internal_5.UsageError("Pending state cannot be retried if the container is closed or disposed");
|
|
775
790
|
}
|
|
776
791
|
(0, internal_2.assert)(this.attachmentData.state === container_definitions_1.AttachState.Attached, 0x0d1 /* "Container should be attached before close" */);
|
|
777
792
|
(0, internal_2.assert)(this.resolvedUrl !== undefined && this.resolvedUrl.type === "fluid", 0x0d2 /* "resolved url should be valid Fluid url" */);
|
|
@@ -789,7 +804,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
789
804
|
*/
|
|
790
805
|
serialize() {
|
|
791
806
|
if (this.attachmentData.state === container_definitions_1.AttachState.Attached || this.closed) {
|
|
792
|
-
throw new
|
|
807
|
+
throw new internal_5.UsageError("Container must not be attached or closed.");
|
|
793
808
|
}
|
|
794
809
|
const attachingData = this.attachmentData.state === container_definitions_1.AttachState.Attaching ? this.attachmentData : undefined;
|
|
795
810
|
const combinedSummary = attachingData?.summary ??
|
|
@@ -802,7 +817,8 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
802
817
|
baseSnapshot,
|
|
803
818
|
snapshotBlobs,
|
|
804
819
|
pendingRuntimeState,
|
|
805
|
-
hasAttachmentBlobs:
|
|
820
|
+
hasAttachmentBlobs: this.detachedBlobStorage.size > 0,
|
|
821
|
+
attachmentBlobs: (0, memoryBlobStorage_js_1.serializeMemoryDetachedBlobStorage)(this.detachedBlobStorage),
|
|
806
822
|
};
|
|
807
823
|
return JSON.stringify(detachedContainerState);
|
|
808
824
|
}
|
|
@@ -824,10 +840,10 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
824
840
|
}
|
|
825
841
|
connect() {
|
|
826
842
|
if (this.closed) {
|
|
827
|
-
throw new
|
|
843
|
+
throw new internal_5.UsageError(`The Container is closed and cannot be connected`);
|
|
828
844
|
}
|
|
829
845
|
else if (this.attachState !== container_definitions_1.AttachState.Attached) {
|
|
830
|
-
throw new
|
|
846
|
+
throw new internal_5.UsageError(`The Container is not attached and cannot be connected`);
|
|
831
847
|
}
|
|
832
848
|
else if (!this.connected) {
|
|
833
849
|
// Note: no need to fetch ops as we do it preemptively as part of DeltaManager.attachOpHandler().
|
|
@@ -850,7 +866,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
850
866
|
}
|
|
851
867
|
disconnect() {
|
|
852
868
|
if (this.closed) {
|
|
853
|
-
throw new
|
|
869
|
+
throw new internal_5.UsageError(`The Container is closed and cannot be disconnected`);
|
|
854
870
|
}
|
|
855
871
|
else {
|
|
856
872
|
this.disconnectInternal({ text: "DocumentDisconnect" });
|
|
@@ -905,7 +921,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
905
921
|
return;
|
|
906
922
|
}
|
|
907
923
|
// pre-0.58 error message: existingContextDoesNotSatisfyIncomingProposal
|
|
908
|
-
const error = new
|
|
924
|
+
const error = new internal_5.GenericError("Existing context does not satisfy incoming proposal");
|
|
909
925
|
this.close(error);
|
|
910
926
|
}
|
|
911
927
|
/**
|
|
@@ -986,7 +1002,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
986
1002
|
true && this.service?.policies?.supportGetSnapshotApi === true;
|
|
987
1003
|
// Fetch specified snapshot.
|
|
988
1004
|
const { baseSnapshot, version } = await this.serializedStateManager.fetchSnapshot(specifiedVersion, supportGetSnapshotApi);
|
|
989
|
-
const baseSnapshotTree = (0,
|
|
1005
|
+
const baseSnapshotTree = (0, internal_4.getSnapshotTree)(baseSnapshot);
|
|
990
1006
|
this._loadedFromVersion = version;
|
|
991
1007
|
const attributes = await (0, utils_js_1.getDocumentAttributes)(this.storageAdapter, baseSnapshotTree);
|
|
992
1008
|
// If we saved ops, we will replay them and don't need DeltaManager to fetch them
|
|
@@ -1021,7 +1037,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1021
1037
|
const codeDetails = this.getCodeDetailsFromQuorum();
|
|
1022
1038
|
await this.instantiateRuntime(codeDetails, baseSnapshotTree,
|
|
1023
1039
|
// give runtime a dummy value so it knows we're loading from a stash blob
|
|
1024
|
-
pendingLocalState ? pendingLocalState?.pendingRuntimeState ?? {} : undefined, (0,
|
|
1040
|
+
pendingLocalState ? pendingLocalState?.pendingRuntimeState ?? {} : undefined, (0, internal_4.isInstanceOfISnapshot)(baseSnapshot) ? baseSnapshot : undefined);
|
|
1025
1041
|
// replay saved ops
|
|
1026
1042
|
if (pendingLocalState) {
|
|
1027
1043
|
for (const message of pendingLocalState.savedOps) {
|
|
@@ -1040,8 +1056,8 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1040
1056
|
if (!this.closed) {
|
|
1041
1057
|
if (opsBeforeReturnP !== undefined) {
|
|
1042
1058
|
this._deltaManager.inbound.resume();
|
|
1043
|
-
await
|
|
1044
|
-
await
|
|
1059
|
+
await internal_5.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "WaitOps" }, async () => opsBeforeReturnP);
|
|
1060
|
+
await internal_5.PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "WaitOpProcessing" }, async () => this._deltaManager.inbound.waitTillProcessingDone());
|
|
1045
1061
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1046
1062
|
this._deltaManager.inbound.pause();
|
|
1047
1063
|
}
|
|
@@ -1087,9 +1103,12 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1087
1103
|
await this.instantiateRuntime(codeDetails, undefined);
|
|
1088
1104
|
this.setLoaded();
|
|
1089
1105
|
}
|
|
1090
|
-
async rehydrateDetachedFromSnapshot({ baseSnapshot, snapshotBlobs, hasAttachmentBlobs, pendingRuntimeState, }) {
|
|
1106
|
+
async rehydrateDetachedFromSnapshot({ baseSnapshot, snapshotBlobs, hasAttachmentBlobs, attachmentBlobs, pendingRuntimeState, }) {
|
|
1091
1107
|
if (hasAttachmentBlobs) {
|
|
1092
|
-
|
|
1108
|
+
if (attachmentBlobs !== undefined) {
|
|
1109
|
+
(0, memoryBlobStorage_js_1.tryInitializeMemoryDetachedBlobStorage)(this.detachedBlobStorage, attachmentBlobs);
|
|
1110
|
+
}
|
|
1111
|
+
(0, internal_2.assert)(this.detachedBlobStorage.size > 0, 0x250 /* "serialized container with attachment blobs must be rehydrated with detached blob storage" */);
|
|
1093
1112
|
}
|
|
1094
1113
|
const snapshotTreeWithBlobContents = (0, utils_js_1.combineSnapshotTreeAndSnapshotBlobs)(baseSnapshot, snapshotBlobs);
|
|
1095
1114
|
this.storageAdapter.loadSnapshotFromSnapshotBlobs(snapshotBlobs);
|
|
@@ -1097,7 +1116,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1097
1116
|
await this.attachDeltaManagerOpHandler(attributes);
|
|
1098
1117
|
// Initialize the protocol handler
|
|
1099
1118
|
const baseTree = (0, utils_js_1.getProtocolSnapshotTree)(snapshotTreeWithBlobContents);
|
|
1100
|
-
const qValues = await (0,
|
|
1119
|
+
const qValues = await (0, internal_4.readAndParse)(this.storageAdapter, baseTree.blobs.quorumValues);
|
|
1101
1120
|
this.initializeProtocolState(attributes, {
|
|
1102
1121
|
members: [],
|
|
1103
1122
|
proposals: [],
|
|
@@ -1117,24 +1136,22 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1117
1136
|
const baseTree = (0, utils_js_1.getProtocolSnapshotTree)(snapshot);
|
|
1118
1137
|
[quorumSnapshot.members, quorumSnapshot.proposals, quorumSnapshot.values] =
|
|
1119
1138
|
await Promise.all([
|
|
1120
|
-
(0,
|
|
1121
|
-
(0,
|
|
1122
|
-
(0,
|
|
1139
|
+
(0, internal_4.readAndParse)(storage, baseTree.blobs.quorumMembers),
|
|
1140
|
+
(0, internal_4.readAndParse)(storage, baseTree.blobs.quorumProposals),
|
|
1141
|
+
(0, internal_4.readAndParse)(storage, baseTree.blobs.quorumValues),
|
|
1123
1142
|
]);
|
|
1124
1143
|
}
|
|
1125
1144
|
this.initializeProtocolState(attributes, quorumSnapshot);
|
|
1126
1145
|
}
|
|
1127
1146
|
initializeProtocolState(attributes, quorumSnapshot) {
|
|
1128
|
-
const protocol = this.protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) => this.submitMessage(
|
|
1129
|
-
const protocolLogger = (0,
|
|
1147
|
+
const protocol = this.protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) => this.submitMessage(internal_3.MessageType.Propose, JSON.stringify({ key, value })));
|
|
1148
|
+
const protocolLogger = (0, internal_5.createChildLogger)({
|
|
1130
1149
|
logger: this.subLogger,
|
|
1131
1150
|
namespace: "ProtocolHandler",
|
|
1132
1151
|
});
|
|
1133
1152
|
protocol.quorum.on("error", (error) => {
|
|
1134
1153
|
protocolLogger.sendErrorEvent(error);
|
|
1135
1154
|
});
|
|
1136
|
-
// Track membership changes and update connection state accordingly
|
|
1137
|
-
this.connectionStateHandler.initProtocol(protocol);
|
|
1138
1155
|
protocol.quorum.on("addProposal", (proposal) => {
|
|
1139
1156
|
if (proposal.key === "code" || proposal.key === "code2") {
|
|
1140
1157
|
this.emit("codeDetailsProposed", proposal.value, proposal);
|
|
@@ -1148,7 +1165,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1148
1165
|
});
|
|
1149
1166
|
}
|
|
1150
1167
|
this.processCodeProposal().catch((error) => {
|
|
1151
|
-
const normalizedError = (0,
|
|
1168
|
+
const normalizedError = (0, internal_5.normalizeError)(error);
|
|
1152
1169
|
this.close(normalizedError);
|
|
1153
1170
|
throw error;
|
|
1154
1171
|
});
|
|
@@ -1166,22 +1183,22 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1166
1183
|
tree: {
|
|
1167
1184
|
attributes: {
|
|
1168
1185
|
content: JSON.stringify(this.protocolHandler.attributes),
|
|
1169
|
-
type:
|
|
1186
|
+
type: driver_definitions_1.SummaryType.Blob,
|
|
1170
1187
|
},
|
|
1171
1188
|
quorumMembers: {
|
|
1172
1189
|
content: JSON.stringify(quorumSnapshot.members),
|
|
1173
|
-
type:
|
|
1190
|
+
type: driver_definitions_1.SummaryType.Blob,
|
|
1174
1191
|
},
|
|
1175
1192
|
quorumProposals: {
|
|
1176
1193
|
content: JSON.stringify(quorumSnapshot.proposals),
|
|
1177
|
-
type:
|
|
1194
|
+
type: driver_definitions_1.SummaryType.Blob,
|
|
1178
1195
|
},
|
|
1179
1196
|
quorumValues: {
|
|
1180
1197
|
content: JSON.stringify(quorumSnapshot.values),
|
|
1181
|
-
type:
|
|
1198
|
+
type: driver_definitions_1.SummaryType.Blob,
|
|
1182
1199
|
},
|
|
1183
1200
|
},
|
|
1184
|
-
type:
|
|
1201
|
+
type: driver_definitions_1.SummaryType.Tree,
|
|
1185
1202
|
};
|
|
1186
1203
|
return summary;
|
|
1187
1204
|
}
|
|
@@ -1230,7 +1247,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1230
1247
|
}
|
|
1231
1248
|
createDeltaManager() {
|
|
1232
1249
|
const serviceProvider = () => this.service;
|
|
1233
|
-
const deltaManager = new deltaManager_js_1.DeltaManager(serviceProvider, (0,
|
|
1250
|
+
const deltaManager = new deltaManager_js_1.DeltaManager(serviceProvider, (0, internal_5.createChildLogger)({ logger: this.subLogger, namespace: "DeltaManager" }), () => this.activeConnection(), (props) => new connectionManager_js_1.ConnectionManager(serviceProvider, () => this.isDirty, this.client, this._canReconnect, (0, internal_5.createChildLogger)({ logger: this.subLogger, namespace: "ConnectionManager" }), props));
|
|
1234
1251
|
// Disable inbound queues as Container is not ready to accept any ops until we are fully loaded!
|
|
1235
1252
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
1236
1253
|
deltaManager.inbound.pause();
|
|
@@ -1320,7 +1337,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1320
1337
|
if (value === connectionState_js_1.ConnectionState.Connected) {
|
|
1321
1338
|
durationFromDisconnected =
|
|
1322
1339
|
time - this.connectionTransitionTimes[connectionState_js_1.ConnectionState.Disconnected];
|
|
1323
|
-
durationFromDisconnected = (0,
|
|
1340
|
+
durationFromDisconnected = (0, internal_5.formatTick)(durationFromDisconnected);
|
|
1324
1341
|
}
|
|
1325
1342
|
else if (value === connectionState_js_1.ConnectionState.CatchingUp) {
|
|
1326
1343
|
// This info is of most interesting while Catching Up.
|
|
@@ -1343,7 +1360,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1343
1360
|
clientId: this.connectionStateHandler.clientId,
|
|
1344
1361
|
autoReconnect,
|
|
1345
1362
|
opsBehind,
|
|
1346
|
-
online:
|
|
1363
|
+
online: internal_4.OnlineStatus[(0, internal_4.isOnline)()],
|
|
1347
1364
|
lastVisible: this.lastVisible !== undefined
|
|
1348
1365
|
? client_utils_1.performance.now() - this.lastVisible
|
|
1349
1366
|
: undefined,
|
|
@@ -1372,17 +1389,17 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1372
1389
|
// Both protocol and context should not be undefined if we got so far.
|
|
1373
1390
|
this.setContextConnectedState(connected, this.readOnlyInfo.readonly ?? false);
|
|
1374
1391
|
this.protocolHandler.setConnectionState(connected, this.clientId);
|
|
1375
|
-
(0,
|
|
1392
|
+
(0, internal_5.raiseConnectedEvent)(this.mc.logger, this, connected, this.clientId, disconnectedReason?.text);
|
|
1376
1393
|
}
|
|
1377
1394
|
// back-compat: ADO #1385: Remove in the future, summary op should come through submitSummaryMessage()
|
|
1378
1395
|
submitContainerMessage(type, contents, batch, metadata) {
|
|
1379
1396
|
switch (type) {
|
|
1380
|
-
case
|
|
1397
|
+
case internal_3.MessageType.Operation:
|
|
1381
1398
|
return this.submitMessage(type, JSON.stringify(contents), batch, metadata);
|
|
1382
|
-
case
|
|
1399
|
+
case internal_3.MessageType.Summarize:
|
|
1383
1400
|
return this.submitSummaryMessage(contents);
|
|
1384
1401
|
default: {
|
|
1385
|
-
const newError = new
|
|
1402
|
+
const newError = new internal_5.GenericError("invalidContainerSubmitOpType", undefined /* error */, { messageType: type });
|
|
1386
1403
|
this.close(newError);
|
|
1387
1404
|
return -1;
|
|
1388
1405
|
}
|
|
@@ -1392,7 +1409,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1392
1409
|
submitBatch(batch, referenceSequenceNumber) {
|
|
1393
1410
|
let clientSequenceNumber = -1;
|
|
1394
1411
|
for (const message of batch) {
|
|
1395
|
-
clientSequenceNumber = this.submitMessage(
|
|
1412
|
+
clientSequenceNumber = this.submitMessage(internal_3.MessageType.Operation, message.contents, true, // batch
|
|
1396
1413
|
message.metadata, message.compression, referenceSequenceNumber);
|
|
1397
1414
|
}
|
|
1398
1415
|
this._deltaManager.flush();
|
|
@@ -1407,7 +1424,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1407
1424
|
summary.details = {};
|
|
1408
1425
|
}
|
|
1409
1426
|
summary.details.includesProtocolTree = this.storageAdapter.summarizeProtocolTree;
|
|
1410
|
-
return this.submitMessage(
|
|
1427
|
+
return this.submitMessage(internal_3.MessageType.Summarize, JSON.stringify(summary), false /* batch */, undefined /* metadata */, undefined /* compression */, referenceSequenceNumber);
|
|
1411
1428
|
}
|
|
1412
1429
|
submitMessage(type, contents, batch, metadata, compression, referenceSequenceNumber) {
|
|
1413
1430
|
if (this.connectionState !== connectionState_js_1.ConnectionState.Connected) {
|
|
@@ -1439,14 +1456,14 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1439
1456
|
// Hitting this assert would imply we lost activeConnection between notifying the heuristic of a processed message and
|
|
1440
1457
|
// running the microtask that the heuristic queued in response.
|
|
1441
1458
|
(0, internal_2.assert)(this.activeConnection(), 0x241 /* "Trying to send noop without active connection" */);
|
|
1442
|
-
this.submitMessage(
|
|
1459
|
+
this.submitMessage(internal_3.MessageType.NoOp);
|
|
1443
1460
|
});
|
|
1444
1461
|
}
|
|
1445
1462
|
this.noopHeuristic.notifyMessageProcessed(message);
|
|
1446
1463
|
// The contract with the protocolHandler is that returning "immediateNoOp" is equivalent to "please immediately accept the proposal I just processed".
|
|
1447
1464
|
if (result.immediateNoOp === true) {
|
|
1448
1465
|
// ADO:1385: Remove cast and use MessageType once definition changes propagate
|
|
1449
|
-
this.submitMessage(
|
|
1466
|
+
this.submitMessage(internal_4.MessageType2.Accept);
|
|
1450
1467
|
}
|
|
1451
1468
|
}
|
|
1452
1469
|
this.emit("op", message);
|
|
@@ -1471,7 +1488,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1471
1488
|
// are set. Global requests will still go directly to the loader
|
|
1472
1489
|
const maybeLoader = this.scope;
|
|
1473
1490
|
const loader = new loader_js_1.RelativeLoader(this, maybeLoader.ILoader);
|
|
1474
|
-
const loadCodeResult = await
|
|
1491
|
+
const loadCodeResult = await internal_5.PerformanceEvent.timedExecAsync(this.subLogger, { eventName: "CodeLoad" }, async () => this.codeLoader.load(codeDetails));
|
|
1475
1492
|
this._loadedModule = {
|
|
1476
1493
|
module: loadCodeResult.module,
|
|
1477
1494
|
// An older interface ICodeLoader could return an IFluidModule which didn't have details.
|
|
@@ -1486,7 +1503,7 @@ class Container extends internal_4.EventEmitterWithErrorHandling {
|
|
|
1486
1503
|
}
|
|
1487
1504
|
const existing = snapshotTree !== undefined;
|
|
1488
1505
|
const context = new containerContext_js_1.ContainerContext(this.options, this.scope, snapshotTree, this._loadedFromVersion, this._deltaManager, this.storageAdapter, this.protocolHandler.quorum, this.protocolHandler.audience, loader, (type, contents, batch, metadata) => this.submitContainerMessage(type, contents, batch, metadata), (summaryOp, referenceSequenceNumber) => this.submitSummaryMessage(summaryOp, referenceSequenceNumber), (batch, referenceSequenceNumber) => this.submitBatch(batch, referenceSequenceNumber), (content, targetClientId) => this.submitSignal(content, targetClientId), (error) => this.dispose(error), (error) => this.close(error), this.updateDirtyContainerState, this.getAbsoluteUrl, () => this.resolvedUrl?.id, () => this.clientId, () => this.attachState, () => this.connected, this._deltaManager.clientDetails, existing, this.subLogger, pendingLocalState, snapshot);
|
|
1489
|
-
this._runtime = await
|
|
1506
|
+
this._runtime = await internal_5.PerformanceEvent.timedExecAsync(this.subLogger, { eventName: "InstantiateRuntime" }, async () => runtimeFactory.instantiateRuntime(context, existing));
|
|
1490
1507
|
this._lifecycleEvents.emit("runtimeInstantiated");
|
|
1491
1508
|
this._loadedCodeDetails = codeDetails;
|
|
1492
1509
|
}
|