@fluidframework/container-loader 2.0.0-dev-rc.2.0.0.246488 → 2.0.0-dev-rc.3.0.0.253463
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 +11 -11
- package/dist/attachment.d.ts +6 -9
- package/dist/attachment.d.ts.map +1 -1
- package/dist/attachment.js +3 -3
- 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 +2 -2
- package/dist/audience.js.map +1 -1
- package/dist/catchUpMonitor.d.ts +1 -1
- package/dist/catchUpMonitor.d.ts.map +1 -1
- package/dist/catchUpMonitor.js +2 -2
- package/dist/catchUpMonitor.js.map +1 -1
- package/dist/connectionManager.d.ts +4 -4
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js +42 -42
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +3 -3
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js +27 -27
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container-loader-alpha.d.ts +11 -11
- package/dist/container-loader-beta.d.ts +11 -11
- package/dist/container-loader-public.d.ts +11 -11
- package/dist/container-loader-untrimmed.d.ts +11 -11
- package/dist/container.d.ts +9 -46
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +96 -108
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +19 -7
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +7 -2
- package/dist/containerContext.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts +3 -3
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +6 -6
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +4 -3
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js +2 -2
- package/dist/contracts.js.map +1 -1
- package/dist/debugLogger.d.ts +2 -1
- package/dist/debugLogger.d.ts.map +1 -1
- package/dist/debugLogger.js +4 -4
- package/dist/debugLogger.js.map +1 -1
- package/dist/deltaManager.d.ts +7 -6
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js +45 -45
- package/dist/deltaManager.js.map +1 -1
- package/dist/deltaQueue.d.ts +1 -1
- package/dist/deltaQueue.d.ts.map +1 -1
- package/dist/deltaQueue.js +5 -5
- package/dist/deltaQueue.js.map +1 -1
- package/dist/error.d.ts +3 -2
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +5 -5
- package/dist/error.js.map +1 -1
- package/dist/loader.d.ts +4 -4
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +23 -23
- package/dist/loader.js.map +1 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -2
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +2 -2
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
- package/dist/noopHeuristic.d.ts +1 -1
- package/dist/noopHeuristic.d.ts.map +1 -1
- package/dist/noopHeuristic.js +6 -6
- 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 +1 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +2 -2
- package/dist/protocol.js.map +1 -1
- package/dist/protocolTreeDocumentStorageService.d.ts +4 -4
- 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 +7 -7
- package/dist/retriableDocumentStorageService.js.map +1 -1
- package/dist/serializedStateManager.d.ts +87 -16
- package/dist/serializedStateManager.d.ts.map +1 -1
- package/dist/serializedStateManager.js +164 -80
- package/dist/serializedStateManager.js.map +1 -1
- package/dist/utils.d.ts +6 -7
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +39 -23
- package/dist/utils.js.map +1 -1
- package/lib/attachment.d.ts +6 -9
- package/lib/attachment.d.ts.map +1 -1
- package/lib/attachment.js +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 +1 -1
- package/lib/audience.js.map +1 -1
- package/lib/catchUpMonitor.d.ts +1 -1
- package/lib/catchUpMonitor.d.ts.map +1 -1
- package/lib/catchUpMonitor.js +1 -1
- package/lib/catchUpMonitor.js.map +1 -1
- package/lib/connectionManager.d.ts +4 -4
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js +5 -5
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +3 -3
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js +2 -2
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container-loader-alpha.d.ts +11 -11
- package/lib/container-loader-beta.d.ts +11 -11
- package/lib/container-loader-public.d.ts +11 -11
- package/lib/container-loader-untrimmed.d.ts +11 -11
- package/lib/container.d.ts +9 -46
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +28 -40
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +19 -7
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +7 -2
- package/lib/containerContext.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts +3 -3
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +2 -2
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +4 -3
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/debugLogger.d.ts +2 -1
- package/lib/debugLogger.d.ts.map +1 -1
- package/lib/debugLogger.js +1 -1
- package/lib/debugLogger.js.map +1 -1
- package/lib/deltaManager.d.ts +7 -6
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js +5 -5
- package/lib/deltaManager.js.map +1 -1
- package/lib/deltaQueue.d.ts +1 -1
- package/lib/deltaQueue.d.ts.map +1 -1
- package/lib/deltaQueue.js +2 -2
- package/lib/deltaQueue.js.map +1 -1
- package/lib/error.d.ts +3 -2
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +2 -2
- package/lib/error.js.map +1 -1
- package/lib/loader.d.ts +4 -4
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.js +4 -4
- package/lib/loader.js.map +1 -1
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -2
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +2 -2
- package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
- package/lib/noopHeuristic.d.ts +1 -1
- package/lib/noopHeuristic.d.ts.map +1 -1
- package/lib/noopHeuristic.js +2 -2
- 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 +1 -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 +4 -4
- 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 +3 -3
- package/lib/retriableDocumentStorageService.js.map +1 -1
- package/lib/serializedStateManager.d.ts +87 -16
- package/lib/serializedStateManager.d.ts.map +1 -1
- package/lib/serializedStateManager.js +156 -75
- package/lib/serializedStateManager.js.map +1 -1
- package/lib/tsdoc-metadata.json +11 -0
- package/lib/utils.d.ts +6 -7
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +27 -12
- package/lib/utils.js.map +1 -1
- package/package.json +19 -28
- package/src/attachment.ts +9 -8
- package/src/audience.ts +2 -2
- package/src/catchUpMonitor.ts +2 -2
- package/src/connectionManager.ts +19 -19
- package/src/connectionStateHandler.ts +7 -7
- package/src/container.ts +78 -133
- package/src/containerContext.ts +22 -12
- package/src/containerStorageAdapter.ts +7 -6
- package/src/contracts.ts +4 -5
- package/src/debugLogger.ts +3 -4
- package/src/deltaManager.ts +31 -25
- package/src/deltaQueue.ts +2 -2
- package/src/error.ts +5 -4
- package/src/loader.ts +25 -23
- package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +4 -4
- package/src/noopHeuristic.ts +3 -3
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +2 -2
- package/src/protocolTreeDocumentStorageService.ts +4 -1
- package/src/quorum.ts +1 -1
- package/src/retriableDocumentStorageService.ts +6 -5
- package/src/serializedStateManager.ts +276 -110
- package/src/utils.ts +51 -20
- package/lib/test/attachment.spec.js +0 -380
- package/lib/test/attachment.spec.js.map +0 -1
- package/lib/test/catchUpMonitor.spec.js +0 -88
- package/lib/test/catchUpMonitor.spec.js.map +0 -1
- package/lib/test/connectionManager.spec.js +0 -201
- package/lib/test/connectionManager.spec.js.map +0 -1
- package/lib/test/connectionStateHandler.spec.js +0 -555
- package/lib/test/connectionStateHandler.spec.js.map +0 -1
- package/lib/test/container.spec.js +0 -64
- package/lib/test/container.spec.js.map +0 -1
- package/lib/test/deltaManager.spec.js +0 -405
- package/lib/test/deltaManager.spec.js.map +0 -1
- package/lib/test/loader.spec.js +0 -212
- package/lib/test/loader.spec.js.map +0 -1
- package/lib/test/locationRedirectionTests.spec.js +0 -44
- package/lib/test/locationRedirectionTests.spec.js.map +0 -1
- package/lib/test/serializedStateManager.spec.js +0 -148
- package/lib/test/serializedStateManager.spec.js.map +0 -1
- package/lib/test/snapshotConversionTest.spec.js +0 -79
- package/lib/test/snapshotConversionTest.spec.js.map +0 -1
- package/lib/test/types/validateContainerLoaderPrevious.generated.js +0 -38
- package/lib/test/types/validateContainerLoaderPrevious.generated.js.map +0 -1
- package/lib/test/utils.spec.js +0 -31
- package/lib/test/utils.spec.js.map +0 -1
package/src/loader.ts
CHANGED
|
@@ -3,44 +3,46 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { v4 as uuid } from "uuid";
|
|
7
|
-
import {
|
|
8
|
-
ITelemetryLoggerExt,
|
|
9
|
-
mixinMonitoringContext,
|
|
10
|
-
MonitoringContext,
|
|
11
|
-
PerformanceEvent,
|
|
12
|
-
sessionStorageConfigProvider,
|
|
13
|
-
createChildMonitoringContext,
|
|
14
|
-
UsageError,
|
|
15
|
-
} from "@fluidframework/telemetry-utils";
|
|
16
|
-
import {
|
|
17
|
-
ITelemetryBaseLogger,
|
|
18
|
-
FluidObject,
|
|
19
|
-
IRequest,
|
|
20
|
-
IConfigProviderBase,
|
|
21
|
-
} from "@fluidframework/core-interfaces";
|
|
22
6
|
import {
|
|
23
7
|
IContainer,
|
|
8
|
+
IFluidCodeDetails,
|
|
24
9
|
IFluidModule,
|
|
25
10
|
IHostLoader,
|
|
26
11
|
ILoader,
|
|
27
12
|
ILoaderOptions as ILoaderOptions1,
|
|
28
|
-
LoaderHeader,
|
|
29
13
|
IProvideFluidCodeDetailsComparer,
|
|
30
|
-
|
|
31
|
-
} from "@fluidframework/container-definitions";
|
|
14
|
+
LoaderHeader,
|
|
15
|
+
} from "@fluidframework/container-definitions/internal";
|
|
16
|
+
import {
|
|
17
|
+
FluidObject,
|
|
18
|
+
IConfigProviderBase,
|
|
19
|
+
IRequest,
|
|
20
|
+
ITelemetryBaseLogger,
|
|
21
|
+
} from "@fluidframework/core-interfaces";
|
|
32
22
|
import {
|
|
33
23
|
IDocumentServiceFactory,
|
|
34
24
|
IDocumentStorageService,
|
|
35
25
|
IResolvedUrl,
|
|
36
26
|
IUrlResolver,
|
|
37
|
-
} from "@fluidframework/driver-definitions";
|
|
27
|
+
} from "@fluidframework/driver-definitions/internal";
|
|
38
28
|
import { IClientDetails } from "@fluidframework/protocol-definitions";
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
29
|
+
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
30
|
+
import {
|
|
31
|
+
MonitoringContext,
|
|
32
|
+
PerformanceEvent,
|
|
33
|
+
UsageError,
|
|
34
|
+
createChildMonitoringContext,
|
|
35
|
+
mixinMonitoringContext,
|
|
36
|
+
sessionStorageConfigProvider,
|
|
37
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
38
|
+
import { v4 as uuid } from "uuid";
|
|
39
|
+
|
|
40
|
+
import { Container } from "./container.js";
|
|
41
|
+
import { DebugLogger } from "./debugLogger.js";
|
|
41
42
|
import { pkgVersion } from "./packageVersion.js";
|
|
42
43
|
import { ProtocolHandlerBuilder } from "./protocol.js";
|
|
43
|
-
import {
|
|
44
|
+
import type { IPendingContainerState } from "./serializedStateManager.js";
|
|
45
|
+
import { tryParseCompatibleResolvedUrl } from "./utils.js";
|
|
44
46
|
|
|
45
47
|
function ensureResolvedUrlDefined(
|
|
46
48
|
resolved: IResolvedUrl | undefined,
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { IRequest, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
|
|
7
|
+
import { DriverErrorTypes } from "@fluidframework/driver-definitions";
|
|
7
8
|
import {
|
|
8
|
-
DriverErrorTypes,
|
|
9
9
|
ILocationRedirectionError,
|
|
10
10
|
IUrlResolver,
|
|
11
|
-
} from "@fluidframework/driver-definitions";
|
|
12
|
-
import { createChildLogger } from "@fluidframework/telemetry-utils";
|
|
11
|
+
} from "@fluidframework/driver-definitions/internal";
|
|
12
|
+
import { createChildLogger } from "@fluidframework/telemetry-utils/internal";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Checks if the error is location redirection error.
|
package/src/noopHeuristic.ts
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { TypedEventEmitter } from "@fluid-internal/client-utils";
|
|
7
|
-
import { assert, Timer } from "@fluidframework/core-utils";
|
|
8
|
-
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
9
|
-
import { isRuntimeMessage } from "@fluidframework/driver-utils";
|
|
10
7
|
import { IEvent } from "@fluidframework/core-interfaces";
|
|
8
|
+
import { assert, Timer } from "@fluidframework/core-utils/internal";
|
|
9
|
+
import { isRuntimeMessage } from "@fluidframework/driver-utils/internal";
|
|
10
|
+
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
|
|
11
11
|
|
|
12
12
|
const defaultNoopTimeFrequency = 2000;
|
|
13
13
|
const defaultNoopCountFrequency = 50;
|
package/src/packageVersion.ts
CHANGED
package/src/protocol.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IAudienceOwner } from "@fluidframework/container-definitions";
|
|
7
|
-
import { canBeCoalescedByService } from "@fluidframework/driver-utils";
|
|
6
|
+
import { IAudienceOwner } from "@fluidframework/container-definitions/internal";
|
|
7
|
+
import { canBeCoalescedByService } from "@fluidframework/driver-utils/internal";
|
|
8
8
|
import {
|
|
9
9
|
IProtocolHandler as IBaseProtocolHandler,
|
|
10
10
|
IQuorumSnapshot,
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { IDisposable } from "@fluidframework/core-interfaces";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
IDocumentStorageService,
|
|
9
|
+
ISummaryContext,
|
|
10
|
+
} from "@fluidframework/driver-definitions/internal";
|
|
8
11
|
import { ISummaryTree } from "@fluidframework/protocol-definitions";
|
|
9
12
|
|
|
10
13
|
/**
|
package/src/quorum.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IFluidCodeDetails } from "@fluidframework/
|
|
6
|
+
import { IFluidCodeDetails } from "@fluidframework/container-definitions/internal";
|
|
7
7
|
import { ICommittedProposal } from "@fluidframework/protocol-definitions";
|
|
8
8
|
|
|
9
9
|
export function initQuorumValuesFromCodeDetails(
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { IDisposable } from "@fluidframework/core-interfaces";
|
|
7
|
+
import { assert } from "@fluidframework/core-utils/internal";
|
|
7
8
|
import {
|
|
8
9
|
FetchSource,
|
|
9
10
|
IDocumentStorageService,
|
|
@@ -11,7 +12,8 @@ import {
|
|
|
11
12
|
ISnapshot,
|
|
12
13
|
ISnapshotFetchOptions,
|
|
13
14
|
ISummaryContext,
|
|
14
|
-
} from "@fluidframework/driver-definitions";
|
|
15
|
+
} from "@fluidframework/driver-definitions/internal";
|
|
16
|
+
import { runWithRetry } from "@fluidframework/driver-utils/internal";
|
|
15
17
|
import {
|
|
16
18
|
ICreateBlobResponse,
|
|
17
19
|
ISnapshotTree,
|
|
@@ -19,9 +21,8 @@ import {
|
|
|
19
21
|
ISummaryTree,
|
|
20
22
|
IVersion,
|
|
21
23
|
} from "@fluidframework/protocol-definitions";
|
|
22
|
-
import {
|
|
23
|
-
import { GenericError,
|
|
24
|
-
import { runWithRetry } from "@fluidframework/driver-utils";
|
|
24
|
+
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
25
|
+
import { GenericError, UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
25
26
|
|
|
26
27
|
export class RetriableDocumentStorageService implements IDocumentStorageService, IDisposable {
|
|
27
28
|
private _disposed = false;
|
|
@@ -4,37 +4,83 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
+
IGetPendingLocalStateProps,
|
|
8
|
+
IRuntime,
|
|
9
|
+
} from "@fluidframework/container-definitions/internal";
|
|
10
|
+
import { assert } from "@fluidframework/core-utils/internal";
|
|
11
|
+
import {
|
|
12
|
+
IDocumentStorageService,
|
|
13
|
+
IResolvedUrl,
|
|
14
|
+
ISnapshot,
|
|
15
|
+
} from "@fluidframework/driver-definitions/internal";
|
|
16
|
+
import { isInstanceOfISnapshot } from "@fluidframework/driver-utils/internal";
|
|
17
|
+
import {
|
|
18
|
+
type IDocumentAttributes,
|
|
7
19
|
ISequencedDocumentMessage,
|
|
8
20
|
ISnapshotTree,
|
|
9
21
|
IVersion,
|
|
10
22
|
} from "@fluidframework/protocol-definitions";
|
|
11
|
-
import {
|
|
23
|
+
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
|
|
12
24
|
import {
|
|
13
|
-
ITelemetryLoggerExt,
|
|
14
25
|
MonitoringContext,
|
|
15
26
|
PerformanceEvent,
|
|
16
27
|
UsageError,
|
|
17
28
|
createChildMonitoringContext,
|
|
18
|
-
} from "@fluidframework/telemetry-utils";
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
IDocumentStorageService,
|
|
22
|
-
IResolvedUrl,
|
|
23
|
-
ISnapshot,
|
|
24
|
-
} from "@fluidframework/driver-definitions";
|
|
25
|
-
import { isInstanceOfISnapshot } from "@fluidframework/driver-utils";
|
|
29
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
30
|
+
|
|
26
31
|
import { ISerializableBlobContents, getBlobContentsFromTree } from "./containerStorageAdapter.js";
|
|
27
|
-
import {
|
|
32
|
+
import { getDocumentAttributes } from "./utils.js";
|
|
33
|
+
|
|
34
|
+
export interface SnapshotWithBlobs {
|
|
35
|
+
/**
|
|
36
|
+
* Snapshot from which container initially loaded.
|
|
37
|
+
*/
|
|
38
|
+
baseSnapshot: ISnapshotTree;
|
|
39
|
+
/**
|
|
40
|
+
* Serializable blobs from the base snapshot. Used to load offline since
|
|
41
|
+
* storage is not available.
|
|
42
|
+
*/
|
|
43
|
+
snapshotBlobs: ISerializableBlobContents;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* State saved by a container at close time, to be used to load a new instance
|
|
47
|
+
* of the container to the same state
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
export interface IPendingContainerState extends SnapshotWithBlobs {
|
|
51
|
+
attached: true;
|
|
52
|
+
pendingRuntimeState: unknown;
|
|
53
|
+
/**
|
|
54
|
+
* All ops since base snapshot sequence number up to the latest op
|
|
55
|
+
* seen when the container was closed. Used to apply stashed (saved pending)
|
|
56
|
+
* ops at the same sequence number at which they were made.
|
|
57
|
+
*/
|
|
58
|
+
savedOps: ISequencedDocumentMessage[];
|
|
59
|
+
url: string;
|
|
60
|
+
clientId?: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* State saved by a container in detached state, to be used to load a new instance
|
|
65
|
+
* of the container to the same state (rehydrate)
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
68
|
+
export interface IPendingDetachedContainerState extends SnapshotWithBlobs {
|
|
69
|
+
attached: false;
|
|
70
|
+
hasAttachmentBlobs: boolean;
|
|
71
|
+
pendingRuntimeState?: unknown;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface SnapshotInfo extends SnapshotWithBlobs {
|
|
75
|
+
snapshotSequenceNumber: number;
|
|
76
|
+
}
|
|
28
77
|
|
|
29
78
|
export class SerializedStateManager {
|
|
30
79
|
private readonly processedOps: ISequencedDocumentMessage[] = [];
|
|
31
|
-
private snapshot:
|
|
32
|
-
| {
|
|
33
|
-
tree: ISnapshotTree;
|
|
34
|
-
blobs: ISerializableBlobContents;
|
|
35
|
-
}
|
|
36
|
-
| undefined;
|
|
80
|
+
private snapshot: SnapshotWithBlobs | undefined;
|
|
37
81
|
private readonly mc: MonitoringContext;
|
|
82
|
+
private latestSnapshot: SnapshotInfo | undefined;
|
|
83
|
+
private refreshSnapshot: Promise<void> | undefined;
|
|
38
84
|
|
|
39
85
|
constructor(
|
|
40
86
|
private readonly pendingLocalState: IPendingContainerState | undefined,
|
|
@@ -44,6 +90,7 @@ export class SerializedStateManager {
|
|
|
44
90
|
"readBlob" | "getSnapshotTree" | "getSnapshot" | "getVersions"
|
|
45
91
|
>,
|
|
46
92
|
private readonly _offlineLoadEnabled: boolean,
|
|
93
|
+
private readonly newSnapshotFetched?: () => void,
|
|
47
94
|
) {
|
|
48
95
|
this.mc = createChildMonitoringContext({
|
|
49
96
|
logger: subLogger,
|
|
@@ -58,107 +105,96 @@ export class SerializedStateManager {
|
|
|
58
105
|
public addProcessedOp(message: ISequencedDocumentMessage) {
|
|
59
106
|
if (this.offlineLoadEnabled) {
|
|
60
107
|
this.processedOps.push(message);
|
|
108
|
+
this.updateSnapshotAndProcessedOpsMaybe();
|
|
61
109
|
}
|
|
62
110
|
}
|
|
63
111
|
|
|
64
|
-
private async getVersion(version: string | null): Promise<IVersion | undefined> {
|
|
65
|
-
const versions = await this.storageAdapter.getVersions(version, 1);
|
|
66
|
-
return versions[0];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
112
|
public async fetchSnapshot(
|
|
70
113
|
specifiedVersion: string | undefined,
|
|
71
|
-
supportGetSnapshotApi: boolean
|
|
114
|
+
supportGetSnapshotApi: boolean,
|
|
72
115
|
) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (this.pendingLocalState) {
|
|
81
|
-
this.snapshot = {
|
|
82
|
-
tree: this.pendingLocalState.baseSnapshot,
|
|
83
|
-
blobs: this.pendingLocalState.snapshotBlobs,
|
|
84
|
-
};
|
|
85
|
-
} else {
|
|
86
|
-
assert(snapshotTree !== undefined, 0x8e4 /* Snapshot should exist */);
|
|
116
|
+
if (this.pendingLocalState === undefined) {
|
|
117
|
+
const { baseSnapshot, version } = await getSnapshotTree(
|
|
118
|
+
this.mc,
|
|
119
|
+
this.storageAdapter,
|
|
120
|
+
supportGetSnapshotApi,
|
|
121
|
+
specifiedVersion,
|
|
122
|
+
);
|
|
87
123
|
// non-interactive clients will not have any pending state we want to save
|
|
88
124
|
if (this.offlineLoadEnabled) {
|
|
89
|
-
const
|
|
90
|
-
|
|
125
|
+
const snapshotBlobs = await getBlobContentsFromTree(
|
|
126
|
+
baseSnapshot,
|
|
127
|
+
this.storageAdapter,
|
|
128
|
+
);
|
|
129
|
+
this.snapshot = { baseSnapshot, snapshotBlobs };
|
|
91
130
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
131
|
+
return { baseSnapshot, version };
|
|
132
|
+
} else {
|
|
133
|
+
const { baseSnapshot, snapshotBlobs } = this.pendingLocalState;
|
|
134
|
+
this.snapshot = { baseSnapshot, snapshotBlobs };
|
|
135
|
+
this.refreshSnapshot ??= (async () => {
|
|
136
|
+
this.latestSnapshot = await getLatestSnapshotInfo(
|
|
137
|
+
this.mc,
|
|
138
|
+
this.storageAdapter,
|
|
139
|
+
supportGetSnapshotApi,
|
|
140
|
+
);
|
|
141
|
+
this.newSnapshotFetched?.();
|
|
142
|
+
this.updateSnapshotAndProcessedOpsMaybe();
|
|
143
|
+
})();
|
|
95
144
|
|
|
96
|
-
|
|
97
|
-
specifiedVersion: string | undefined,
|
|
98
|
-
supportGetSnapshotApi: boolean | undefined,
|
|
99
|
-
): Promise<{ snapshot?: ISnapshot | ISnapshotTree; version?: IVersion }> {
|
|
100
|
-
if (
|
|
101
|
-
this.mc.config.getBoolean("Fluid.Container.UseLoadingGroupIdForSnapshotFetch") ===
|
|
102
|
-
true &&
|
|
103
|
-
supportGetSnapshotApi === true
|
|
104
|
-
) {
|
|
105
|
-
const snapshot =
|
|
106
|
-
(await this.storageAdapter.getSnapshot?.({
|
|
107
|
-
versionId: specifiedVersion,
|
|
108
|
-
})) ?? undefined;
|
|
109
|
-
const version: IVersion | undefined =
|
|
110
|
-
snapshot?.snapshotTree.id === undefined
|
|
111
|
-
? undefined
|
|
112
|
-
: {
|
|
113
|
-
id: snapshot.snapshotTree.id,
|
|
114
|
-
treeId: snapshot.snapshotTree.id,
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
if (snapshot === undefined && specifiedVersion !== undefined) {
|
|
118
|
-
this.mc.logger.sendErrorEvent({
|
|
119
|
-
eventName: "getSnapshotTreeFailed",
|
|
120
|
-
id: specifiedVersion,
|
|
121
|
-
});
|
|
122
|
-
// Not sure if this should be here actually
|
|
123
|
-
} else if (snapshot !== undefined && version?.id === undefined) {
|
|
124
|
-
this.mc.logger.sendErrorEvent({
|
|
125
|
-
eventName: "getSnapshotFetchedTreeWithoutVersionId",
|
|
126
|
-
hasVersion: version !== undefined, // if hasVersion is true, this means that the contract with the service was broken.
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
return { snapshot, version };
|
|
145
|
+
return { baseSnapshot, version: undefined };
|
|
130
146
|
}
|
|
131
|
-
return this.fetchSnapshotTree(specifiedVersion);
|
|
132
147
|
}
|
|
133
148
|
|
|
134
149
|
/**
|
|
135
|
-
*
|
|
136
|
-
* @param specifiedVersion - The specific version of the snapshot to retrieve
|
|
137
|
-
* @returns The snapshot requested, or the latest snapshot if no version was specified, plus version ID
|
|
150
|
+
* Updates class snapshot and processedOps if we have a new snapshot and it's among processedOps range.
|
|
138
151
|
*/
|
|
139
|
-
private
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const version = await this.getVersion(specifiedVersion ?? null);
|
|
143
|
-
|
|
144
|
-
if (version === undefined && specifiedVersion !== undefined) {
|
|
145
|
-
// We should have a defined version to load from if specified version requested
|
|
146
|
-
this.mc.logger.sendErrorEvent({
|
|
147
|
-
eventName: "NoVersionFoundWhenSpecified",
|
|
148
|
-
id: specifiedVersion,
|
|
149
|
-
});
|
|
152
|
+
private updateSnapshotAndProcessedOpsMaybe() {
|
|
153
|
+
if (this.latestSnapshot === undefined) {
|
|
154
|
+
return;
|
|
150
155
|
}
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
const snapshotSequenceNumber = this.latestSnapshot?.snapshotSequenceNumber;
|
|
157
|
+
if (this.processedOps.length === 0) {
|
|
158
|
+
// can't refresh latest snapshot until we have processed the ops up to it.
|
|
159
|
+
// Pending state would be behind the latest snapshot.
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const firstProcessedOpSequenceNumber = this.processedOps[0].sequenceNumber;
|
|
163
|
+
const lastProcessedOpSequenceNumber =
|
|
164
|
+
this.processedOps[this.processedOps.length - 1].sequenceNumber;
|
|
165
|
+
|
|
166
|
+
if (snapshotSequenceNumber < firstProcessedOpSequenceNumber) {
|
|
167
|
+
// Snapshot seq number is older than our first processed op, which could mean we're fetching
|
|
168
|
+
// the same snapshot that we already have or snapshot is too old, implicating an unexpected behavior.
|
|
169
|
+
this.mc.logger.sendTelemetryEvent({
|
|
170
|
+
category:
|
|
171
|
+
snapshotSequenceNumber < firstProcessedOpSequenceNumber - 1
|
|
172
|
+
? "error"
|
|
173
|
+
: "generic",
|
|
174
|
+
eventName: "OldSnapshotFetchWhileRefreshing",
|
|
175
|
+
snapshotSequenceNumber,
|
|
176
|
+
firstProcessedOpSequenceNumber,
|
|
177
|
+
});
|
|
178
|
+
this.latestSnapshot = undefined;
|
|
179
|
+
} else if (snapshotSequenceNumber <= lastProcessedOpSequenceNumber) {
|
|
180
|
+
// Snapshot seq num is between the first and last processed op.
|
|
181
|
+
// Remove the ops that are already part of the snapshot
|
|
182
|
+
this.processedOps.splice(
|
|
183
|
+
0,
|
|
184
|
+
snapshotSequenceNumber - firstProcessedOpSequenceNumber + 1,
|
|
185
|
+
);
|
|
186
|
+
this.snapshot = this.latestSnapshot;
|
|
187
|
+
this.latestSnapshot = undefined;
|
|
188
|
+
this.mc.logger.sendTelemetryEvent({
|
|
189
|
+
eventName: "SnapshotRefreshed",
|
|
190
|
+
snapshotSequenceNumber,
|
|
191
|
+
firstProcessedOpSequenceNumber,
|
|
192
|
+
newFirstProcessedOpSequenceNumber:
|
|
193
|
+
this.processedOps.length === 0
|
|
194
|
+
? undefined
|
|
195
|
+
: this.processedOps[0].sequenceNumber,
|
|
159
196
|
});
|
|
160
197
|
}
|
|
161
|
-
return { snapshot, version };
|
|
162
198
|
}
|
|
163
199
|
|
|
164
200
|
/**
|
|
@@ -166,14 +202,7 @@ export class SerializedStateManager {
|
|
|
166
202
|
* base snapshot when attaching.
|
|
167
203
|
* @param snapshot - snapshot and blobs collected while attaching
|
|
168
204
|
*/
|
|
169
|
-
public setSnapshot(
|
|
170
|
-
snapshot:
|
|
171
|
-
| {
|
|
172
|
-
tree: ISnapshotTree;
|
|
173
|
-
blobs: ISerializableBlobContents;
|
|
174
|
-
}
|
|
175
|
-
| undefined,
|
|
176
|
-
) {
|
|
205
|
+
public setSnapshot(snapshot: SnapshotWithBlobs | undefined) {
|
|
177
206
|
this.snapshot = snapshot;
|
|
178
207
|
}
|
|
179
208
|
|
|
@@ -202,8 +231,8 @@ export class SerializedStateManager {
|
|
|
202
231
|
const pendingState: IPendingContainerState = {
|
|
203
232
|
attached: true,
|
|
204
233
|
pendingRuntimeState,
|
|
205
|
-
baseSnapshot: this.snapshot.
|
|
206
|
-
snapshotBlobs: this.snapshot.
|
|
234
|
+
baseSnapshot: this.snapshot.baseSnapshot,
|
|
235
|
+
snapshotBlobs: this.snapshot.snapshotBlobs,
|
|
207
236
|
savedOps: this.processedOps,
|
|
208
237
|
url: resolvedUrl.url,
|
|
209
238
|
// no need to save this if there is no pending runtime state
|
|
@@ -215,3 +244,140 @@ export class SerializedStateManager {
|
|
|
215
244
|
);
|
|
216
245
|
}
|
|
217
246
|
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Retrieves the most recent snapshot and returns its info.
|
|
250
|
+
*
|
|
251
|
+
* @param mc - The monitoring context.
|
|
252
|
+
* @param storageAdapter - The storage adapter providing methods to retrieve the snapshot.
|
|
253
|
+
* @param supportGetSnapshotApi - a boolean indicating whether to use the fetchISnapshot or fetchISnapshotTree.
|
|
254
|
+
* @returns a SnapshotInfo object containing the snapshot tree, snapshot blobs and its sequence number.
|
|
255
|
+
*/
|
|
256
|
+
export async function getLatestSnapshotInfo(
|
|
257
|
+
mc: MonitoringContext,
|
|
258
|
+
storageAdapter: Pick<
|
|
259
|
+
IDocumentStorageService,
|
|
260
|
+
"getSnapshot" | "getSnapshotTree" | "getVersions" | "readBlob"
|
|
261
|
+
>,
|
|
262
|
+
supportGetSnapshotApi: boolean,
|
|
263
|
+
): Promise<SnapshotInfo | undefined> {
|
|
264
|
+
return PerformanceEvent.timedExecAsync(
|
|
265
|
+
mc.logger,
|
|
266
|
+
{ eventName: "GetLatestSnapshotInfo" },
|
|
267
|
+
async () => {
|
|
268
|
+
const { baseSnapshot } = await getSnapshotTree(
|
|
269
|
+
mc,
|
|
270
|
+
storageAdapter,
|
|
271
|
+
supportGetSnapshotApi,
|
|
272
|
+
undefined,
|
|
273
|
+
);
|
|
274
|
+
const snapshotBlobs = await getBlobContentsFromTree(baseSnapshot, storageAdapter);
|
|
275
|
+
const attributes: IDocumentAttributes = await getDocumentAttributes(
|
|
276
|
+
storageAdapter,
|
|
277
|
+
baseSnapshot,
|
|
278
|
+
);
|
|
279
|
+
const snapshotSequenceNumber = attributes.sequenceNumber;
|
|
280
|
+
return { baseSnapshot, snapshotBlobs, snapshotSequenceNumber };
|
|
281
|
+
},
|
|
282
|
+
).catch(() => undefined);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Retrieves a snapshot from the storage adapter and transforms it into an ISnapshotTree object.
|
|
287
|
+
*
|
|
288
|
+
* @param mc - The monitoring context.
|
|
289
|
+
* @param storageAdapter - The storage adapter providing methods to retrieve the snapshot.
|
|
290
|
+
* @param supportGetSnapshotApi - a boolean indicating whether to use the fetchISnapshot or fetchISnapshotTree.
|
|
291
|
+
* @param specifiedVersion - An optional version string specifying the version of the snapshot tree to fetch.
|
|
292
|
+
* @returns - An ISnapshotTree and its version.
|
|
293
|
+
*/
|
|
294
|
+
async function getSnapshotTree(
|
|
295
|
+
mc: MonitoringContext,
|
|
296
|
+
storageAdapter: Pick<
|
|
297
|
+
IDocumentStorageService,
|
|
298
|
+
"getSnapshot" | "getSnapshotTree" | "getVersions"
|
|
299
|
+
>,
|
|
300
|
+
supportGetSnapshotApi: boolean,
|
|
301
|
+
specifiedVersion: string | undefined,
|
|
302
|
+
): Promise<{ baseSnapshot: ISnapshotTree; version?: IVersion }> {
|
|
303
|
+
const { snapshot, version } = supportGetSnapshotApi
|
|
304
|
+
? await fetchISnapshot(mc, storageAdapter, specifiedVersion)
|
|
305
|
+
: await fetchISnapshotTree(mc, storageAdapter, specifiedVersion);
|
|
306
|
+
const baseSnapshot: ISnapshotTree | undefined = isInstanceOfISnapshot(snapshot)
|
|
307
|
+
? snapshot.snapshotTree
|
|
308
|
+
: snapshot;
|
|
309
|
+
assert(baseSnapshot !== undefined, 0x8e4 /* Snapshot should exist */);
|
|
310
|
+
return { baseSnapshot, version };
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Fetches an ISnapshot from a storage adapter based on the specified version.
|
|
315
|
+
*
|
|
316
|
+
* @param mc - The monitoring context.
|
|
317
|
+
* @param storageAdapter - The storage adapter providing a getSnapshot method to retrieve the ISnapshot and version.
|
|
318
|
+
* @param specifiedVersion - An optional version string specifying the version of the snapshot tree to fetch.
|
|
319
|
+
* @returns - The fetched snapshot tree and its version.
|
|
320
|
+
*/
|
|
321
|
+
export async function fetchISnapshot(
|
|
322
|
+
mc: MonitoringContext,
|
|
323
|
+
storageAdapter: Pick<IDocumentStorageService, "getSnapshot">,
|
|
324
|
+
specifiedVersion: string | undefined,
|
|
325
|
+
): Promise<{ snapshot?: ISnapshot; version?: IVersion }> {
|
|
326
|
+
const snapshot = await storageAdapter.getSnapshot?.({ versionId: specifiedVersion });
|
|
327
|
+
const version: IVersion | undefined =
|
|
328
|
+
snapshot?.snapshotTree.id === undefined
|
|
329
|
+
? undefined
|
|
330
|
+
: {
|
|
331
|
+
id: snapshot.snapshotTree.id,
|
|
332
|
+
treeId: snapshot.snapshotTree.id,
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
if (snapshot === undefined && specifiedVersion !== undefined) {
|
|
336
|
+
mc.logger.sendErrorEvent({
|
|
337
|
+
eventName: "getSnapshotTreeFailed",
|
|
338
|
+
id: specifiedVersion,
|
|
339
|
+
});
|
|
340
|
+
} else if (snapshot !== undefined && version?.id === undefined) {
|
|
341
|
+
mc.logger.sendErrorEvent({
|
|
342
|
+
eventName: "getSnapshotFetchedTreeWithoutVersionId",
|
|
343
|
+
hasVersion: version !== undefined, // if hasVersion is true, this means that the contract with the service was broken.
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
return { snapshot, version };
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Fetches an ISnapshotTree from a storage adapter based on the specified version.
|
|
351
|
+
*
|
|
352
|
+
* @param mc - The monitoring context.
|
|
353
|
+
* @param storageAdapter - The storage adapter providing methods to retrieve the ISnapshotTree and version.
|
|
354
|
+
* @param specifiedVersion - An optional version string specifying the version of the snapshot tree to fetch.
|
|
355
|
+
* @returns - The fetched snapshot tree and its version.
|
|
356
|
+
*/
|
|
357
|
+
export async function fetchISnapshotTree(
|
|
358
|
+
mc: MonitoringContext,
|
|
359
|
+
storageAdapter: Pick<IDocumentStorageService, "getSnapshotTree" | "getVersions">,
|
|
360
|
+
specifiedVersion: string | undefined,
|
|
361
|
+
): Promise<{ snapshot?: ISnapshotTree; version?: IVersion | undefined }> {
|
|
362
|
+
const versions = await storageAdapter.getVersions(specifiedVersion ?? null, 1);
|
|
363
|
+
const version = versions[0];
|
|
364
|
+
|
|
365
|
+
if (version === undefined && specifiedVersion !== undefined) {
|
|
366
|
+
// We should have a defined version to load from if specified version requested
|
|
367
|
+
mc.logger.sendErrorEvent({
|
|
368
|
+
eventName: "NoVersionFoundWhenSpecified",
|
|
369
|
+
id: specifiedVersion,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
const snapshot = (await storageAdapter.getSnapshotTree(version)) ?? undefined;
|
|
373
|
+
|
|
374
|
+
if (snapshot === undefined && version !== undefined) {
|
|
375
|
+
mc.logger.sendErrorEvent({ eventName: "getSnapshotTreeFailed", id: version.id });
|
|
376
|
+
} else if (snapshot !== undefined && version?.id === undefined) {
|
|
377
|
+
mc.logger.sendErrorEvent({
|
|
378
|
+
eventName: "getSnapshotFetchedTreeWithoutVersionId",
|
|
379
|
+
hasVersion: version !== undefined, // if hasVersion is true, this means that the contract with the service was broken.
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
return { snapshot, version };
|
|
383
|
+
}
|