@fluidframework/container-runtime 2.70.0-361248 → 2.70.0-361788
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/container-runtime.test-files.tar +0 -0
- package/dist/blobManager/blobManager.d.ts.map +1 -1
- package/dist/blobManager/blobManager.js +0 -1
- package/dist/blobManager/blobManager.js.map +1 -1
- package/dist/containerRuntime.d.ts +10 -0
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +37 -4
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js +1 -1
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +7 -0
- package/dist/opLifecycle/outbox.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/runtimeLayerCompatState.d.ts +4 -3
- package/dist/runtimeLayerCompatState.d.ts.map +1 -1
- package/dist/runtimeLayerCompatState.js +4 -35
- package/dist/runtimeLayerCompatState.js.map +1 -1
- package/dist/storageServiceWithAttachBlobs.d.ts +0 -36
- package/dist/storageServiceWithAttachBlobs.d.ts.map +1 -1
- package/dist/storageServiceWithAttachBlobs.js +0 -55
- package/dist/storageServiceWithAttachBlobs.js.map +1 -1
- package/lib/blobManager/blobManager.d.ts.map +1 -1
- package/lib/blobManager/blobManager.js +0 -1
- package/lib/blobManager/blobManager.js.map +1 -1
- package/lib/containerRuntime.d.ts +10 -0
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +37 -4
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js +1 -1
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +7 -0
- package/lib/opLifecycle/outbox.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/runtimeLayerCompatState.d.ts +4 -3
- package/lib/runtimeLayerCompatState.d.ts.map +1 -1
- package/lib/runtimeLayerCompatState.js +5 -36
- package/lib/runtimeLayerCompatState.js.map +1 -1
- package/lib/storageServiceWithAttachBlobs.d.ts +0 -36
- package/lib/storageServiceWithAttachBlobs.d.ts.map +1 -1
- package/lib/storageServiceWithAttachBlobs.js +0 -55
- package/lib/storageServiceWithAttachBlobs.js.map +1 -1
- package/package.json +20 -17
- package/src/blobManager/blobManager.ts +0 -1
- package/src/containerRuntime.ts +47 -8
- package/src/dataStoreContext.ts +1 -0
- package/src/opLifecycle/outbox.ts +10 -0
- package/src/packageVersion.ts +1 -1
- package/src/runtimeLayerCompatState.ts +23 -39
- package/src/storageServiceWithAttachBlobs.ts +0 -92
package/src/containerRuntime.ts
CHANGED
|
@@ -1215,6 +1215,8 @@ export class ContainerRuntime
|
|
|
1215
1215
|
recentBatchInfo,
|
|
1216
1216
|
);
|
|
1217
1217
|
|
|
1218
|
+
runtime.sharePendingBlobs();
|
|
1219
|
+
|
|
1218
1220
|
// Initialize the base state of the runtime before it's returned.
|
|
1219
1221
|
await runtime.initializeBaseState(context.loader);
|
|
1220
1222
|
|
|
@@ -1581,13 +1583,6 @@ export class ContainerRuntime
|
|
|
1581
1583
|
|
|
1582
1584
|
this.isSnapshotInstanceOfISnapshot = snapshotWithContents !== undefined;
|
|
1583
1585
|
|
|
1584
|
-
// Validate that the Loader is compatible with this Runtime.
|
|
1585
|
-
const maybeLoaderCompatDetailsForRuntime = context as FluidObject<ILayerCompatDetails>;
|
|
1586
|
-
validateLoaderCompatibility(
|
|
1587
|
-
maybeLoaderCompatDetailsForRuntime.ILayerCompatDetails,
|
|
1588
|
-
this.disposeFn,
|
|
1589
|
-
);
|
|
1590
|
-
|
|
1591
1586
|
this.mc = createChildMonitoringContext({
|
|
1592
1587
|
logger: this.baseLogger,
|
|
1593
1588
|
namespace: "ContainerRuntime",
|
|
@@ -1598,6 +1593,14 @@ export class ContainerRuntime
|
|
|
1598
1593
|
},
|
|
1599
1594
|
});
|
|
1600
1595
|
|
|
1596
|
+
// Validate that the Loader is compatible with this Runtime.
|
|
1597
|
+
const maybeLoaderCompatDetailsForRuntime = context as FluidObject<ILayerCompatDetails>;
|
|
1598
|
+
validateLoaderCompatibility(
|
|
1599
|
+
maybeLoaderCompatDetailsForRuntime.ILayerCompatDetails,
|
|
1600
|
+
this.disposeFn,
|
|
1601
|
+
this.mc.logger,
|
|
1602
|
+
);
|
|
1603
|
+
|
|
1601
1604
|
// If we support multiple algorithms in the future, then we would need to manage it here carefully.
|
|
1602
1605
|
// We can use runtimeOptions.compressionOptions.compressionAlgorithm, but only if it's in the schema list!
|
|
1603
1606
|
// If it's not in the list, then we will need to either use no compression, or fallback to some other (supported by format)
|
|
@@ -4548,7 +4551,6 @@ export class ContainerRuntime
|
|
|
4548
4551
|
contents: any,
|
|
4549
4552
|
localOpMetadata: unknown = undefined,
|
|
4550
4553
|
): void {
|
|
4551
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
4552
4554
|
this.submit({ type, contents }, localOpMetadata);
|
|
4553
4555
|
}
|
|
4554
4556
|
|
|
@@ -5133,6 +5135,43 @@ export class ContainerRuntime
|
|
|
5133
5135
|
);
|
|
5134
5136
|
}
|
|
5135
5137
|
|
|
5138
|
+
/**
|
|
5139
|
+
* ContainerRuntime knows about additional restrictions on when blob sharing can be resumed as compared
|
|
5140
|
+
* to BlobManager. In particular, it wants to avoid sharing blobs while in readonly state, and it also
|
|
5141
|
+
* wants to avoid sharing blobs before connection completes (otherwise it may cause the sharing to happen
|
|
5142
|
+
* before processing shared ops).
|
|
5143
|
+
*
|
|
5144
|
+
* This method can be called safely before those conditions are met. In the background, it will wait until
|
|
5145
|
+
* it is safe before initiating sharing. It will close the container on any error.
|
|
5146
|
+
*/
|
|
5147
|
+
public sharePendingBlobs = (): void => {
|
|
5148
|
+
new Promise<void>((resolve) => {
|
|
5149
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
5150
|
+
const canStartSharing = (): boolean =>
|
|
5151
|
+
this.connected && this.deltaManager.readOnlyInfo.readonly !== true;
|
|
5152
|
+
|
|
5153
|
+
if (canStartSharing()) {
|
|
5154
|
+
resolve();
|
|
5155
|
+
return;
|
|
5156
|
+
}
|
|
5157
|
+
|
|
5158
|
+
const checkCanShare = (readonly: boolean): void => {
|
|
5159
|
+
if (canStartSharing()) {
|
|
5160
|
+
this.deltaManager.off("readonly", checkCanShare);
|
|
5161
|
+
this.off("connected", checkCanShare);
|
|
5162
|
+
resolve();
|
|
5163
|
+
}
|
|
5164
|
+
};
|
|
5165
|
+
this.deltaManager.on("readonly", checkCanShare);
|
|
5166
|
+
this.on("connected", checkCanShare);
|
|
5167
|
+
})
|
|
5168
|
+
.then(this.blobManager.sharePendingBlobs)
|
|
5169
|
+
// It may not be necessary to close the container on failures - this should just mean there's
|
|
5170
|
+
// a handle in the container that is stuck pending, which is a scenario that customers need to
|
|
5171
|
+
// handle anyway. Starting with this more aggressive/restrictive behavior to be cautious.
|
|
5172
|
+
.catch(this.closeFn);
|
|
5173
|
+
};
|
|
5174
|
+
|
|
5136
5175
|
public summarizeOnDemand(options: IOnDemandSummarizeOptions): ISummarizeResults {
|
|
5137
5176
|
if (this._summarizer !== undefined) {
|
|
5138
5177
|
return this._summarizer.summarizeOnDemand(options);
|
package/src/dataStoreContext.ts
CHANGED
|
@@ -365,6 +365,16 @@ export class Outbox {
|
|
|
365
365
|
* @param resubmitInfo - Key information when flushing a resubmitted batch. Undefined means this is not resubmit.
|
|
366
366
|
*/
|
|
367
367
|
public flush(resubmitInfo?: BatchResubmitInfo): void {
|
|
368
|
+
// We have nothing to flush if all batchManagers are empty, and we we're not needing to resubmit an empty batch placeholder
|
|
369
|
+
if (
|
|
370
|
+
this.idAllocationBatch.empty &&
|
|
371
|
+
this.blobAttachBatch.empty &&
|
|
372
|
+
this.mainBatch.empty &&
|
|
373
|
+
resubmitInfo?.batchId === undefined
|
|
374
|
+
) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
368
378
|
assert(
|
|
369
379
|
!this.isContextReentrant(),
|
|
370
380
|
0xb7b /* Flushing must not happen while incoming changes are being processed */,
|
package/src/packageVersion.ts
CHANGED
|
@@ -3,17 +3,19 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type ILayerCompatSupportRequirements,
|
|
6
|
+
import type {
|
|
7
|
+
ILayerCompatDetails,
|
|
8
|
+
ILayerCompatSupportRequirements,
|
|
10
9
|
} from "@fluid-internal/client-utils";
|
|
11
10
|
import type { ICriticalContainerError } from "@fluidframework/container-definitions";
|
|
12
11
|
import {
|
|
13
12
|
encodeHandlesInContainerRuntime,
|
|
14
13
|
notifiesReadOnlyState,
|
|
15
14
|
} from "@fluidframework/runtime-definitions/internal";
|
|
16
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
validateLayerCompatibility,
|
|
17
|
+
type ITelemetryLoggerExt,
|
|
18
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
17
19
|
|
|
18
20
|
import { pkgVersion } from "./packageVersion.js";
|
|
19
21
|
|
|
@@ -95,26 +97,17 @@ export const dataStoreSupportRequirementsForRuntime: ILayerCompatSupportRequirem
|
|
|
95
97
|
export function validateLoaderCompatibility(
|
|
96
98
|
maybeLoaderCompatDetailsForRuntime: ILayerCompatDetails | undefined,
|
|
97
99
|
disposeFn: (error?: ICriticalContainerError) => void,
|
|
100
|
+
logger: ITelemetryLoggerExt,
|
|
98
101
|
): void {
|
|
99
|
-
|
|
102
|
+
validateLayerCompatibility(
|
|
103
|
+
"runtime",
|
|
104
|
+
"loader",
|
|
105
|
+
runtimeCompatDetailsForLoader,
|
|
100
106
|
loaderSupportRequirementsForRuntime,
|
|
101
107
|
maybeLoaderCompatDetailsForRuntime,
|
|
108
|
+
disposeFn,
|
|
109
|
+
logger,
|
|
102
110
|
);
|
|
103
|
-
if (!layerCheckResult.isCompatible) {
|
|
104
|
-
const error = new UsageError("Runtime is not compatible with Loader", {
|
|
105
|
-
errorDetails: JSON.stringify({
|
|
106
|
-
runtimeVersion: runtimeCoreCompatDetails.pkgVersion,
|
|
107
|
-
loaderVersion: maybeLoaderCompatDetailsForRuntime?.pkgVersion,
|
|
108
|
-
runtimeGeneration: runtimeCoreCompatDetails.generation,
|
|
109
|
-
loaderGeneration: maybeLoaderCompatDetailsForRuntime?.generation,
|
|
110
|
-
minSupportedGeneration: loaderSupportRequirementsForRuntime.minSupportedGeneration,
|
|
111
|
-
isGenerationCompatible: layerCheckResult.isGenerationCompatible,
|
|
112
|
-
unsupportedFeatures: layerCheckResult.unsupportedFeatures,
|
|
113
|
-
}),
|
|
114
|
-
});
|
|
115
|
-
disposeFn(error);
|
|
116
|
-
throw error;
|
|
117
|
-
}
|
|
118
111
|
}
|
|
119
112
|
|
|
120
113
|
/**
|
|
@@ -122,26 +115,17 @@ export function validateLoaderCompatibility(
|
|
|
122
115
|
* @internal
|
|
123
116
|
*/
|
|
124
117
|
export function validateDatastoreCompatibility(
|
|
125
|
-
|
|
118
|
+
maybeDataStoreCompatDetailsForRuntime: ILayerCompatDetails | undefined,
|
|
126
119
|
disposeFn: () => void,
|
|
120
|
+
logger: ITelemetryLoggerExt,
|
|
127
121
|
): void {
|
|
128
|
-
|
|
122
|
+
validateLayerCompatibility(
|
|
123
|
+
"runtime",
|
|
124
|
+
"dataStore",
|
|
125
|
+
runtimeCompatDetailsForDataStore,
|
|
129
126
|
dataStoreSupportRequirementsForRuntime,
|
|
130
|
-
|
|
127
|
+
maybeDataStoreCompatDetailsForRuntime,
|
|
128
|
+
disposeFn,
|
|
129
|
+
logger,
|
|
131
130
|
);
|
|
132
|
-
if (!layerCheckResult.isCompatible) {
|
|
133
|
-
const error = new UsageError("Runtime is not compatible with DataStore", {
|
|
134
|
-
errorDetails: JSON.stringify({
|
|
135
|
-
runtimeVersion: runtimeCoreCompatDetails.pkgVersion,
|
|
136
|
-
dataStoreVersion: maybeDataStoreCompatDetails?.pkgVersion,
|
|
137
|
-
runtimeGeneration: runtimeCoreCompatDetails.generation,
|
|
138
|
-
dataStoreGeneration: maybeDataStoreCompatDetails?.generation,
|
|
139
|
-
minSupportedGeneration: dataStoreSupportRequirementsForRuntime.minSupportedGeneration,
|
|
140
|
-
isGenerationCompatible: layerCheckResult.isGenerationCompatible,
|
|
141
|
-
unsupportedFeatures: layerCheckResult.unsupportedFeatures,
|
|
142
|
-
}),
|
|
143
|
-
});
|
|
144
|
-
disposeFn();
|
|
145
|
-
throw error;
|
|
146
|
-
}
|
|
147
131
|
}
|
|
@@ -3,20 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
7
|
-
FetchSource,
|
|
8
|
-
ICreateBlobResponse,
|
|
9
|
-
IDocumentStorageServicePolicies,
|
|
10
|
-
ISnapshot,
|
|
11
|
-
ISnapshotFetchOptions,
|
|
12
|
-
ISnapshotTree,
|
|
13
|
-
ISummaryContext,
|
|
14
|
-
ISummaryHandle,
|
|
15
|
-
ISummaryTree,
|
|
16
|
-
IVersion,
|
|
17
|
-
} from "@fluidframework/driver-definitions/internal";
|
|
18
6
|
import type { IRuntimeStorageService } from "@fluidframework/runtime-definitions/internal";
|
|
19
|
-
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
20
7
|
|
|
21
8
|
/**
|
|
22
9
|
* IRuntimeStorageService proxy which intercepts requests if they can be satisfied by the blobs received in the
|
|
@@ -28,14 +15,6 @@ export class StorageServiceWithAttachBlobs implements IRuntimeStorageService {
|
|
|
28
15
|
private readonly attachBlobs: Map<string, ArrayBufferLike>,
|
|
29
16
|
) {}
|
|
30
17
|
|
|
31
|
-
/**
|
|
32
|
-
* {@link IRuntimeStorageService.policies}.
|
|
33
|
-
* @deprecated This will be removed in a future release. The DataStore layer does not need this.
|
|
34
|
-
*/
|
|
35
|
-
public get policies(): IDocumentStorageServicePolicies | undefined {
|
|
36
|
-
return this.internalStorageService.policies;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
18
|
public async readBlob(id: string): Promise<ArrayBufferLike> {
|
|
40
19
|
const blob = this.attachBlobs.get(id);
|
|
41
20
|
if (blob !== undefined) {
|
|
@@ -46,75 +25,4 @@ export class StorageServiceWithAttachBlobs implements IRuntimeStorageService {
|
|
|
46
25
|
// IRuntimeStorageService to cache appropriately, no need to double-cache.
|
|
47
26
|
return this.internalStorageService.readBlob(id);
|
|
48
27
|
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* {@link IRuntimeStorageService.getSnapshotTree}.
|
|
52
|
-
* @deprecated This will be removed in a future release. The DataStore layer does not need this.
|
|
53
|
-
*/
|
|
54
|
-
public async getSnapshotTree(
|
|
55
|
-
version?: IVersion,
|
|
56
|
-
scenarioName?: string,
|
|
57
|
-
// eslint-disable-next-line @rushstack/no-new-null
|
|
58
|
-
): Promise<ISnapshotTree | null> {
|
|
59
|
-
return this.internalStorageService.getSnapshotTree(version, scenarioName);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* {@link IRuntimeStorageService.getSnapshot}.
|
|
64
|
-
* @deprecated This will be removed in a future release. The DataStore layer does not need this.
|
|
65
|
-
*/
|
|
66
|
-
public async getSnapshot(snapshotFetchOptions?: ISnapshotFetchOptions): Promise<ISnapshot> {
|
|
67
|
-
if (this.internalStorageService.getSnapshot !== undefined) {
|
|
68
|
-
return this.internalStorageService.getSnapshot(snapshotFetchOptions);
|
|
69
|
-
}
|
|
70
|
-
throw new UsageError(
|
|
71
|
-
"getSnapshot api should exist on internal storage in documentStorageServiceProxy class",
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* {@link IRuntimeStorageService.getVersions}.
|
|
77
|
-
* @deprecated This will be removed in a future release. The DataStore layer does not need this.
|
|
78
|
-
*/
|
|
79
|
-
public async getVersions(
|
|
80
|
-
// eslint-disable-next-line @rushstack/no-new-null
|
|
81
|
-
versionId: string | null,
|
|
82
|
-
count: number,
|
|
83
|
-
scenarioName?: string,
|
|
84
|
-
fetchSource?: FetchSource,
|
|
85
|
-
): Promise<IVersion[]> {
|
|
86
|
-
return this.internalStorageService.getVersions(
|
|
87
|
-
versionId,
|
|
88
|
-
count,
|
|
89
|
-
scenarioName,
|
|
90
|
-
fetchSource,
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* {@link IRuntimeStorageService.uploadSummaryWithContext}.
|
|
96
|
-
* @deprecated This will be removed in a future release. The DataStore layer does not need this.
|
|
97
|
-
*/
|
|
98
|
-
public async uploadSummaryWithContext(
|
|
99
|
-
summary: ISummaryTree,
|
|
100
|
-
context: ISummaryContext,
|
|
101
|
-
): Promise<string> {
|
|
102
|
-
return this.internalStorageService.uploadSummaryWithContext(summary, context);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* {@link IRuntimeStorageService.createBlob}.
|
|
107
|
-
* @deprecated This will be removed in a future release. The DataStore layer does not need this.
|
|
108
|
-
*/
|
|
109
|
-
public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {
|
|
110
|
-
return this.internalStorageService.createBlob(file);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* {@link IRuntimeStorageService.downloadSummary}.
|
|
115
|
-
* @deprecated This will be removed in a future release. The DataStore layer does not need this.
|
|
116
|
-
*/
|
|
117
|
-
public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {
|
|
118
|
-
return this.internalStorageService.downloadSummary(handle);
|
|
119
|
-
}
|
|
120
28
|
}
|