@fluidframework/container-runtime 2.0.0-dev.4.1.0.148229 → 2.0.0-dev.4.2.0.153917
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +69 -0
- package/dist/blobManager.d.ts +6 -14
- package/dist/blobManager.d.ts.map +1 -1
- package/dist/blobManager.js +50 -37
- package/dist/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +14 -1
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +37 -12
- package/dist/containerRuntime.js.map +1 -1
- package/dist/gc/gcHelpers.d.ts.map +1 -1
- package/dist/gc/gcHelpers.js +6 -6
- package/dist/gc/gcHelpers.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -0
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +3 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/dist/opLifecycle/opDecompressor.js +2 -1
- package/dist/opLifecycle/opDecompressor.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +14 -0
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -0
- package/dist/opLifecycle/opGroupingManager.js +56 -0
- package/dist/opLifecycle/opGroupingManager.js.map +1 -0
- package/dist/opLifecycle/opSplitter.d.ts +1 -1
- package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
- package/dist/opLifecycle/opSplitter.js +5 -6
- package/dist/opLifecycle/opSplitter.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts +2 -0
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +3 -3
- package/dist/opLifecycle/outbox.js.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.d.ts +4 -2
- package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/dist/opLifecycle/remoteMessageProcessor.js +30 -20
- package/dist/opLifecycle/remoteMessageProcessor.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/summary/index.d.ts +1 -1
- package/dist/summary/index.d.ts.map +1 -1
- package/dist/summary/index.js +3 -1
- package/dist/summary/index.js.map +1 -1
- package/dist/summary/runningSummarizer.d.ts +5 -3
- package/dist/summary/runningSummarizer.d.ts.map +1 -1
- package/dist/summary/runningSummarizer.js +82 -67
- package/dist/summary/runningSummarizer.js.map +1 -1
- package/dist/summary/summarizer.d.ts.map +1 -1
- package/dist/summary/summarizer.js +1 -5
- package/dist/summary/summarizer.js.map +1 -1
- package/dist/summary/summarizerHeuristics.d.ts +1 -0
- package/dist/summary/summarizerHeuristics.d.ts.map +1 -1
- package/dist/summary/summarizerHeuristics.js +3 -0
- package/dist/summary/summarizerHeuristics.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js +1 -1
- package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +128 -2
- package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js +4 -3
- package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/dist/summary/summarizerTypes.d.ts +14 -2
- package/dist/summary/summarizerTypes.d.ts.map +1 -1
- package/dist/summary/summarizerTypes.js.map +1 -1
- package/dist/summary/summaryGenerator.d.ts +28 -2
- package/dist/summary/summaryGenerator.d.ts.map +1 -1
- package/dist/summary/summaryGenerator.js +19 -16
- package/dist/summary/summaryGenerator.js.map +1 -1
- package/lib/blobManager.d.ts +6 -14
- package/lib/blobManager.d.ts.map +1 -1
- package/lib/blobManager.js +50 -37
- package/lib/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +14 -1
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +38 -13
- package/lib/containerRuntime.js.map +1 -1
- package/lib/gc/gcHelpers.d.ts.map +1 -1
- package/lib/gc/gcHelpers.js +6 -6
- package/lib/gc/gcHelpers.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -0
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -0
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
- package/lib/opLifecycle/opDecompressor.js +2 -1
- package/lib/opLifecycle/opDecompressor.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +14 -0
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -0
- package/lib/opLifecycle/opGroupingManager.js +52 -0
- package/lib/opLifecycle/opGroupingManager.js.map +1 -0
- package/lib/opLifecycle/opSplitter.d.ts +1 -1
- package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
- package/lib/opLifecycle/opSplitter.js +5 -6
- package/lib/opLifecycle/opSplitter.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts +2 -0
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +3 -3
- package/lib/opLifecycle/outbox.js.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.d.ts +4 -2
- package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
- package/lib/opLifecycle/remoteMessageProcessor.js +30 -20
- package/lib/opLifecycle/remoteMessageProcessor.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/summary/index.d.ts +1 -1
- package/lib/summary/index.d.ts.map +1 -1
- package/lib/summary/index.js +1 -0
- package/lib/summary/index.js.map +1 -1
- package/lib/summary/runningSummarizer.d.ts +5 -3
- package/lib/summary/runningSummarizer.d.ts.map +1 -1
- package/lib/summary/runningSummarizer.js +82 -67
- package/lib/summary/runningSummarizer.js.map +1 -1
- package/lib/summary/summarizer.d.ts.map +1 -1
- package/lib/summary/summarizer.js +1 -5
- package/lib/summary/summarizer.js.map +1 -1
- package/lib/summary/summarizerHeuristics.d.ts +1 -0
- package/lib/summary/summarizerHeuristics.d.ts.map +1 -1
- package/lib/summary/summarizerHeuristics.js +3 -0
- package/lib/summary/summarizerHeuristics.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js +1 -1
- package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +128 -2
- package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js +3 -3
- package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
- package/lib/summary/summarizerTypes.d.ts +14 -2
- package/lib/summary/summarizerTypes.d.ts.map +1 -1
- package/lib/summary/summarizerTypes.js.map +1 -1
- package/lib/summary/summaryGenerator.d.ts +28 -2
- package/lib/summary/summaryGenerator.d.ts.map +1 -1
- package/lib/summary/summaryGenerator.js +17 -15
- package/lib/summary/summaryGenerator.js.map +1 -1
- package/package.json +19 -16
- package/src/blobManager.ts +64 -41
- package/src/containerRuntime.ts +70 -9
- package/src/gc/gcHelpers.ts +9 -6
- package/src/opLifecycle/README.md +106 -0
- package/src/opLifecycle/index.ts +1 -0
- package/src/opLifecycle/opDecompressor.ts +1 -0
- package/src/opLifecycle/opGroupingManager.ts +78 -0
- package/src/opLifecycle/opSplitter.ts +1 -5
- package/src/opLifecycle/outbox.ts +7 -3
- package/src/opLifecycle/remoteMessageProcessor.ts +38 -22
- package/src/packageVersion.ts +1 -1
- package/src/summary/index.ts +1 -1
- package/src/summary/runningSummarizer.ts +102 -80
- package/src/summary/summarizer.ts +0 -8
- package/src/summary/summarizerHeuristics.ts +4 -0
- package/src/summary/summarizerNode/summarizerNode.ts +1 -1
- package/src/summary/summarizerNode/summarizerNodeWithGc.ts +3 -3
- package/src/summary/summarizerTypes.ts +20 -3
- package/src/summary/summaryGenerator.ts +22 -16
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @fluidframework/container-runtime
|
|
2
|
+
|
|
3
|
+
## 2.0.0-internal.4.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- GC interfaces removed from runtime-definitions ([#14750](https://github.com/microsoft/FluidFramework/pull-requests/14750)) [60274eacab](https://github.com/microsoft/FluidFramework/commits/60274eacabf14d42f52f6ad1c2f64356e64ba1a2)
|
|
8
|
+
|
|
9
|
+
The following interfaces available in `@fluidframework/runtime-definitions` are internal implementation details and have been deprecated for public use. They will be removed in an upcoming release.
|
|
10
|
+
|
|
11
|
+
- `IGarbageCollectionNodeData`
|
|
12
|
+
- `IGarbageCollectionState`
|
|
13
|
+
- `IGarbageCollectionSnapshotData`
|
|
14
|
+
- `IGarbageCollectionSummaryDetailsLegacy`
|
|
15
|
+
|
|
16
|
+
- Ability to enable grouped batching ([#14512](https://github.com/microsoft/FluidFramework/pull-requests/14512)) [8e4dc47a38](https://github.com/microsoft/FluidFramework/commits/8e4dc47a3871bcaf1f7c1339c362d9c9d08551fc)
|
|
17
|
+
|
|
18
|
+
The `IContainerRuntimeOptions.enableGroupedBatching` option has been added to the container runtime layer and is off by default. This option will group all batch messages
|
|
19
|
+
under a new "grouped" message to be sent to the service. Upon receiving this new "grouped" message, the batch messages will be extracted and given
|
|
20
|
+
the sequence number of the parent "grouped" message.
|
|
21
|
+
|
|
22
|
+
Upon enabling this option, if any issues arise, use the `Fluid.ContainerRuntime.DisableGroupedBatching` feature flag to disable at runtime. This option should **ONLY** be enabled after observing that 99.9% of your application sessions contains these changes (version "2.0.0-internal.4.1.0" or later). This option is experimental and should not be enabled yet in production. Containers created with this option may not open in future versions of the framework.
|
|
23
|
+
|
|
24
|
+
This option will change a couple of expectations around message structure and runtime layer expectations. Only enable this option after testing
|
|
25
|
+
and verifying that the following expectation changes won't have any effects:
|
|
26
|
+
|
|
27
|
+
- batch messages observed at the runtime layer will not match messages seen at the loader layer
|
|
28
|
+
- messages within the same batch will have the same sequence number
|
|
29
|
+
- client sequence numbers on batch messages can only be used to order messages with the same sequenceNumber
|
|
30
|
+
- requires all ops to be processed by runtime layer (version "2.0.0-internal.1.2.0" or later
|
|
31
|
+
https://github.com/microsoft/FluidFramework/pull/11832)
|
|
32
|
+
|
|
33
|
+
- Op compression is enabled by default ([#14856](https://github.com/microsoft/FluidFramework/pull-requests/14856)) [439c21f31f](https://github.com/microsoft/FluidFramework/commits/439c21f31f4a3ea6515f01d2b2be7f35c04910ce)
|
|
34
|
+
|
|
35
|
+
If the size of a batch is larger than 614kb, the ops will be compressed. After upgrading to this version, if batches exceed the size threshold, the runtime will produce a new type of op with the compression properties. To open a document which contains this type of op, the client's runtime version needs to be at least `client_v2.0.0-internal.2.3.0`. Older clients will close with assert `0x3ce` ("Runtime message of unknown type") and will not be able to open the documents until they upgrade. To minimize the risk, it is recommended to audit existing session and ensure that at least 99.9% of them are using a runtime version equal or greater than `client_v2.0.0-internal.2.3.0`, before upgrading to `2.0.0-internal.4.1.0`.
|
|
36
|
+
|
|
37
|
+
More information about op compression can be found
|
|
38
|
+
[here](./packages/runtime/container-runtime/src/opLifecycle/README.md).
|
|
39
|
+
|
|
40
|
+
- @fluidframework/garbage-collector deprecated ([#14750](https://github.com/microsoft/FluidFramework/pull-requests/14750)) [60274eacab](https://github.com/microsoft/FluidFramework/commits/60274eacabf14d42f52f6ad1c2f64356e64ba1a2)
|
|
41
|
+
|
|
42
|
+
The `@fluidframework/garbage-collector` package is deprecated with the following functions, interfaces, and types in it.
|
|
43
|
+
These are internal implementation details and have been deprecated for public use. They will be removed in an upcoming
|
|
44
|
+
release.
|
|
45
|
+
|
|
46
|
+
- `cloneGCData`
|
|
47
|
+
- `concatGarbageCollectionData`
|
|
48
|
+
- `concatGarbageCollectionStates`
|
|
49
|
+
- `GCDataBuilder`
|
|
50
|
+
- `getGCDataFromSnapshot`
|
|
51
|
+
- `IGCResult`
|
|
52
|
+
- `removeRouteFromAllNodes`
|
|
53
|
+
- `runGarbageCollection`
|
|
54
|
+
- `trimLeadingAndTrailingSlashes`
|
|
55
|
+
- `trimLeadingSlashes`
|
|
56
|
+
- `trimTrailingSlashes`
|
|
57
|
+
- `unpackChildNodesGCDetails`
|
|
58
|
+
- `unpackChildNodesUsedRoutes`
|
package/README.md
CHANGED
|
@@ -1 +1,70 @@
|
|
|
1
1
|
# @fluidframework/container-runtime
|
|
2
|
+
|
|
3
|
+
<!-- AUTO-GENERATED-CONTENT:START (LIBRARY_PACKAGE_README:scripts=FALSE) -->
|
|
4
|
+
|
|
5
|
+
<!-- prettier-ignore-start -->
|
|
6
|
+
<!-- NOTE: This section is automatically generated using @fluid-tools/markdown-magic. Do not update these generated contents directly. -->
|
|
7
|
+
|
|
8
|
+
## Using Fluid Framework libraries
|
|
9
|
+
|
|
10
|
+
When taking a dependency on a Fluid Framework library, we recommend using a `^` (caret) version range, such as `^1.3.4`.
|
|
11
|
+
While Fluid Framework libraries may use different ranges with interdependencies between other Fluid Framework libraries,
|
|
12
|
+
library consumers should always prefer `^`.
|
|
13
|
+
|
|
14
|
+
Note that when depending on a library version of the form 2.0.0-internal.x.y.z, called the Fluid internal version
|
|
15
|
+
scheme, you must use a `>= <` dependency range. Standard `^` and `~` ranges will not work as expected. See the
|
|
16
|
+
[@fluid-tools/version-tools](https://github.com/microsoft/FluidFramework/blob/main/build-tools/packages/version-tools/README.md)
|
|
17
|
+
package for more information including tools to convert between version schemes.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
To get started, install the package by running the following command:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm i @fluidframework/container-runtime
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## API Documentation
|
|
28
|
+
|
|
29
|
+
API documentation for **@fluidframework/container-runtime** is available at <https://fluidframework.com/docs/apis/container-runtime>.
|
|
30
|
+
|
|
31
|
+
## Contribution Guidelines
|
|
32
|
+
|
|
33
|
+
There are many ways to [contribute](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md) to Fluid.
|
|
34
|
+
|
|
35
|
+
- Participate in Q&A in our [GitHub Discussions](https://github.com/microsoft/FluidFramework/discussions).
|
|
36
|
+
- [Submit bugs](https://github.com/microsoft/FluidFramework/issues) and help us verify fixes as they are checked in.
|
|
37
|
+
- Review the [source code changes](https://github.com/microsoft/FluidFramework/pulls).
|
|
38
|
+
- [Contribute bug fixes](https://github.com/microsoft/FluidFramework/blob/main/CONTRIBUTING.md).
|
|
39
|
+
|
|
40
|
+
Detailed instructions for working in the repo can be found in the [Wiki](https://github.com/microsoft/FluidFramework/wiki).
|
|
41
|
+
|
|
42
|
+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
|
43
|
+
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
|
44
|
+
|
|
45
|
+
This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
|
|
46
|
+
Use of these trademarks or logos must follow Microsoft’s [Trademark & Brand Guidelines](https://www.microsoft.com/trademarks).
|
|
47
|
+
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
|
|
48
|
+
|
|
49
|
+
## Help
|
|
50
|
+
|
|
51
|
+
Not finding what you're looking for in this README? Check out our [GitHub
|
|
52
|
+
Wiki](https://github.com/microsoft/FluidFramework/wiki) or [fluidframework.com](https://fluidframework.com/docs/).
|
|
53
|
+
|
|
54
|
+
Still not finding what you're looking for? Please [file an
|
|
55
|
+
issue](https://github.com/microsoft/FluidFramework/wiki/Submitting-Bugs-and-Feature-Requests).
|
|
56
|
+
|
|
57
|
+
Thank you!
|
|
58
|
+
|
|
59
|
+
## Trademark
|
|
60
|
+
|
|
61
|
+
This project may contain Microsoft trademarks or logos for Microsoft projects, products, or services.
|
|
62
|
+
|
|
63
|
+
Use of these trademarks or logos must follow Microsoft's [Trademark & Brand
|
|
64
|
+
Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
|
|
65
|
+
|
|
66
|
+
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
|
|
67
|
+
|
|
68
|
+
<!-- prettier-ignore-end -->
|
|
69
|
+
|
|
70
|
+
<!-- AUTO-GENERATED-CONTENT:END -->
|
package/dist/blobManager.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { IDocumentStorageService } from "@fluidframework/driver-definitions";
|
|
|
7
7
|
import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
|
|
8
8
|
import { TypedEventEmitter } from "@fluidframework/common-utils";
|
|
9
9
|
import { IContainerRuntime, IContainerRuntimeEvents } from "@fluidframework/container-runtime-definitions";
|
|
10
|
+
import { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
10
11
|
import { IGarbageCollectionData, ISummaryTreeWithStats, ITelemetryContext } from "@fluidframework/runtime-definitions";
|
|
11
12
|
import { ContainerRuntime } from "./containerRuntime";
|
|
12
13
|
/**
|
|
@@ -39,6 +40,8 @@ export declare type IBlobManagerRuntime = Pick<IContainerRuntime, "attachState"
|
|
|
39
40
|
export interface IPendingBlobs {
|
|
40
41
|
[id: string]: {
|
|
41
42
|
blob: string;
|
|
43
|
+
uploadTime?: number;
|
|
44
|
+
minTTLInSeconds?: number;
|
|
42
45
|
};
|
|
43
46
|
}
|
|
44
47
|
export interface IBlobManagerEvents {
|
|
@@ -47,21 +50,10 @@ export interface IBlobManagerEvents {
|
|
|
47
50
|
export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
48
51
|
private readonly routeContext;
|
|
49
52
|
private readonly getStorage;
|
|
50
|
-
/**
|
|
51
|
-
* Submit a BlobAttach op. When a blob is uploaded, there is a short grace period before which the blob is
|
|
52
|
-
* deleted. The BlobAttach op notifies the server that blob is in use. The server will then not delete the
|
|
53
|
-
* the blob as long as it is listed as referenced in future summaries. The summarizing client will know to
|
|
54
|
-
* include the storage ID in the summary when it sees the op.
|
|
55
|
-
*
|
|
56
|
-
* The op will also include a local ID to inform all clients of the relation to the storage ID, without
|
|
57
|
-
* knowledge of which they cannot request the blob from storage. It's important that this op is sequenced
|
|
58
|
-
* before any ops that reference the local ID, otherwise, an invalid handle could be added to the document.
|
|
59
|
-
*/
|
|
60
|
-
private readonly sendBlobAttachOp;
|
|
61
53
|
private readonly blobRequested;
|
|
62
54
|
private readonly isBlobDeleted;
|
|
63
55
|
private readonly runtime;
|
|
64
|
-
private readonly
|
|
56
|
+
private readonly closeContainer;
|
|
65
57
|
static readonly basePath = "_blobs";
|
|
66
58
|
private static readonly redirectTableBlobName;
|
|
67
59
|
private readonly mc;
|
|
@@ -93,6 +85,7 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
93
85
|
* Tombstone is a temporary feature that imitates a blob getting swept by garbage collection.
|
|
94
86
|
*/
|
|
95
87
|
private readonly tombstonedBlobs;
|
|
88
|
+
private readonly sendBlobAttachOp;
|
|
96
89
|
constructor(routeContext: IFluidHandleContext, snapshot: IBlobManagerLoadInfo, getStorage: () => IDocumentStorageService,
|
|
97
90
|
/**
|
|
98
91
|
* Submit a BlobAttach op. When a blob is uploaded, there is a short grace period before which the blob is
|
|
@@ -104,7 +97,7 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
104
97
|
* knowledge of which they cannot request the blob from storage. It's important that this op is sequenced
|
|
105
98
|
* before any ops that reference the local ID, otherwise, an invalid handle could be added to the document.
|
|
106
99
|
*/
|
|
107
|
-
sendBlobAttachOp: (localId: string, storageId?: string) => void, blobRequested: (blobPath: string) => void, isBlobDeleted: (blobPath: string) => boolean, runtime: IBlobManagerRuntime, stashedBlobs: IPendingBlobs | undefined,
|
|
100
|
+
sendBlobAttachOp: (localId: string, storageId?: string) => void, blobRequested: (blobPath: string) => void, isBlobDeleted: (blobPath: string) => boolean, runtime: IBlobManagerRuntime, stashedBlobs: IPendingBlobs | undefined, closeContainer: (error?: ICriticalContainerError) => void);
|
|
108
101
|
private get pendingOfflineUploads();
|
|
109
102
|
get hasPendingOfflineUploads(): boolean;
|
|
110
103
|
get hasPendingBlobs(): boolean;
|
|
@@ -142,7 +135,6 @@ export declare class BlobManager extends TypedEventEmitter<IBlobManagerEvents> {
|
|
|
142
135
|
* @param metadata - op metadata containing storage and/or local IDs
|
|
143
136
|
*/
|
|
144
137
|
reSubmit(metadata: Record<string, unknown> | undefined): void;
|
|
145
|
-
private logTimeInfo;
|
|
146
138
|
processBlobAttachOp(message: ISequencedDocumentMessage, local: boolean): void;
|
|
147
139
|
/**
|
|
148
140
|
* Reads blobs needed to load BlobManager from storage.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAEN,yBAAyB,EACzB,aAAa,EACb,MAAM,sCAAsC,CAAC;AAO9C,OAAO,EAKN,iBAAiB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACN,iBAAiB,EACjB,uBAAuB,EACvB,MAAM,+CAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../src/blobManager.ts"],"names":[],"mappings":"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"}
|
package/dist/blobManager.js
CHANGED
|
@@ -10,6 +10,7 @@ const runtime_utils_1 = require("@fluidframework/runtime-utils");
|
|
|
10
10
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
11
11
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
12
12
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
13
|
+
const container_utils_1 = require("@fluidframework/container-utils");
|
|
13
14
|
const containerRuntime_1 = require("./containerRuntime");
|
|
14
15
|
const gc_1 = require("./gc");
|
|
15
16
|
const throttler_1 = require("./throttler");
|
|
@@ -86,15 +87,14 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
86
87
|
blobRequested,
|
|
87
88
|
// Called to check if a blob has been deleted by GC.
|
|
88
89
|
// blobPath's format - `/<BlobManager.basePath>/<blobId>`.
|
|
89
|
-
isBlobDeleted, runtime, stashedBlobs = {},
|
|
90
|
+
isBlobDeleted, runtime, stashedBlobs = {}, closeContainer) {
|
|
90
91
|
super();
|
|
91
92
|
this.routeContext = routeContext;
|
|
92
93
|
this.getStorage = getStorage;
|
|
93
|
-
this.sendBlobAttachOp = sendBlobAttachOp;
|
|
94
94
|
this.blobRequested = blobRequested;
|
|
95
95
|
this.isBlobDeleted = isBlobDeleted;
|
|
96
96
|
this.runtime = runtime;
|
|
97
|
-
this.
|
|
97
|
+
this.closeContainer = closeContainer;
|
|
98
98
|
/**
|
|
99
99
|
* Blobs which have not been uploaded or for which we have not yet seen a BlobAttach op round-trip.
|
|
100
100
|
* Until we see the op round-trip, there is a possibility we may need to re-upload the blob, so
|
|
@@ -127,6 +127,21 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
127
127
|
// Begin uploading stashed blobs from previous container instance
|
|
128
128
|
Object.entries(stashedBlobs).forEach(([localId, entry]) => {
|
|
129
129
|
const blob = (0, common_utils_1.stringToBuffer)(entry.blob, "base64");
|
|
130
|
+
if (entry.minTTLInSeconds && entry.uploadTime) {
|
|
131
|
+
const timeLapseSinceLocalUpload = (Date.now() - entry.uploadTime) / 1000;
|
|
132
|
+
// stashed entries with more than half-life in storage will not be reuploaded
|
|
133
|
+
if (entry.minTTLInSeconds - timeLapseSinceLocalUpload > entry.minTTLInSeconds / 2) {
|
|
134
|
+
this.pendingBlobs.set(localId, {
|
|
135
|
+
blob,
|
|
136
|
+
status: PendingBlobStatus.OfflinePendingOp,
|
|
137
|
+
handleP: new common_utils_1.Deferred(),
|
|
138
|
+
uploadP: undefined,
|
|
139
|
+
uploadTime: entry.uploadTime,
|
|
140
|
+
minTTLInSeconds: entry.minTTLInSeconds,
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
130
145
|
this.pendingBlobs.set(localId, {
|
|
131
146
|
blob,
|
|
132
147
|
status: PendingBlobStatus.OfflinePendingUpload,
|
|
@@ -134,6 +149,30 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
134
149
|
uploadP: this.uploadBlob(localId, blob),
|
|
135
150
|
});
|
|
136
151
|
});
|
|
152
|
+
this.sendBlobAttachOp = (localId, blobId) => {
|
|
153
|
+
const pendingEntry = this.pendingBlobs.get(localId);
|
|
154
|
+
if ((pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.uploadTime) && (pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.minTTLInSeconds)) {
|
|
155
|
+
const secondsSinceUpload = (Date.now() - pendingEntry.uploadTime) / 1000;
|
|
156
|
+
const expired = pendingEntry.minTTLInSeconds - secondsSinceUpload < 0;
|
|
157
|
+
this.mc.logger.sendTelemetryEvent({
|
|
158
|
+
eventName: "sendBlobAttach",
|
|
159
|
+
entryStatus: pendingEntry.status,
|
|
160
|
+
secondsSinceUpload,
|
|
161
|
+
minTTLInSeconds: pendingEntry.minTTLInSeconds,
|
|
162
|
+
expired,
|
|
163
|
+
});
|
|
164
|
+
if (expired) {
|
|
165
|
+
// we want to avoid submitting ops with broken handles
|
|
166
|
+
this.closeContainer(new container_utils_1.GenericError("Trying to submit a BlobAttach for expired blob", undefined, {
|
|
167
|
+
localId,
|
|
168
|
+
blobId,
|
|
169
|
+
entryStatus: pendingEntry.status,
|
|
170
|
+
secondsSinceUpload,
|
|
171
|
+
}));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return sendBlobAttachOp(localId, blobId);
|
|
175
|
+
};
|
|
137
176
|
}
|
|
138
177
|
get pendingOfflineUploads() {
|
|
139
178
|
return Array.from(this.pendingBlobs.values()).filter((e) => e.status === PendingBlobStatus.OfflinePendingUpload);
|
|
@@ -266,9 +305,8 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
266
305
|
(0, common_utils_1.assert)((entry === null || entry === void 0 ? void 0 : entry.status) === PendingBlobStatus.OnlinePendingUpload ||
|
|
267
306
|
(entry === null || entry === void 0 ? void 0 : entry.status) === PendingBlobStatus.OfflinePendingUpload, 0x386 /* Must have pending blob entry for uploaded blob */);
|
|
268
307
|
entry.storageId = response.id;
|
|
269
|
-
entry.
|
|
308
|
+
entry.uploadTime = Date.now();
|
|
270
309
|
entry.minTTLInSeconds = response.minTTLInSeconds;
|
|
271
|
-
entry.serverUploadTime = this.getCurrentReferenceTimestampMs();
|
|
272
310
|
if (this.runtime.connected) {
|
|
273
311
|
if (entry.status === PendingBlobStatus.OnlinePendingUpload) {
|
|
274
312
|
// Send a blob attach op. This serves two purposes:
|
|
@@ -276,7 +314,6 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
276
314
|
// until its storage ID is added to the next summary.
|
|
277
315
|
// 2. It will create a local ID to storage ID mapping in all clients which is needed to retrieve the
|
|
278
316
|
// blob from the server via the storage ID.
|
|
279
|
-
this.logTimeInfo(entry, "sendBlobAttachResolveTTL");
|
|
280
317
|
this.sendBlobAttachOp(localId, response.id);
|
|
281
318
|
if (this.storageIds.has(response.id)) {
|
|
282
319
|
// The blob is de-duped. Set up a local ID to storage ID mapping and return the blob. Since this is
|
|
@@ -340,7 +377,6 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
340
377
|
* is called on reconnection.
|
|
341
378
|
*/
|
|
342
379
|
if (entry.status !== PendingBlobStatus.OnlinePendingOp) {
|
|
343
|
-
this.logTimeInfo(entry, "sendBlobAttachTransitionOfflineTTL");
|
|
344
380
|
this.sendBlobAttachOp(localId, entry.storageId);
|
|
345
381
|
}
|
|
346
382
|
entry.status =
|
|
@@ -359,9 +395,6 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
359
395
|
const { localId, blobId } = metadata;
|
|
360
396
|
(0, common_utils_1.assert)(localId !== undefined, 0x50d /* local ID not available on reSubmit */);
|
|
361
397
|
const pendingEntry = this.pendingBlobs.get(localId);
|
|
362
|
-
if (pendingEntry) {
|
|
363
|
-
this.logTimeInfo(pendingEntry, "sendBlobAttachResubmitTTL");
|
|
364
|
-
}
|
|
365
398
|
if (!blobId) {
|
|
366
399
|
// We submitted this op while offline. The blob should have been uploaded by now.
|
|
367
400
|
(0, common_utils_1.assert)((pendingEntry === null || pendingEntry === void 0 ? void 0 : pendingEntry.status) === PendingBlobStatus.OfflinePendingOp &&
|
|
@@ -370,32 +403,6 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
370
403
|
}
|
|
371
404
|
return this.sendBlobAttachOp(localId, blobId);
|
|
372
405
|
}
|
|
373
|
-
logTimeInfo(pendingEntry, eventName) {
|
|
374
|
-
var _a, _b;
|
|
375
|
-
let timeLapseSinceLocalUpload = 0;
|
|
376
|
-
let timeLapseSinceServerUpload = 0;
|
|
377
|
-
let expiredUsingLocalTime;
|
|
378
|
-
let expiredUsingServerTime;
|
|
379
|
-
if (pendingEntry.localUploadTime) {
|
|
380
|
-
timeLapseSinceLocalUpload = (Date.now() - pendingEntry.localUploadTime) / 1000;
|
|
381
|
-
expiredUsingLocalTime =
|
|
382
|
-
((_a = pendingEntry.minTTLInSeconds) !== null && _a !== void 0 ? _a : 0) - timeLapseSinceLocalUpload < 0 ? true : false;
|
|
383
|
-
}
|
|
384
|
-
if (pendingEntry.serverUploadTime) {
|
|
385
|
-
timeLapseSinceServerUpload = (Date.now() - pendingEntry.serverUploadTime) / 1000;
|
|
386
|
-
expiredUsingServerTime =
|
|
387
|
-
((_b = pendingEntry.minTTLInSeconds) !== null && _b !== void 0 ? _b : 0) - timeLapseSinceServerUpload < 0 ? true : false;
|
|
388
|
-
}
|
|
389
|
-
this.mc.logger.sendTelemetryEvent({
|
|
390
|
-
eventName,
|
|
391
|
-
entryStatus: pendingEntry.status,
|
|
392
|
-
timeLapseSinceLocalUpload,
|
|
393
|
-
timeLapseSinceServerUpload,
|
|
394
|
-
minTTLInSeconds: pendingEntry.minTTLInSeconds,
|
|
395
|
-
expiredUsingLocalTime,
|
|
396
|
-
expiredUsingServerTime,
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
406
|
processBlobAttachOp(message, local) {
|
|
400
407
|
var _a, _b;
|
|
401
408
|
const localId = (_a = message.metadata) === null || _a === void 0 ? void 0 : _a.localId;
|
|
@@ -651,7 +658,13 @@ class BlobManager extends common_utils_1.TypedEventEmitter {
|
|
|
651
658
|
getPendingBlobs() {
|
|
652
659
|
const blobs = {};
|
|
653
660
|
for (const [key, entry] of this.pendingBlobs) {
|
|
654
|
-
blobs[key] =
|
|
661
|
+
blobs[key] = entry.minTTLInSeconds
|
|
662
|
+
? {
|
|
663
|
+
blob: (0, common_utils_1.bufferToString)(entry.blob, "base64"),
|
|
664
|
+
uploadTime: entry.uploadTime,
|
|
665
|
+
minTTLInSeconds: entry.minTTLInSeconds,
|
|
666
|
+
}
|
|
667
|
+
: { blob: (0, common_utils_1.bufferToString)(entry.blob, "base64") };
|
|
655
668
|
}
|
|
656
669
|
return blobs;
|
|
657
670
|
}
|