@fluidframework/container-runtime 2.43.0-343119 → 2.50.0-345060
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 +4 -0
- package/container-runtime.test-files.tar +0 -0
- package/dist/channelCollection.d.ts +1 -1
- package/dist/channelCollection.d.ts.map +1 -1
- package/dist/channelCollection.js +3 -1
- package/dist/channelCollection.js.map +1 -1
- package/dist/containerRuntime.d.ts +1 -1
- package/dist/containerRuntime.d.ts.map +1 -1
- package/dist/containerRuntime.js +18 -17
- package/dist/containerRuntime.js.map +1 -1
- package/dist/dataStoreContext.d.ts +0 -2
- package/dist/dataStoreContext.d.ts.map +1 -1
- package/dist/dataStoreContext.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/opLifecycle/batchManager.d.ts +1 -0
- package/dist/opLifecycle/batchManager.d.ts.map +1 -1
- package/dist/opLifecycle/batchManager.js +3 -2
- package/dist/opLifecycle/batchManager.js.map +1 -1
- package/dist/opLifecycle/index.d.ts +1 -1
- package/dist/opLifecycle/index.d.ts.map +1 -1
- package/dist/opLifecycle/index.js +2 -1
- package/dist/opLifecycle/index.js.map +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts +1 -1
- package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/dist/opLifecycle/opGroupingManager.js.map +1 -1
- package/dist/opLifecycle/outbox.d.ts.map +1 -1
- package/dist/opLifecycle/outbox.js +2 -5
- 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/pendingStateManager.d.ts +7 -6
- package/dist/pendingStateManager.d.ts.map +1 -1
- package/dist/pendingStateManager.js +20 -15
- package/dist/pendingStateManager.js.map +1 -1
- package/dist/runtimeLayerCompatState.d.ts +3 -3
- package/dist/runtimeLayerCompatState.d.ts.map +1 -1
- package/dist/runtimeLayerCompatState.js +10 -10
- package/dist/runtimeLayerCompatState.js.map +1 -1
- package/lib/channelCollection.d.ts +1 -1
- package/lib/channelCollection.d.ts.map +1 -1
- package/lib/channelCollection.js +3 -1
- package/lib/channelCollection.js.map +1 -1
- package/lib/containerRuntime.d.ts +1 -1
- package/lib/containerRuntime.d.ts.map +1 -1
- package/lib/containerRuntime.js +18 -17
- package/lib/containerRuntime.js.map +1 -1
- package/lib/dataStoreContext.d.ts +0 -2
- package/lib/dataStoreContext.d.ts.map +1 -1
- package/lib/dataStoreContext.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/opLifecycle/batchManager.d.ts +1 -0
- package/lib/opLifecycle/batchManager.d.ts.map +1 -1
- package/lib/opLifecycle/batchManager.js +1 -1
- package/lib/opLifecycle/batchManager.js.map +1 -1
- package/lib/opLifecycle/index.d.ts +1 -1
- package/lib/opLifecycle/index.d.ts.map +1 -1
- package/lib/opLifecycle/index.js +1 -1
- package/lib/opLifecycle/index.js.map +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts +1 -1
- package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
- package/lib/opLifecycle/opGroupingManager.js.map +1 -1
- package/lib/opLifecycle/outbox.d.ts.map +1 -1
- package/lib/opLifecycle/outbox.js +2 -5
- 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/pendingStateManager.d.ts +7 -6
- package/lib/pendingStateManager.d.ts.map +1 -1
- package/lib/pendingStateManager.js +20 -15
- package/lib/pendingStateManager.js.map +1 -1
- package/lib/runtimeLayerCompatState.d.ts +3 -3
- package/lib/runtimeLayerCompatState.d.ts.map +1 -1
- package/lib/runtimeLayerCompatState.js +9 -9
- package/lib/runtimeLayerCompatState.js.map +1 -1
- package/package.json +20 -20
- package/src/channelCollection.ts +3 -1
- package/src/containerRuntime.ts +24 -28
- package/src/dataStoreContext.ts +0 -2
- package/src/index.ts +7 -0
- package/src/opLifecycle/batchManager.ts +1 -1
- package/src/opLifecycle/index.ts +1 -0
- package/src/opLifecycle/opGroupingManager.ts +1 -1
- package/src/opLifecycle/outbox.ts +2 -5
- package/src/packageVersion.ts +1 -1
- package/src/pendingStateManager.ts +30 -22
- package/src/runtimeLayerCompatState.ts +10 -10
package/src/index.ts
CHANGED
|
@@ -112,3 +112,10 @@ export {
|
|
|
112
112
|
DefaultSummaryConfiguration,
|
|
113
113
|
} from "./summary/index.js";
|
|
114
114
|
export { IChunkedOp, unpackRuntimeMessage } from "./opLifecycle/index.js";
|
|
115
|
+
export {
|
|
116
|
+
runtimeCoreCompatDetails,
|
|
117
|
+
runtimeCompatDetailsForLoader,
|
|
118
|
+
runtimeCompatDetailsForDataStore,
|
|
119
|
+
loaderSupportRequirementsForRuntime,
|
|
120
|
+
dataStoreSupportRequirementsForRuntime,
|
|
121
|
+
} from "./runtimeLayerCompatState.js";
|
|
@@ -178,7 +178,7 @@ export class BatchManager {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
const addBatchMetadata = (batch: LocalBatch, batchId?: BatchId): LocalBatch => {
|
|
181
|
+
export const addBatchMetadata = (batch: LocalBatch, batchId?: BatchId): LocalBatch => {
|
|
182
182
|
const batchEnd = batch.messages.length - 1;
|
|
183
183
|
|
|
184
184
|
const firstMsg = batch.messages[0];
|
package/src/opLifecycle/index.ts
CHANGED
|
@@ -455,10 +455,7 @@ export class Outbox {
|
|
|
455
455
|
if (
|
|
456
456
|
batchManager.options.canRebase &&
|
|
457
457
|
rawBatch.hasReentrantOps === true &&
|
|
458
|
-
|
|
459
|
-
// However there is some test that is depending on this behavior so we haven't removed these conditions yet. See AB#33427
|
|
460
|
-
groupingEnabled &&
|
|
461
|
-
rawBatch.messages.length > 1
|
|
458
|
+
groupingEnabled
|
|
462
459
|
) {
|
|
463
460
|
assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
|
|
464
461
|
// If a batch contains reentrant ops (ops created as a result from processing another op)
|
|
@@ -466,7 +463,7 @@ export class Outbox {
|
|
|
466
463
|
// and eventual consistency at the DDS level.
|
|
467
464
|
// Note: Since this is happening in the same turn the ops were originally created with,
|
|
468
465
|
// and they haven't gone to PendingStateManager yet, we can just let them respect
|
|
469
|
-
// ContainerRuntime.inStagingMode
|
|
466
|
+
// ContainerRuntime.inStagingMode. So we do not plumb local 'staged' variable through here.
|
|
470
467
|
this.rebase(rawBatch, batchManager);
|
|
471
468
|
return;
|
|
472
469
|
}
|
package/src/packageVersion.ts
CHANGED
|
@@ -48,9 +48,9 @@ export interface IPendingMessage {
|
|
|
48
48
|
content: string;
|
|
49
49
|
/**
|
|
50
50
|
* The original runtime op that was submitted to the ContainerRuntime
|
|
51
|
-
* Unless this pending message came from stashed content, in which case this
|
|
51
|
+
* Unless this pending message came from stashed content, in which case this is undefined at first and then deserialized from the contents string
|
|
52
52
|
*/
|
|
53
|
-
runtimeOp
|
|
53
|
+
runtimeOp: LocalContainerRuntimeMessage | EmptyGroupedBatch | undefined; // Undefined for initial messages before parsing
|
|
54
54
|
/**
|
|
55
55
|
* Local Op Metadata that was passed to the ContainerRuntime when the op was submitted.
|
|
56
56
|
* This contains state needed when processing the ack, or to resubmit or rollback the op.
|
|
@@ -234,10 +234,11 @@ function toSerializableForm(
|
|
|
234
234
|
|
|
235
235
|
interface ReplayPendingStateOptions {
|
|
236
236
|
/**
|
|
237
|
-
* If true, only replay staged batches
|
|
237
|
+
* If true, only replay staged batches, clearing the "staged" flag.
|
|
238
|
+
* This is used when we are exiting staging mode and want to rebase and submit the staged batches without resubmitting pre-staged messages.
|
|
238
239
|
* Default: false
|
|
239
240
|
*/
|
|
240
|
-
|
|
241
|
+
committingStagedBatches: boolean;
|
|
241
242
|
/**
|
|
242
243
|
* @param squash - If true, edits should be squashed when resubmitting.
|
|
243
244
|
* Default: false
|
|
@@ -246,7 +247,7 @@ interface ReplayPendingStateOptions {
|
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
const defaultReplayPendingStatesOptions: ReplayPendingStateOptions = {
|
|
249
|
-
|
|
250
|
+
committingStagedBatches: false,
|
|
250
251
|
squash: false,
|
|
251
252
|
};
|
|
252
253
|
|
|
@@ -300,8 +301,8 @@ export class PendingStateManager implements IDisposable {
|
|
|
300
301
|
for (let i = 0; i < this.pendingMessages.length; i++) {
|
|
301
302
|
const element = this.pendingMessages.get(i);
|
|
302
303
|
if (
|
|
303
|
-
element
|
|
304
|
-
|
|
304
|
+
element !== undefined &&
|
|
305
|
+
hasTypicalRuntimeOp(element) && // Empty batches don't count towards user changes
|
|
305
306
|
isContainerMessageDirtyable(element.runtimeOp)
|
|
306
307
|
) {
|
|
307
308
|
return true;
|
|
@@ -742,16 +743,18 @@ export class PendingStateManager implements IDisposable {
|
|
|
742
743
|
* states in its queue. This includes triggering resubmission of unacked ops.
|
|
743
744
|
* ! Note: successfully resubmitting an op that has been successfully sequenced is not possible due to checks in the ConnectionStateHandler (Loader layer)
|
|
744
745
|
*/
|
|
745
|
-
public replayPendingStates(
|
|
746
|
-
const
|
|
747
|
-
|
|
746
|
+
public replayPendingStates(options?: ReplayPendingStateOptions): void {
|
|
747
|
+
const { committingStagedBatches, squash } = {
|
|
748
|
+
...defaultReplayPendingStatesOptions,
|
|
749
|
+
...options,
|
|
750
|
+
};
|
|
748
751
|
assert(
|
|
749
|
-
this.stateHandler.connected() ||
|
|
752
|
+
this.stateHandler.connected() || committingStagedBatches === true,
|
|
750
753
|
0x172 /* "The connection state is not consistent with the runtime" */,
|
|
751
754
|
);
|
|
752
755
|
|
|
753
756
|
// Staged batches have not yet been submitted so check doesn't apply
|
|
754
|
-
if (!
|
|
757
|
+
if (!committingStagedBatches) {
|
|
755
758
|
// This assert suggests we are about to send same ops twice, which will result in data loss.
|
|
756
759
|
assert(
|
|
757
760
|
this.clientIdFromLastReplay !== this.stateHandler.clientId(),
|
|
@@ -778,8 +781,8 @@ export class PendingStateManager implements IDisposable {
|
|
|
778
781
|
let pendingMessage = this.pendingMessages.shift()!;
|
|
779
782
|
remainingPendingMessagesCount--;
|
|
780
783
|
|
|
781
|
-
// Re-queue pre-staging messages
|
|
782
|
-
if (
|
|
784
|
+
// Re-queue pre-staging messages - we are only to replay staged batches
|
|
785
|
+
if (committingStagedBatches) {
|
|
783
786
|
if (!pendingMessage.batchInfo.staged) {
|
|
784
787
|
assert(!seenStagedBatch, 0xb86 /* Staged batch was followed by non-staged batch */);
|
|
785
788
|
this.pendingMessages.push(pendingMessage);
|
|
@@ -807,8 +810,8 @@ export class PendingStateManager implements IDisposable {
|
|
|
807
810
|
}
|
|
808
811
|
|
|
809
812
|
assert(
|
|
810
|
-
|
|
811
|
-
0xb87 /*
|
|
813
|
+
hasTypicalRuntimeOp(pendingMessage),
|
|
814
|
+
0xb87 /* runtimeOp is only undefined for empty batches */,
|
|
812
815
|
);
|
|
813
816
|
|
|
814
817
|
/**
|
|
@@ -843,8 +846,8 @@ export class PendingStateManager implements IDisposable {
|
|
|
843
846
|
// check is >= because batch end may be last pending message
|
|
844
847
|
while (remainingPendingMessagesCount >= 0) {
|
|
845
848
|
assert(
|
|
846
|
-
|
|
847
|
-
0xb88 /*
|
|
849
|
+
hasTypicalRuntimeOp(pendingMessage),
|
|
850
|
+
0xb88 /* runtimeOp is only undefined for empty batches */,
|
|
848
851
|
);
|
|
849
852
|
batch.push({
|
|
850
853
|
runtimeOp: pendingMessage.runtimeOp,
|
|
@@ -890,15 +893,17 @@ export class PendingStateManager implements IDisposable {
|
|
|
890
893
|
*/
|
|
891
894
|
public popStagedBatches(
|
|
892
895
|
callback: (
|
|
893
|
-
|
|
896
|
+
// callback will only be given staged messages with a valid runtime op (i.e. not empty batch and not an initial message with only serialized content)
|
|
897
|
+
stagedMessage: IPendingMessage & { runtimeOp: LocalContainerRuntimeMessage },
|
|
894
898
|
) => void,
|
|
895
899
|
): void {
|
|
896
900
|
while (!this.pendingMessages.isEmpty()) {
|
|
897
901
|
const stagedMessage = this.pendingMessages.peekBack();
|
|
898
902
|
if (stagedMessage?.batchInfo.staged === true) {
|
|
899
|
-
|
|
903
|
+
this.pendingMessages.pop();
|
|
904
|
+
|
|
905
|
+
if (hasTypicalRuntimeOp(stagedMessage)) {
|
|
900
906
|
callback(stagedMessage);
|
|
901
|
-
this.pendingMessages.pop();
|
|
902
907
|
}
|
|
903
908
|
} else {
|
|
904
909
|
break; // no more staged messages
|
|
@@ -924,7 +929,10 @@ function patchbatchInfo(
|
|
|
924
929
|
}
|
|
925
930
|
}
|
|
926
931
|
|
|
927
|
-
|
|
932
|
+
/**
|
|
933
|
+
* This filters out messages that are not "typical" runtime ops, i.e. empty batches or initial messages (which only have serialized content).
|
|
934
|
+
*/
|
|
935
|
+
function hasTypicalRuntimeOp(
|
|
928
936
|
message: IPendingMessage,
|
|
929
937
|
): message is IPendingMessage & { runtimeOp: LocalContainerRuntimeMessage } {
|
|
930
938
|
return message.runtimeOp !== undefined && message.runtimeOp.type !== "groupedBatch";
|
|
@@ -48,7 +48,7 @@ export const runtimeCompatDetailsForLoader: ILayerCompatDetails = {
|
|
|
48
48
|
* The requirements that the Loader layer must meet to be compatible with this Runtime.
|
|
49
49
|
* @internal
|
|
50
50
|
*/
|
|
51
|
-
export const
|
|
51
|
+
export const loaderSupportRequirementsForRuntime: ILayerCompatSupportRequirements = {
|
|
52
52
|
/**
|
|
53
53
|
* Minimum generation that Loader must be at to be compatible with Runtime. Note that 0 is used here so
|
|
54
54
|
* that Loader layers before the introduction of the layer compatibility enforcement are compatible.
|
|
@@ -76,7 +76,7 @@ export const runtimeCompatDetailsForDataStore: ILayerCompatDetails = {
|
|
|
76
76
|
* The requirements that the DataStore layer must meet to be compatible with this Runtime.
|
|
77
77
|
* @internal
|
|
78
78
|
*/
|
|
79
|
-
export const
|
|
79
|
+
export const dataStoreSupportRequirementsForRuntime: ILayerCompatSupportRequirements = {
|
|
80
80
|
/**
|
|
81
81
|
* Minimum generation that DataStore must be at to be compatible with Runtime. Note that 0 is used here so
|
|
82
82
|
* that DataStore layers before the introduction of the layer compatibility enforcement are compatible.
|
|
@@ -93,21 +93,21 @@ export const dataStoreSupportRequirements: ILayerCompatSupportRequirements = {
|
|
|
93
93
|
* @internal
|
|
94
94
|
*/
|
|
95
95
|
export function validateLoaderCompatibility(
|
|
96
|
-
|
|
96
|
+
maybeLoaderCompatDetailsForRuntime: ILayerCompatDetails | undefined,
|
|
97
97
|
disposeFn: (error?: ICriticalContainerError) => void,
|
|
98
98
|
): void {
|
|
99
99
|
const layerCheckResult = checkLayerCompatibility(
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
loaderSupportRequirementsForRuntime,
|
|
101
|
+
maybeLoaderCompatDetailsForRuntime,
|
|
102
102
|
);
|
|
103
103
|
if (!layerCheckResult.isCompatible) {
|
|
104
104
|
const error = new UsageError("Runtime is not compatible with Loader", {
|
|
105
105
|
errorDetails: JSON.stringify({
|
|
106
106
|
runtimeVersion: runtimeCoreCompatDetails.pkgVersion,
|
|
107
|
-
loaderVersion:
|
|
107
|
+
loaderVersion: maybeLoaderCompatDetailsForRuntime?.pkgVersion,
|
|
108
108
|
runtimeGeneration: runtimeCoreCompatDetails.generation,
|
|
109
|
-
loaderGeneration:
|
|
110
|
-
minSupportedGeneration:
|
|
109
|
+
loaderGeneration: maybeLoaderCompatDetailsForRuntime?.generation,
|
|
110
|
+
minSupportedGeneration: loaderSupportRequirementsForRuntime.minSupportedGeneration,
|
|
111
111
|
isGenerationCompatible: layerCheckResult.isGenerationCompatible,
|
|
112
112
|
unsupportedFeatures: layerCheckResult.unsupportedFeatures,
|
|
113
113
|
}),
|
|
@@ -126,7 +126,7 @@ export function validateDatastoreCompatibility(
|
|
|
126
126
|
disposeFn: () => void,
|
|
127
127
|
): void {
|
|
128
128
|
const layerCheckResult = checkLayerCompatibility(
|
|
129
|
-
|
|
129
|
+
dataStoreSupportRequirementsForRuntime,
|
|
130
130
|
maybeDataStoreCompatDetails,
|
|
131
131
|
);
|
|
132
132
|
if (!layerCheckResult.isCompatible) {
|
|
@@ -136,7 +136,7 @@ export function validateDatastoreCompatibility(
|
|
|
136
136
|
dataStoreVersion: maybeDataStoreCompatDetails?.pkgVersion,
|
|
137
137
|
runtimeGeneration: runtimeCoreCompatDetails.generation,
|
|
138
138
|
dataStoreGeneration: maybeDataStoreCompatDetails?.generation,
|
|
139
|
-
minSupportedGeneration:
|
|
139
|
+
minSupportedGeneration: dataStoreSupportRequirementsForRuntime.minSupportedGeneration,
|
|
140
140
|
isGenerationCompatible: layerCheckResult.isGenerationCompatible,
|
|
141
141
|
unsupportedFeatures: layerCheckResult.unsupportedFeatures,
|
|
142
142
|
}),
|