@fluidframework/container-loader 2.0.0-dev.2.3.0.115467 → 2.0.0-dev.4.1.0.148229
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/.eslintrc.js +18 -21
- package/.mocharc.js +2 -2
- package/README.md +65 -44
- package/api-extractor.json +2 -2
- package/closeAndGetPendingLocalState.md +51 -0
- package/dist/audience.d.ts +0 -1
- package/dist/audience.d.ts.map +1 -1
- package/dist/audience.js.map +1 -1
- package/dist/catchUpMonitor.d.ts.map +1 -1
- package/dist/catchUpMonitor.js.map +1 -1
- package/dist/collabWindowTracker.d.ts.map +1 -1
- package/dist/collabWindowTracker.js.map +1 -1
- package/dist/connectionManager.d.ts +5 -5
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +107 -44
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionState.d.ts.map +1 -1
- package/dist/connectionState.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +7 -7
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +50 -21
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +64 -5
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +329 -137
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +19 -8
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +58 -14
- package/dist/containerContext.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts +41 -2
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +88 -14
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +3 -3
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deltaManager.d.ts +21 -8
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +112 -37
- package/dist/deltaManager.js.map +1 -1
- package/dist/deltaManagerProxy.d.ts +10 -22
- package/dist/deltaManagerProxy.d.ts.map +1 -1
- package/dist/deltaManagerProxy.js +14 -50
- package/dist/deltaManagerProxy.js.map +1 -1
- package/dist/deltaQueue.d.ts.map +1 -1
- package/dist/deltaQueue.js +4 -2
- package/dist/deltaQueue.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +13 -4
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +38 -24
- package/dist/loader.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.map +1 -1
- package/dist/protocol.js +2 -1
- package/dist/protocol.js.map +1 -1
- package/dist/protocolTreeDocumentStorageService.d.ts +6 -2
- package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/dist/protocolTreeDocumentStorageService.js +7 -4
- package/dist/protocolTreeDocumentStorageService.js.map +1 -1
- package/dist/quorum.d.ts.map +1 -1
- package/dist/quorum.js.map +1 -1
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/retriableDocumentStorageService.js +6 -2
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +8 -5
- package/dist/utils.js.map +1 -1
- package/lib/audience.d.ts +0 -1
- package/lib/audience.d.ts.map +1 -1
- package/lib/audience.js.map +1 -1
- package/lib/catchUpMonitor.d.ts.map +1 -1
- package/lib/catchUpMonitor.js.map +1 -1
- package/lib/collabWindowTracker.d.ts.map +1 -1
- package/lib/collabWindowTracker.js.map +1 -1
- package/lib/connectionManager.d.ts +5 -5
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +110 -47
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionState.d.ts.map +1 -1
- package/lib/connectionState.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +7 -7
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +50 -21
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +64 -5
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +336 -144
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +19 -8
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +59 -15
- package/lib/containerContext.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts +41 -2
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +86 -14
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +3 -3
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/deltaManager.d.ts +21 -8
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +114 -39
- package/lib/deltaManager.js.map +1 -1
- package/lib/deltaManagerProxy.d.ts +10 -22
- package/lib/deltaManagerProxy.d.ts.map +1 -1
- package/lib/deltaManagerProxy.js +14 -50
- package/lib/deltaManagerProxy.js.map +1 -1
- package/lib/deltaQueue.d.ts.map +1 -1
- package/lib/deltaQueue.js +4 -2
- package/lib/deltaQueue.js.map +1 -1
- package/lib/index.d.ts +4 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/loader.d.ts +13 -4
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.js +37 -24
- package/lib/loader.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.map +1 -1
- package/lib/protocol.js +2 -1
- package/lib/protocol.js.map +1 -1
- package/lib/protocolTreeDocumentStorageService.d.ts +6 -2
- package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/lib/protocolTreeDocumentStorageService.js +7 -4
- package/lib/protocolTreeDocumentStorageService.js.map +1 -1
- package/lib/quorum.d.ts.map +1 -1
- package/lib/quorum.js.map +1 -1
- package/lib/retriableDocumentStorageService.d.ts.map +1 -1
- package/lib/retriableDocumentStorageService.js +6 -2
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +8 -5
- package/lib/utils.js.map +1 -1
- package/package.json +67 -56
- package/prettier.config.cjs +1 -1
- package/src/audience.ts +51 -46
- package/src/catchUpMonitor.ts +39 -37
- package/src/collabWindowTracker.ts +75 -70
- package/src/connectionManager.ts +1040 -941
- package/src/connectionState.ts +19 -19
- package/src/connectionStateHandler.ts +557 -463
- package/src/container.ts +2147 -1784
- package/src/containerContext.ts +417 -345
- package/src/containerStorageAdapter.ts +268 -154
- package/src/contracts.ts +155 -153
- package/src/deltaManager.ts +1074 -945
- package/src/deltaManagerProxy.ts +88 -137
- package/src/deltaQueue.ts +155 -151
- package/src/index.ts +13 -17
- package/src/loader.ts +434 -427
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +93 -87
- package/src/protocolTreeDocumentStorageService.ts +34 -34
- package/src/quorum.ts +34 -34
- package/src/retriableDocumentStorageService.ts +118 -102
- package/src/utils.ts +93 -83
- package/tsconfig.esnext.json +6 -6
- package/tsconfig.json +8 -12
package/dist/contracts.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { ITelemetryProperties } from "@fluidframework/common-definitions";
|
|
6
|
-
import { IDeltaQueue, ReadOnlyInfo,
|
|
6
|
+
import { IDeltaQueue, ReadOnlyInfo, IConnectionDetailsInternal, ICriticalContainerError, IFluidCodeDetails } from "@fluidframework/container-definitions";
|
|
7
7
|
import { ConnectionMode, IDocumentMessage, ISequencedDocumentMessage, IClientConfiguration, IClientDetails, ISignalMessage } from "@fluidframework/protocol-definitions";
|
|
8
8
|
import { IContainerPackageInfo } from "@fluidframework/driver-definitions";
|
|
9
9
|
export declare enum ReconnectMode {
|
|
@@ -60,7 +60,7 @@ export interface IConnectionManager {
|
|
|
60
60
|
/**
|
|
61
61
|
* Disposed connection manager
|
|
62
62
|
*/
|
|
63
|
-
dispose(error?: ICriticalContainerError): void;
|
|
63
|
+
dispose(error?: ICriticalContainerError, switchToReadonly?: boolean): void;
|
|
64
64
|
get connectionMode(): ConnectionMode;
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
@@ -97,7 +97,7 @@ export interface IConnectionManagerFactoryArgs {
|
|
|
97
97
|
/**
|
|
98
98
|
* Called whenever new connection to rely service is established
|
|
99
99
|
*/
|
|
100
|
-
readonly connectHandler: (connection:
|
|
100
|
+
readonly connectHandler: (connection: IConnectionDetailsInternal) => void;
|
|
101
101
|
/**
|
|
102
102
|
* Called whenever ping/pong messages are roundtripped on connection.
|
|
103
103
|
*
|
package/dist/contracts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"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"}
|
package/dist/contracts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,iFAO+C;AAW/C,IAAY,aAIX;AAJD,WAAY,aAAa;IACxB,gCAAe,CAAA;IACf,sCAAqB,CAAA;IACrB,oCAAmB,CAAA;AACpB,CAAC,EAJW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAIxB;AA+ID;;;;GAIG;AACI,MAAM,cAAc,GAAG,CAC7B,WAA0C,EAClB,EAAE;IAC1B,IAAI,oBAAoB,CAAC;IACzB,IAAI,WAAW,IAAI,MAAM,IAAI,WAAW,EAAE;QACzC,oBAAoB,GAAG,WAAW,CAAC;KACnC;SAAM,IAAI,IAAA,sCAAc,EAAC,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAC,EAAE;QAChD,oBAAoB,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAC,IAAI,CAAC;KACjD;SAAM;QACN,oBAAoB,GAAG,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAC;KAC5C;IACD,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC;AACvC,CAAC,CAAC;AAZW,QAAA,cAAc,kBAYzB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryProperties } from \"@fluidframework/common-definitions\";\nimport {\n\tIDeltaQueue,\n\tReadOnlyInfo,\n\tIConnectionDetailsInternal,\n\tICriticalContainerError,\n\tIFluidCodeDetails,\n\tisFluidPackage,\n} from \"@fluidframework/container-definitions\";\nimport {\n\tConnectionMode,\n\tIDocumentMessage,\n\tISequencedDocumentMessage,\n\tIClientConfiguration,\n\tIClientDetails,\n\tISignalMessage,\n} from \"@fluidframework/protocol-definitions\";\nimport { IContainerPackageInfo } from \"@fluidframework/driver-definitions\";\n\nexport enum ReconnectMode {\n\tNever = \"Never\",\n\tDisabled = \"Disabled\",\n\tEnabled = \"Enabled\",\n}\n\n/**\n * Connection manager (implements this interface) is responsible for maintaining connection\n * to relay service.\n */\nexport interface IConnectionManager {\n\treadonly connected: boolean;\n\n\treadonly clientId: string | undefined;\n\n\t/** The queue of outbound delta messages */\n\treadonly outbound: IDeltaQueue<IDocumentMessage[]>;\n\n\t/** Details of client */\n\treadonly clientDetails: IClientDetails;\n\n\t/** Protocol version being used to communicate with the service */\n\treadonly version: string;\n\n\t/** Max message size allowed to the delta manager */\n\treadonly maxMessageSize: number;\n\n\t/** Service configuration provided by the service. */\n\treadonly serviceConfiguration: IClientConfiguration | undefined;\n\n\treadonly readOnlyInfo: ReadOnlyInfo;\n\n\t// Various connectivity properties for telemetry describing type of current connection\n\t// Things like connection mode, service info, etc.\n\t// Called when connection state changes (connect / disconnect)\n\treadonly connectionProps: ITelemetryProperties;\n\n\t// Verbose information about connection logged to telemetry in case of issues with\n\t// maintaining healthy connection, including op gaps, not receiving join op in time, etc.\n\t// Contains details information, like sequence numbers at connection time, initial ops info, etc.\n\treadonly connectionVerboseProps: ITelemetryProperties;\n\n\t/**\n\t * Prepares message to be sent. Fills in clientSequenceNumber.\n\t * Called only when active connection is present.\n\t */\n\tprepareMessageToSend(\n\t\tmessage: Omit<IDocumentMessage, \"clientSequenceNumber\">,\n\t): IDocumentMessage | undefined;\n\n\t/**\n\t * Called before incoming message is processed. Incoming messages can be combing from connection,\n\t * but also could come from storage.\n\t * This call allows connection manager to adjust knowledge about acked ops sent on previous connection.\n\t * Can be called at any time, including when there is no active connection.\n\t */\n\tbeforeProcessingIncomingOp(message: ISequencedDocumentMessage): void;\n\n\t/**\n\t * Submits signal to relay service.\n\t * Called only when active connection is present.\n\t */\n\tsubmitSignal(content: any): void;\n\n\t/**\n\t * Submits messages to relay service.\n\t * Called only when active connection is present.\n\t */\n\tsendMessages(messages: IDocumentMessage[]): void;\n\n\t/**\n\t * Initiates connection to relay service (noop if already connected).\n\t */\n\tconnect(connectionMode?: ConnectionMode): void;\n\n\t/**\n\t * Disposed connection manager\n\t */\n\tdispose(error?: ICriticalContainerError, switchToReadonly?: boolean): void;\n\n\tget connectionMode(): ConnectionMode;\n}\n\n/**\n * This interface represents a set of callbacks provided by DeltaManager to IConnectionManager on its creation\n * IConnectionManager instance will use them to communicate to DeltaManager about various events.\n */\nexport interface IConnectionManagerFactoryArgs {\n\t/**\n\t * Called by connection manager for each incoming op. Some ops maybe delivered before\n\t * connectHandler is called (initial ops on socket connection)\n\t */\n\treadonly incomingOpHandler: (messages: ISequencedDocumentMessage[], reason: string) => void;\n\n\t/**\n\t * Called by connection manager for each incoming signals.\n\t * Maybe called before connectHandler is called (initial signals on socket connection)\n\t */\n\treadonly signalHandler: (message: ISignalMessage) => void;\n\n\t/**\n\t * Called when connection manager experiences delay in connecting to relay service.\n\t * This can happen because client is offline, or service is busy and asks to not connect for some time.\n\t * Can be called many times while not connected.\n\t * Situation is considered resolved when connection is established and connectHandler is called.\n\t */\n\treadonly reconnectionDelayHandler: (delayMs: number, error: unknown) => void;\n\n\t/**\n\t * Called by connection manager whenever critical error happens and container should be closed.\n\t * Expects dispose() call in response to this call.\n\t */\n\treadonly closeHandler: (error?: any) => void;\n\n\t/**\n\t * Called whenever connection to relay service is lost.\n\t */\n\treadonly disconnectHandler: (reason: string) => void;\n\n\t/**\n\t * Called whenever new connection to rely service is established\n\t */\n\treadonly connectHandler: (connection: IConnectionDetailsInternal) => void;\n\n\t/**\n\t * Called whenever ping/pong messages are roundtripped on connection.\n\t *\n\t * @deprecated No replacement API intended.\n\t */\n\treadonly pongHandler: (latency: number) => void;\n\n\t/**\n\t * Called whenever connection type changes from writable to read-only or vice versa.\n\t *\n\t * @remarks\n\t *\n\t * Connection can be read-only if user has no edit permissions, or if container forced\n\t * connection to be read-only.\n\t * This should not be confused with \"read\" / \"write\"connection mode which is internal\n\t * optimization.\n\t *\n\t * @param readonly - Whether or not the container is now read-only.\n\t * `undefined` indicates that user permissions are not yet known.\n\t */\n\treadonly readonlyChangeHandler: (readonly?: boolean) => void;\n}\n\n/**\n *\n * @param codeDetails- - Data structure used to describe the code to load on the Fluid document\n * @returns The name of the Fluid package\n */\nexport const getPackageName = (\n\tcodeDetails: IFluidCodeDetails | undefined,\n): IContainerPackageInfo => {\n\tlet containerPackageName;\n\tif (codeDetails && \"name\" in codeDetails) {\n\t\tcontainerPackageName = codeDetails;\n\t} else if (isFluidPackage(codeDetails?.package)) {\n\t\tcontainerPackageName = codeDetails?.package.name;\n\t} else {\n\t\tcontainerPackageName = codeDetails?.package;\n\t}\n\treturn { name: containerPackageName };\n};\n"]}
|
package/dist/deltaManager.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { default as AbortController } from "abort-controller";
|
|
6
6
|
import { ITelemetryLogger, IEventProvider, ITelemetryProperties, ITelemetryErrorEvent } from "@fluidframework/common-definitions";
|
|
7
|
-
import { IDeltaHandlerStrategy, IDeltaManager, IDeltaManagerEvents, IDeltaQueue, ICriticalContainerError, IThrottlingWarning } from "@fluidframework/container-definitions";
|
|
7
|
+
import { IDeltaHandlerStrategy, IDeltaManager, IDeltaManagerEvents, IDeltaQueue, ICriticalContainerError, IThrottlingWarning, IConnectionDetailsInternal } from "@fluidframework/container-definitions";
|
|
8
8
|
import { TypedEventEmitter } from "@fluidframework/common-utils";
|
|
9
9
|
import { IDocumentService } from "@fluidframework/driver-definitions";
|
|
10
10
|
import { IDocumentMessage, ISequencedDocumentMessage, ISignalMessage, MessageType, ConnectionMode } from "@fluidframework/protocol-definitions";
|
|
@@ -20,7 +20,8 @@ export interface IConnectionArgs {
|
|
|
20
20
|
*/
|
|
21
21
|
export interface IDeltaManagerInternalEvents extends IDeltaManagerEvents {
|
|
22
22
|
(event: "throttled", listener: (error: IThrottlingWarning) => void): any;
|
|
23
|
-
(event: "closed", listener: (error?: ICriticalContainerError) => void): any;
|
|
23
|
+
(event: "closed" | "disposed", listener: (error?: ICriticalContainerError) => void): any;
|
|
24
|
+
(event: "connect", listener: (details: IConnectionDetailsInternal, opsBehind?: number) => void): any;
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
27
|
* Manages the flow of both inbound and outbound messages. This class ensures that shared objects receive delta
|
|
@@ -43,16 +44,21 @@ export declare class DeltaManager<TConnectionManager extends IConnectionManager>
|
|
|
43
44
|
private lastProcessedSequenceNumber;
|
|
44
45
|
private lastProcessedMessage;
|
|
45
46
|
private baseTerm;
|
|
47
|
+
/** count number of noops sent by the client which may not be acked */
|
|
48
|
+
private noOpCount;
|
|
49
|
+
/** Track clientSequenceNumber of the last op */
|
|
50
|
+
private lastClientSequenceNumber;
|
|
46
51
|
/**
|
|
47
52
|
* Track down the ops size.
|
|
48
|
-
|
|
53
|
+
*/
|
|
49
54
|
private opsSize;
|
|
50
55
|
private prevEnqueueMessagesReason;
|
|
51
56
|
private previouslyProcessedMessage;
|
|
52
57
|
private initSequenceNumber;
|
|
53
58
|
private readonly _inbound;
|
|
54
59
|
private readonly _inboundSignal;
|
|
55
|
-
private
|
|
60
|
+
private _closed;
|
|
61
|
+
private _disposed;
|
|
56
62
|
private handler;
|
|
57
63
|
private deltaStorage;
|
|
58
64
|
private readonly throttlingIdSet;
|
|
@@ -81,7 +87,7 @@ export declare class DeltaManager<TConnectionManager extends IConnectionManager>
|
|
|
81
87
|
get outbound(): IDeltaQueue<IDocumentMessage[]>;
|
|
82
88
|
get readOnlyInfo(): import("@fluidframework/container-definitions").ReadOnlyInfo;
|
|
83
89
|
get clientDetails(): import("@fluidframework/protocol-definitions").IClientDetails;
|
|
84
|
-
submit(type: MessageType, contents?: string, batch?: boolean, metadata?: any, compression?: string): number;
|
|
90
|
+
submit(type: MessageType, contents?: string, batch?: boolean, metadata?: any, compression?: string, referenceSequenceNumber?: number): number;
|
|
85
91
|
submitSignal(content: any): void;
|
|
86
92
|
flush(): void;
|
|
87
93
|
get connectionProps(): ITelemetryProperties;
|
|
@@ -103,8 +109,15 @@ export declare class DeltaManager<TConnectionManager extends IConnectionManager>
|
|
|
103
109
|
private getDeltas;
|
|
104
110
|
/**
|
|
105
111
|
* Closes the connection and clears inbound & outbound queues.
|
|
112
|
+
*
|
|
113
|
+
* @param doDispose - should the DeltaManager treat this close call as a dispose?
|
|
114
|
+
* Differences between close and dispose:
|
|
115
|
+
* - dispose will emit "disposed" event while close emits "closed"
|
|
116
|
+
* - dispose will remove all listeners
|
|
117
|
+
* - dispose can be called after closure, but not vis versa
|
|
106
118
|
*/
|
|
107
|
-
close(error?: ICriticalContainerError): void;
|
|
119
|
+
close(error?: ICriticalContainerError, doDispose?: boolean): void;
|
|
120
|
+
private disposeInternal;
|
|
108
121
|
refreshDelayInfo(id: string): void;
|
|
109
122
|
private disconnectHandler;
|
|
110
123
|
/**
|
|
@@ -122,8 +135,8 @@ export declare class DeltaManager<TConnectionManager extends IConnectionManager>
|
|
|
122
135
|
*/
|
|
123
136
|
private fetchMissingDeltas;
|
|
124
137
|
/**
|
|
125
|
-
|
|
126
|
-
|
|
138
|
+
* Retrieves the missing deltas between the given sequence numbers
|
|
139
|
+
*/
|
|
127
140
|
private fetchMissingDeltasCore;
|
|
128
141
|
/**
|
|
129
142
|
* Sorts pending ops and attempts to apply them
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deltaManager.d.ts","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,
|
|
1
|
+
{"version":3,"file":"deltaManager.d.ts","sourceRoot":"","sources":["../src/deltaManager.ts"],"names":[],"mappings":"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"}
|
package/dist/deltaManager.js
CHANGED
|
@@ -61,15 +61,20 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
61
61
|
this.lastObservedSeqNumber = 0;
|
|
62
62
|
this.lastProcessedSequenceNumber = 0;
|
|
63
63
|
this.baseTerm = 0;
|
|
64
|
+
/** count number of noops sent by the client which may not be acked */
|
|
65
|
+
this.noOpCount = 0;
|
|
66
|
+
/** Track clientSequenceNumber of the last op */
|
|
67
|
+
this.lastClientSequenceNumber = 0;
|
|
64
68
|
/**
|
|
65
69
|
* Track down the ops size.
|
|
66
|
-
|
|
70
|
+
*/
|
|
67
71
|
this.opsSize = 0;
|
|
68
72
|
// The sequence number we initially loaded from
|
|
69
73
|
// In case of reading from a snapshot or pending state, its value will be equal to
|
|
70
74
|
// the last message that got serialized.
|
|
71
75
|
this.initSequenceNumber = 0;
|
|
72
|
-
this.
|
|
76
|
+
this._closed = false;
|
|
77
|
+
this._disposed = false;
|
|
73
78
|
this.throttlingIdSet = new Set();
|
|
74
79
|
this.timeTillThrottling = 0;
|
|
75
80
|
this.closeAbortController = new abort_controller_1.default();
|
|
@@ -118,9 +123,15 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
118
123
|
// - outbound is flipped back and forth in setupNewSuccessfulConnection / disconnectFromDeltaStream
|
|
119
124
|
// - inbound & inboundSignal are resumed in attachOpHandler() when we have handler setup
|
|
120
125
|
}
|
|
121
|
-
get active() {
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
get active() {
|
|
127
|
+
return this._active();
|
|
128
|
+
}
|
|
129
|
+
get disposed() {
|
|
130
|
+
return this._closed;
|
|
131
|
+
}
|
|
132
|
+
get IDeltaSender() {
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
124
135
|
get inbound() {
|
|
125
136
|
return this._inbound;
|
|
126
137
|
}
|
|
@@ -155,17 +166,31 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
155
166
|
return this._checkpointSequenceNumber !== undefined;
|
|
156
167
|
}
|
|
157
168
|
// Forwarding connection manager properties / IDeltaManager implementation
|
|
158
|
-
get maxMessageSize() {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
get
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
169
|
+
get maxMessageSize() {
|
|
170
|
+
return this.connectionManager.maxMessageSize;
|
|
171
|
+
}
|
|
172
|
+
get version() {
|
|
173
|
+
return this.connectionManager.version;
|
|
174
|
+
}
|
|
175
|
+
get serviceConfiguration() {
|
|
176
|
+
return this.connectionManager.serviceConfiguration;
|
|
177
|
+
}
|
|
178
|
+
get outbound() {
|
|
179
|
+
return this.connectionManager.outbound;
|
|
180
|
+
}
|
|
181
|
+
get readOnlyInfo() {
|
|
182
|
+
return this.connectionManager.readOnlyInfo;
|
|
183
|
+
}
|
|
184
|
+
get clientDetails() {
|
|
185
|
+
return this.connectionManager.clientDetails;
|
|
186
|
+
}
|
|
187
|
+
submit(type, contents, batch = false, metadata, compression, referenceSequenceNumber) {
|
|
188
|
+
// Back-compat ADO:3455
|
|
189
|
+
const backCompatRefSeqNum = referenceSequenceNumber !== null && referenceSequenceNumber !== void 0 ? referenceSequenceNumber : this.lastProcessedSequenceNumber;
|
|
165
190
|
const messagePartial = {
|
|
166
191
|
contents,
|
|
167
192
|
metadata,
|
|
168
|
-
referenceSequenceNumber:
|
|
193
|
+
referenceSequenceNumber: backCompatRefSeqNum,
|
|
169
194
|
type,
|
|
170
195
|
compression,
|
|
171
196
|
};
|
|
@@ -181,13 +206,18 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
181
206
|
this.opsSize += contents.length;
|
|
182
207
|
}
|
|
183
208
|
this.messageBuffer.push(message);
|
|
209
|
+
if (message.type === protocol_definitions_1.MessageType.NoOp) {
|
|
210
|
+
this.noOpCount++;
|
|
211
|
+
}
|
|
184
212
|
this.emit("submitOp", message);
|
|
185
213
|
if (!batch) {
|
|
186
214
|
this.flush();
|
|
187
215
|
}
|
|
188
216
|
return message.clientSequenceNumber;
|
|
189
217
|
}
|
|
190
|
-
submitSignal(content) {
|
|
218
|
+
submitSignal(content) {
|
|
219
|
+
return this.connectionManager.submitSignal(content);
|
|
220
|
+
}
|
|
191
221
|
flush() {
|
|
192
222
|
var _a, _b, _c;
|
|
193
223
|
const batch = this.messageBuffer;
|
|
@@ -244,8 +274,10 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
244
274
|
// state. As requirements change, so should these checks.
|
|
245
275
|
(0, common_utils_1.assert)(this.messageBuffer.length === 0, 0x0e9 /* "messageBuffer is not empty on new connection" */);
|
|
246
276
|
this.opsSize = 0;
|
|
247
|
-
this.
|
|
248
|
-
|
|
277
|
+
this.noOpCount = 0;
|
|
278
|
+
this.emit("connect", connection, checkpointSequenceNumber !== undefined
|
|
279
|
+
? this.lastObservedSeqNumber - this.lastSequenceNumber
|
|
280
|
+
: undefined);
|
|
249
281
|
// If we got some initial ops, then we know the gap and call above fetched ops to fill it.
|
|
250
282
|
// Same is true for "write" mode even if we have no ops - we will get "join" own op very very soon.
|
|
251
283
|
// However if we are connecting as view-only, then there is no good signal to realize if client is behind.
|
|
@@ -285,7 +317,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
285
317
|
// setupNewSuccessfulConnection. But it should do nothing, because there is no way to fetch ops before
|
|
286
318
|
// we know snapshot sequence number that is set in attachOpHandler. So all such calls should be noop.
|
|
287
319
|
(0, common_utils_1.assert)(this.fetchReason === undefined, 0x268 /* "There can't be pending fetch that early in boot sequence!" */);
|
|
288
|
-
if (this.
|
|
320
|
+
if (this._closed) {
|
|
289
321
|
return;
|
|
290
322
|
}
|
|
291
323
|
this._inbound.resume();
|
|
@@ -400,13 +432,22 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
400
432
|
}
|
|
401
433
|
/**
|
|
402
434
|
* Closes the connection and clears inbound & outbound queues.
|
|
435
|
+
*
|
|
436
|
+
* @param doDispose - should the DeltaManager treat this close call as a dispose?
|
|
437
|
+
* Differences between close and dispose:
|
|
438
|
+
* - dispose will emit "disposed" event while close emits "closed"
|
|
439
|
+
* - dispose will remove all listeners
|
|
440
|
+
* - dispose can be called after closure, but not vis versa
|
|
403
441
|
*/
|
|
404
|
-
close(error) {
|
|
405
|
-
if (this.
|
|
442
|
+
close(error, doDispose) {
|
|
443
|
+
if (this._closed) {
|
|
444
|
+
if (doDispose === true) {
|
|
445
|
+
this.disposeInternal(error);
|
|
446
|
+
}
|
|
406
447
|
return;
|
|
407
448
|
}
|
|
408
|
-
this.
|
|
409
|
-
this.connectionManager.dispose(error);
|
|
449
|
+
this._closed = true;
|
|
450
|
+
this.connectionManager.dispose(error, doDispose !== true);
|
|
410
451
|
this.closeAbortController.abort();
|
|
411
452
|
this._inbound.clear();
|
|
412
453
|
this._inboundSignal.clear();
|
|
@@ -416,10 +457,23 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
416
457
|
this._inboundSignal.pause();
|
|
417
458
|
// Drop pending messages - this will ensure catchUp() does not go into infinite loop
|
|
418
459
|
this.pending = [];
|
|
460
|
+
if (doDispose === true) {
|
|
461
|
+
this.disposeInternal(error);
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
this.emit("closed", error);
|
|
465
|
+
this.disposeInternal(error); // ! TODO: remove this call when Container close no longer disposes
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
disposeInternal(error) {
|
|
469
|
+
if (this._disposed) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
this._disposed = true;
|
|
419
473
|
// This needs to be the last thing we do (before removing listeners), as it causes
|
|
420
474
|
// Container to dispose context and break ability of data stores / runtime to "hear"
|
|
421
475
|
// from delta manager, including notification (above) about readonly state.
|
|
422
|
-
this.emit("
|
|
476
|
+
this.emit("disposed", error);
|
|
423
477
|
this.removeAllListeners();
|
|
424
478
|
}
|
|
425
479
|
refreshDelayInfo(id) {
|
|
@@ -441,7 +495,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
441
495
|
emitDelayInfo(id, delayMs, error) {
|
|
442
496
|
const timeNow = Date.now();
|
|
443
497
|
this.throttlingIdSet.add(id);
|
|
444
|
-
if (delayMs > 0 &&
|
|
498
|
+
if (delayMs > 0 && timeNow + delayMs > this.timeTillThrottling) {
|
|
445
499
|
this.timeTillThrottling = timeNow + delayMs;
|
|
446
500
|
const throttlingWarning = container_utils_1.ThrottlingWarning.wrap(error, delayMs / 1000 /* retryAfterSeconds */, this.logger);
|
|
447
501
|
this.emit("throttled", throttlingWarning);
|
|
@@ -505,12 +559,16 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
505
559
|
}
|
|
506
560
|
let eventName;
|
|
507
561
|
// Report if we found some issues
|
|
508
|
-
if (duplicate !== 0 ||
|
|
562
|
+
if (duplicate !== 0 ||
|
|
563
|
+
(gap !== 0 && !allowGaps) ||
|
|
564
|
+
(initialGap > 0 && this.fetchReason === undefined)) {
|
|
509
565
|
eventName = "enqueueMessages";
|
|
510
566
|
// Also report if we are fetching ops, and same range comes in, thus making this fetch obsolete.
|
|
511
567
|
}
|
|
512
|
-
else if (this.fetchReason !== undefined &&
|
|
513
|
-
|
|
568
|
+
else if (this.fetchReason !== undefined &&
|
|
569
|
+
this.fetchReason !== reason &&
|
|
570
|
+
from <= this.lastQueuedSequenceNumber + 1 &&
|
|
571
|
+
last > this.lastQueuedSequenceNumber) {
|
|
514
572
|
eventName = "enqueueMessagesExtraFetch";
|
|
515
573
|
}
|
|
516
574
|
// Report if there is something to report
|
|
@@ -541,8 +599,8 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
541
599
|
// hit. One example is that some clients could be submitting ops to two different service
|
|
542
600
|
// instances such that the same sequence number is reused for two different ops.
|
|
543
601
|
// pre-0.58 error message: twoMessagesWithSameSeqNumAndDifferentPayload
|
|
544
|
-
"Found two messages with the same sequenceNumber but different payloads. Likely to be a "
|
|
545
|
-
|
|
602
|
+
"Found two messages with the same sequenceNumber but different payloads. Likely to be a " +
|
|
603
|
+
"service issue", driver_definitions_1.DriverErrorType.fileOverwrittenInStorage, {
|
|
546
604
|
clientId: this.connectionManager.clientId,
|
|
547
605
|
sequenceNumber: message.sequenceNumber,
|
|
548
606
|
message1,
|
|
@@ -583,11 +641,25 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
583
641
|
throw new container_utils_1.DataCorruptionError("Mismatch in clientId", Object.assign(Object.assign({}, (0, container_utils_1.extractSafePropertiesFromMessage)(message)), { messageType: message.type }));
|
|
584
642
|
}
|
|
585
643
|
// TODO Remove after SPO picks up the latest build.
|
|
586
|
-
if (typeof message.contents === "string"
|
|
587
|
-
|
|
588
|
-
|
|
644
|
+
if (typeof message.contents === "string" &&
|
|
645
|
+
message.contents !== "" &&
|
|
646
|
+
message.type !== protocol_definitions_1.MessageType.ClientLeave) {
|
|
589
647
|
message.contents = JSON.parse(message.contents);
|
|
590
648
|
}
|
|
649
|
+
// Validate client sequence number has no gap. Decrement the noOpCount by gap
|
|
650
|
+
// If the count ends up negative, that means we have a real gap and throw error
|
|
651
|
+
if (this.connectionManager.clientId !== undefined &&
|
|
652
|
+
this.connectionManager.clientId === message.clientId) {
|
|
653
|
+
if (message.type === protocol_definitions_1.MessageType.NoOp) {
|
|
654
|
+
this.noOpCount--;
|
|
655
|
+
}
|
|
656
|
+
const clientSeqNumGap = message.clientSequenceNumber - this.lastClientSequenceNumber - 1;
|
|
657
|
+
this.noOpCount -= clientSeqNumGap;
|
|
658
|
+
if (this.noOpCount < 0) {
|
|
659
|
+
throw new Error(`gap in client sequence number: ${clientSeqNumGap}`);
|
|
660
|
+
}
|
|
661
|
+
this.lastClientSequenceNumber = message.clientSequenceNumber;
|
|
662
|
+
}
|
|
591
663
|
this.connectionManager.beforeProcessingIncomingOp(message);
|
|
592
664
|
// Watch the minimum sequence number and be ready to update as needed
|
|
593
665
|
if (this.minSequenceNumber > message.minimumSequenceNumber) {
|
|
@@ -598,7 +670,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
598
670
|
// reference sequence number as this op.
|
|
599
671
|
// System ops (when no clients are connected) are the only ops where equation is possible.
|
|
600
672
|
const diff = message.sequenceNumber - message.minimumSequenceNumber;
|
|
601
|
-
if (diff < 0 || diff === 0 && message.clientId !== null) {
|
|
673
|
+
if (diff < 0 || (diff === 0 && message.clientId !== null)) {
|
|
602
674
|
throw new container_utils_1.DataCorruptionError("MSN has to be lower than sequence #", (0, container_utils_1.extractSafePropertiesFromMessage)(message));
|
|
603
675
|
}
|
|
604
676
|
this.minSequenceNumber = message.minimumSequenceNumber;
|
|
@@ -633,16 +705,19 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
633
705
|
});
|
|
634
706
|
}
|
|
635
707
|
/**
|
|
636
|
-
|
|
637
|
-
|
|
708
|
+
* Retrieves the missing deltas between the given sequence numbers
|
|
709
|
+
*/
|
|
638
710
|
async fetchMissingDeltasCore(reason, cacheOnly, to) {
|
|
639
711
|
var _a;
|
|
640
712
|
// Exit out early if we're already fetching deltas
|
|
641
713
|
if (this.fetchReason !== undefined) {
|
|
642
714
|
return;
|
|
643
715
|
}
|
|
644
|
-
if (this.
|
|
645
|
-
this.logger.sendTelemetryEvent({
|
|
716
|
+
if (this._closed) {
|
|
717
|
+
this.logger.sendTelemetryEvent({
|
|
718
|
+
eventName: "fetchMissingDeltasClosedConnection",
|
|
719
|
+
reason,
|
|
720
|
+
});
|
|
646
721
|
return;
|
|
647
722
|
}
|
|
648
723
|
if (this.handler === undefined) {
|
|
@@ -684,7 +759,7 @@ class DeltaManager extends common_utils_1.TypedEventEmitter {
|
|
|
684
759
|
* Sorts pending ops and attempts to apply them
|
|
685
760
|
*/
|
|
686
761
|
processPendingOps(reason) {
|
|
687
|
-
if (this.
|
|
762
|
+
if (this._closed) {
|
|
688
763
|
return;
|
|
689
764
|
}
|
|
690
765
|
(0, common_utils_1.assert)(this.handler !== undefined, 0x26c /* "handler should be installed" */);
|