@fluidframework/container-loader 0.58.2001 → 0.59.2000-61729
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/dist/connectionManager.d.ts +0 -2
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +14 -11
- package/dist/connectionManager.js.map +1 -1
- package/dist/container.d.ts +22 -10
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +81 -39
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +5 -7
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +6 -4
- package/dist/containerContext.js.map +1 -1
- package/dist/contracts.d.ts +8 -1
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +21 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deltaManager.d.ts +2 -1
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +1 -1
- package/dist/deltaManager.js.map +1 -1
- package/dist/loader.d.ts +4 -4
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.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/retriableDocumentStorageService.js +1 -1
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +0 -1
- package/dist/utils.js.map +1 -1
- package/lib/connectionManager.d.ts +0 -2
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +14 -11
- package/lib/connectionManager.js.map +1 -1
- package/lib/container.d.ts +22 -10
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +81 -39
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +5 -7
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +6 -4
- package/lib/containerContext.js.map +1 -1
- package/lib/contracts.d.ts +8 -1
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js +19 -0
- package/lib/contracts.js.map +1 -1
- package/lib/deltaManager.d.ts +2 -1
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +1 -1
- package/lib/deltaManager.js.map +1 -1
- package/lib/loader.d.ts +4 -4
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.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/retriableDocumentStorageService.js +1 -1
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +0 -1
- package/lib/utils.js.map +1 -1
- package/package.json +25 -13
- package/src/connectionManager.ts +16 -12
- package/src/container.ts +98 -39
- package/src/containerContext.ts +11 -13
- package/src/contracts.ts +20 -0
- package/src/deltaManager.ts +3 -2
- package/src/loader.ts +5 -6
- package/src/packageVersion.ts +1 -1
- package/src/retriableDocumentStorageService.ts +1 -1
- package/src/utils.ts +0 -1
package/lib/container.js
CHANGED
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
import merge from "lodash/merge";
|
|
7
7
|
import { v4 as uuid } from "uuid";
|
|
8
8
|
import { assert, performance, unreachableCase } from "@fluidframework/common-utils";
|
|
9
|
-
import { isFluidCodeDetails, } from "@fluidframework/
|
|
10
|
-
import { AttachState, } from "@fluidframework/container-definitions";
|
|
9
|
+
import { AttachState, isFluidCodeDetails, } from "@fluidframework/container-definitions";
|
|
11
10
|
import { DataCorruptionError, extractSafePropertiesFromMessage, GenericError, UsageError, } from "@fluidframework/container-utils";
|
|
12
11
|
import { readAndParse, OnlineStatus, isOnline, ensureFluidResolvedUrl, combineAppAndProtocolSummary, runWithRetry, isFluidResolvedUrl, } from "@fluidframework/driver-utils";
|
|
13
12
|
import { isSystemMessage, ProtocolOpHandler, } from "@fluidframework/protocol-base";
|
|
@@ -15,7 +14,7 @@ import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions"
|
|
|
15
14
|
import { ChildLogger, EventEmitterWithErrorHandling, PerformanceEvent, raiseConnectedEvent, TelemetryLogger, connectedEventName, disconnectedEventName, normalizeError, loggerToMonitoringContext, } from "@fluidframework/telemetry-utils";
|
|
16
15
|
import { Audience } from "./audience";
|
|
17
16
|
import { ContainerContext } from "./containerContext";
|
|
18
|
-
import { ReconnectMode } from "./contracts";
|
|
17
|
+
import { ReconnectMode, getPackageName } from "./contracts";
|
|
19
18
|
import { DeltaManager } from "./deltaManager";
|
|
20
19
|
import { DeltaManagerProxy } from "./deltaManagerProxy";
|
|
21
20
|
import { RelativeLoader } from "./loader";
|
|
@@ -102,6 +101,7 @@ export async function waitContainerToCatchUp(container) {
|
|
|
102
101
|
const getCodeProposal =
|
|
103
102
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
104
103
|
(quorum) => { var _a; return (_a = quorum.get("code")) !== null && _a !== void 0 ? _a : quorum.get("code2"); };
|
|
104
|
+
const summarizerClientType = "summarizer";
|
|
105
105
|
export class Container extends EventEmitterWithErrorHandling {
|
|
106
106
|
constructor(loader, config) {
|
|
107
107
|
var _a, _b, _c;
|
|
@@ -119,7 +119,6 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
119
119
|
this._attachState = AttachState.Detached;
|
|
120
120
|
this.resumedOpProcessingAfterLoad = false;
|
|
121
121
|
this.firstConnection = true;
|
|
122
|
-
this.manualReconnectInProgress = false;
|
|
123
122
|
this.connectionTransitionTimes = [];
|
|
124
123
|
this.messageCountAfterDisconnection = 0;
|
|
125
124
|
this.attachStarted = false;
|
|
@@ -346,7 +345,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
346
345
|
}
|
|
347
346
|
get context() {
|
|
348
347
|
if (this._context === undefined) {
|
|
349
|
-
throw new
|
|
348
|
+
throw new GenericError("Attempted to access context before it was defined");
|
|
350
349
|
}
|
|
351
350
|
return this._context;
|
|
352
351
|
}
|
|
@@ -367,6 +366,9 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
367
366
|
get readOnlyInfo() {
|
|
368
367
|
return this._deltaManager.readOnlyInfo;
|
|
369
368
|
}
|
|
369
|
+
get closeSignal() {
|
|
370
|
+
return this._deltaManager.closeAbortController.signal;
|
|
371
|
+
}
|
|
370
372
|
/**
|
|
371
373
|
* Tracks host requiring read-only mode.
|
|
372
374
|
*/
|
|
@@ -541,7 +543,10 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
541
543
|
const createNewResolvedUrl = await this.urlResolver.resolve(request);
|
|
542
544
|
ensureFluidResolvedUrl(createNewResolvedUrl);
|
|
543
545
|
if (this.service === undefined) {
|
|
544
|
-
this.
|
|
546
|
+
assert(this.client.details.type !== summarizerClientType, 0x2c4 /* "client should not be summarizer before container is created" */);
|
|
547
|
+
this.service = await runWithRetry(async () => this.serviceFactory.createContainer(summary, createNewResolvedUrl, this.subLogger, false), "containerAttach", this.mc.logger, {
|
|
548
|
+
cancel: this.closeSignal,
|
|
549
|
+
});
|
|
545
550
|
}
|
|
546
551
|
const resolvedUrl = this.service.resolvedUrl;
|
|
547
552
|
ensureFluidResolvedUrl(resolvedUrl);
|
|
@@ -597,11 +602,28 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
597
602
|
async request(path) {
|
|
598
603
|
return PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Request" }, async () => this.context.request(path), { end: true, cancel: "error" });
|
|
599
604
|
}
|
|
605
|
+
/**
|
|
606
|
+
* Dictates whether or not the current container will automatically attempt to reconnect to the delta stream
|
|
607
|
+
* after receiving a disconnect event
|
|
608
|
+
* @param reconnect - Boolean indicating if reconnect should automatically occur
|
|
609
|
+
* @deprecated - 0.58, This API will be removed in 1.0
|
|
610
|
+
* Use `connect()` and `disconnect()` instead of `setAutoReconnect(true)` and `setAutoReconnect(false)` respectively
|
|
611
|
+
* See https://github.com/microsoft/FluidFramework/issues/9167 for context
|
|
612
|
+
*/
|
|
600
613
|
setAutoReconnect(reconnect) {
|
|
601
614
|
if (this.closed) {
|
|
602
615
|
throw new Error("Attempting to setAutoReconnect() a closed Container");
|
|
603
616
|
}
|
|
604
617
|
const mode = reconnect ? ReconnectMode.Enabled : ReconnectMode.Disabled;
|
|
618
|
+
this.setAutoReconnectInternal(mode);
|
|
619
|
+
// If container state is not attached and resumed, then don't connect to delta stream. Also don't set the
|
|
620
|
+
// manual reconnection flag to true as we haven't made the initial connection yet.
|
|
621
|
+
if (reconnect && this._attachState === AttachState.Attached && this.resumedOpProcessingAfterLoad) {
|
|
622
|
+
// Ensure connection to web socket
|
|
623
|
+
this.connectToDeltaStream({ reason: "autoReconnect" });
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
setAutoReconnectInternal(mode) {
|
|
605
627
|
const currentMode = this._deltaManager.connectionManager.reconnectMode;
|
|
606
628
|
if (currentMode === mode) {
|
|
607
629
|
return;
|
|
@@ -610,23 +632,56 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
610
632
|
const duration = now - this.setAutoReconnectTime;
|
|
611
633
|
this.setAutoReconnectTime = now;
|
|
612
634
|
this.mc.logger.sendTelemetryEvent({
|
|
613
|
-
eventName:
|
|
635
|
+
eventName: mode === ReconnectMode.Enabled ? "AutoReconnectEnabled" : "AutoReconnectDisabled",
|
|
614
636
|
connectionMode: this.connectionMode,
|
|
615
637
|
connectionState: ConnectionState[this.connectionState],
|
|
616
638
|
duration,
|
|
617
639
|
});
|
|
618
640
|
this._deltaManager.connectionManager.setAutoReconnect(mode);
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
if (
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
641
|
+
}
|
|
642
|
+
connect() {
|
|
643
|
+
if (this.closed) {
|
|
644
|
+
throw new UsageError(`The Container is closed and cannot be connected`);
|
|
645
|
+
}
|
|
646
|
+
else if (this._attachState !== AttachState.Attached) {
|
|
647
|
+
throw new UsageError(`The Container is not attached and cannot be connected`);
|
|
648
|
+
}
|
|
649
|
+
else if (!this.connected) {
|
|
650
|
+
// Note: no need to fetch ops as we do it preemptively as part of DeltaManager.attachOpHandler().
|
|
651
|
+
// If there is gap, we will learn about it once connected, but the gap should be small (if any),
|
|
652
|
+
// assuming that connect() is called quickly after initial container boot.
|
|
653
|
+
this.connectInternal({ reason: "DocumentConnect", fetchOpsFromStorage: false });
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
connectInternal(args) {
|
|
657
|
+
assert(!this.closed, 0x2c5 /* "Attempting to connect() a closed Container" */);
|
|
658
|
+
assert(this._attachState === AttachState.Attached, 0x2c6 /* "Attempting to connect() a container that is not attached" */);
|
|
659
|
+
// Resume processing ops and connect to delta stream
|
|
660
|
+
this.resumeInternal(args);
|
|
661
|
+
// Set Auto Reconnect Mode
|
|
662
|
+
const mode = ReconnectMode.Enabled;
|
|
663
|
+
this.setAutoReconnectInternal(mode);
|
|
664
|
+
}
|
|
665
|
+
disconnect() {
|
|
666
|
+
if (this.closed) {
|
|
667
|
+
throw new UsageError(`The Container is closed and cannot be disconnected`);
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
this.disconnectInternal();
|
|
628
671
|
}
|
|
629
672
|
}
|
|
673
|
+
disconnectInternal() {
|
|
674
|
+
assert(!this.closed, 0x2c7 /* "Attempting to disconnect() a closed Container" */);
|
|
675
|
+
// Set Auto Reconnect Mode
|
|
676
|
+
const mode = ReconnectMode.Disabled;
|
|
677
|
+
this.setAutoReconnectInternal(mode);
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Have the container attempt to resume processing ops
|
|
681
|
+
* @deprecated - 0.58, This API will be removed in 1.0
|
|
682
|
+
* Use `connect()` instead
|
|
683
|
+
* See https://github.com/microsoft/FluidFramework/issues/9167 for context
|
|
684
|
+
*/
|
|
630
685
|
resume() {
|
|
631
686
|
if (!this.closed) {
|
|
632
687
|
// Note: no need to fetch ops as we do it preemptively as part of DeltaManager.attachOpHandler().
|
|
@@ -646,26 +701,12 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
646
701
|
// Ensure connection to web socket
|
|
647
702
|
this.connectToDeltaStream(args);
|
|
648
703
|
}
|
|
649
|
-
/**
|
|
650
|
-
* @deprecated 0.56, will be removed in next release from IContainerContext
|
|
651
|
-
* Raise non-critical error to host. Calling this API will not close container.
|
|
652
|
-
* For critical errors, please call Container.close(error).
|
|
653
|
-
* @param error - an error to raise
|
|
654
|
-
*/
|
|
655
|
-
raiseContainerWarning(warning) {
|
|
656
|
-
// Some "warning" events come from outside the container and are logged
|
|
657
|
-
// elsewhere (e.g. summarizing container). We shouldn't log these here.
|
|
658
|
-
if (warning.logged !== true) {
|
|
659
|
-
this.logContainerError(warning);
|
|
660
|
-
}
|
|
661
|
-
this.emit("warning", warning);
|
|
662
|
-
}
|
|
663
704
|
async getAbsoluteUrl(relativeUrl) {
|
|
664
705
|
var _a;
|
|
665
706
|
if (this.resolvedUrl === undefined) {
|
|
666
707
|
return undefined;
|
|
667
708
|
}
|
|
668
|
-
return this.urlResolver.getAbsoluteUrl(this.resolvedUrl, relativeUrl, (_a = this._context) === null || _a === void 0 ? void 0 : _a.codeDetails);
|
|
709
|
+
return this.urlResolver.getAbsoluteUrl(this.resolvedUrl, relativeUrl, getPackageName((_a = this._context) === null || _a === void 0 ? void 0 : _a.codeDetails));
|
|
669
710
|
}
|
|
670
711
|
async proposeCodeDetails(codeDetails) {
|
|
671
712
|
if (!isFluidCodeDetails(codeDetails)) {
|
|
@@ -723,7 +764,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
723
764
|
if (this._resolvedUrl === undefined) {
|
|
724
765
|
throw new Error("Attempting to load without a resolved url");
|
|
725
766
|
}
|
|
726
|
-
this.service = await this.serviceFactory.createDocumentService(this._resolvedUrl, this.subLogger);
|
|
767
|
+
this.service = await this.serviceFactory.createDocumentService(this._resolvedUrl, this.subLogger, this.client.details.type === summarizerClientType);
|
|
727
768
|
// Ideally we always connect as "read" by default.
|
|
728
769
|
// Currently that works with SPO & r11s, because we get "write" connection when connecting to non-existing file.
|
|
729
770
|
// We should not rely on it by (one of them will address the issue, but we need to address both)
|
|
@@ -1023,12 +1064,17 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1023
1064
|
this.connectionStateHandler.receivedConnectEvent(this.connectionMode, details);
|
|
1024
1065
|
});
|
|
1025
1066
|
deltaManager.on("disconnect", (reason) => {
|
|
1026
|
-
this.manualReconnectInProgress = false;
|
|
1027
1067
|
this.collabWindowTracker.stopSequenceNumberUpdate();
|
|
1028
1068
|
this.connectionStateHandler.receivedDisconnectEvent(reason);
|
|
1029
1069
|
});
|
|
1030
1070
|
deltaManager.on("throttled", (warning) => {
|
|
1031
|
-
|
|
1071
|
+
const warn = warning;
|
|
1072
|
+
// Some "warning" events come from outside the container and are logged
|
|
1073
|
+
// elsewhere (e.g. summarizing container). We shouldn't log these here.
|
|
1074
|
+
if (warn.logged !== true) {
|
|
1075
|
+
this.logContainerError(warn);
|
|
1076
|
+
}
|
|
1077
|
+
this.emit("warning", warn);
|
|
1032
1078
|
});
|
|
1033
1079
|
deltaManager.on("readonly", (readonly) => {
|
|
1034
1080
|
this.emit("readonly", readonly);
|
|
@@ -1075,9 +1121,6 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1075
1121
|
if (this.firstConnection) {
|
|
1076
1122
|
connectionInitiationReason = "InitialConnect";
|
|
1077
1123
|
}
|
|
1078
|
-
else if (this.manualReconnectInProgress) {
|
|
1079
|
-
connectionInitiationReason = "ManualReconnect";
|
|
1080
|
-
}
|
|
1081
1124
|
else {
|
|
1082
1125
|
connectionInitiationReason = "AutoReconnect";
|
|
1083
1126
|
}
|
|
@@ -1089,7 +1132,6 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1089
1132
|
opsBehind, online: OnlineStatus[isOnline()], lastVisible: this.lastVisible !== undefined ? performance.now() - this.lastVisible : undefined, checkpointSequenceNumber }, this._deltaManager.connectionProps));
|
|
1090
1133
|
if (value === ConnectionState.Connected) {
|
|
1091
1134
|
this.firstConnection = false;
|
|
1092
|
-
this.manualReconnectInProgress = false;
|
|
1093
1135
|
}
|
|
1094
1136
|
}
|
|
1095
1137
|
propagateConnectionState() {
|
|
@@ -1227,7 +1269,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1227
1269
|
// The relative loader will proxy requests to '/' to the loader itself assuming no non-cache flags
|
|
1228
1270
|
// are set. Global requests will still go directly to the loader
|
|
1229
1271
|
const loader = new RelativeLoader(this, this.loader);
|
|
1230
|
-
this._context = await ContainerContext.createOrLoad(this, this.scope, this.codeLoader, codeDetails, snapshot, new DeltaManagerProxy(this._deltaManager), new QuorumProxy(this.protocolHandler.quorum), loader, (
|
|
1272
|
+
this._context = await ContainerContext.createOrLoad(this, this.scope, this.codeLoader, codeDetails, snapshot, new DeltaManagerProxy(this._deltaManager), new QuorumProxy(this.protocolHandler.quorum), loader, (type, contents, batch, metadata) => this.submitContainerMessage(type, contents, batch, metadata), (message) => this.submitSignal(message), (error) => this.close(error), Container.version, (dirty) => this.updateDirtyContainerState(dirty), existing, pendingLocalState);
|
|
1231
1273
|
this.emit("contextChanged", codeDetails);
|
|
1232
1274
|
}
|
|
1233
1275
|
updateDirtyContainerState(dirty) {
|