@fluidframework/sequence 2.0.0-dev-rc.1.0.0.228517 → 2.0.0-dev-rc.1.0.0.232845
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/sequence.api.md +1 -0
- package/dist/intervalCollection.d.ts +13 -0
- package/dist/intervalCollection.d.ts.map +1 -1
- package/dist/intervalCollection.js +10 -2
- package/dist/intervalCollection.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/sequence-alpha.d.ts +23 -0
- package/dist/sequence-untrimmed.d.ts +23 -0
- package/dist/sequence.d.ts +10 -0
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +32 -2
- package/dist/sequence.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/intervalCollection.d.mts +13 -0
- package/lib/intervalCollection.d.mts.map +1 -1
- package/lib/intervalCollection.mjs +10 -2
- package/lib/intervalCollection.mjs.map +1 -1
- package/lib/packageVersion.d.mts +1 -1
- package/lib/packageVersion.mjs +1 -1
- package/lib/packageVersion.mjs.map +1 -1
- package/lib/sequence-alpha.d.mts +23 -0
- package/lib/sequence-untrimmed.d.mts +23 -0
- package/lib/sequence.d.mts +10 -0
- package/lib/sequence.d.mts.map +1 -1
- package/lib/sequence.mjs +29 -2
- package/lib/sequence.mjs.map +1 -1
- package/package.json +19 -17
- package/src/intervalCollection.ts +40 -2
- package/src/packageVersion.ts +1 -1
- package/src/sequence.ts +33 -1
- /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
package/src/sequence.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import Deque from "double-ended-queue";
|
|
6
7
|
import { assert, Deferred } from "@fluidframework/core-utils";
|
|
7
8
|
import { bufferToString } from "@fluid-internal/client-utils";
|
|
8
9
|
import { LoggingError, createChildLogger } from "@fluidframework/telemetry-utils";
|
|
@@ -212,6 +213,17 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
212
213
|
return ops;
|
|
213
214
|
}
|
|
214
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Note: this field only provides a lower-bound on the reference sequence numbers for in-flight ops.
|
|
218
|
+
* The exact reason isn't understood, but some e2e tests suggest that the runtime may sometimes process
|
|
219
|
+
* incoming leave/join ops before putting an op that this DDS submits over the wire.
|
|
220
|
+
*
|
|
221
|
+
* E.g. SharedString submits an op while deltaManager has lastSequenceNumber = 10, but before the runtime
|
|
222
|
+
* puts this op over the wire, it processes a client join/leave op with sequence number 11, so the referenceSequenceNumber
|
|
223
|
+
* on the SharedString op is 11.
|
|
224
|
+
*/
|
|
225
|
+
private readonly inFlightRefSeqs = new Deque<number>();
|
|
226
|
+
|
|
215
227
|
// eslint-disable-next-line import/no-deprecated
|
|
216
228
|
protected client: Client;
|
|
217
229
|
/** `Deferred` that triggers once the object is loaded */
|
|
@@ -233,6 +245,7 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
233
245
|
) {
|
|
234
246
|
super(id, dataStoreRuntime, attributes, "fluid_sequence_");
|
|
235
247
|
|
|
248
|
+
const getMinInFlightRefSeq = () => this.inFlightRefSeqs.get(0);
|
|
236
249
|
this.guardReentrancy =
|
|
237
250
|
dataStoreRuntime.options.sharedStringPreventReentrancy ?? true
|
|
238
251
|
? ensureNoReentrancy
|
|
@@ -258,6 +271,7 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
258
271
|
namespace: "SharedSegmentSequence.MergeTreeClient",
|
|
259
272
|
}),
|
|
260
273
|
dataStoreRuntime.options,
|
|
274
|
+
getMinInFlightRefSeq,
|
|
261
275
|
);
|
|
262
276
|
|
|
263
277
|
this.client.prependListener("delta", (opArgs, deltaArgs) => {
|
|
@@ -275,7 +289,14 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
275
289
|
this.intervalCollections = new DefaultMap(
|
|
276
290
|
this.serializer,
|
|
277
291
|
this.handle,
|
|
278
|
-
(op, localOpMetadata) =>
|
|
292
|
+
(op, localOpMetadata) => {
|
|
293
|
+
if (!this.isAttached()) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
this.inFlightRefSeqs.push(this.runtime.deltaManager.lastSequenceNumber);
|
|
298
|
+
this.submitLocalMessage(op, localOpMetadata);
|
|
299
|
+
},
|
|
279
300
|
new SequenceIntervalCollectionValueType(),
|
|
280
301
|
dataStoreRuntime.options,
|
|
281
302
|
);
|
|
@@ -427,6 +448,8 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
427
448
|
if (!this.isAttached()) {
|
|
428
449
|
return;
|
|
429
450
|
}
|
|
451
|
+
|
|
452
|
+
this.inFlightRefSeqs.push(this.runtime.deltaManager.lastSequenceNumber);
|
|
430
453
|
const translated = makeHandlesSerializable(message, this.serializer, this.handle);
|
|
431
454
|
const metadata = this.client.peekPendingSegmentGroups(
|
|
432
455
|
message.type === MergeTreeDeltaType.GROUP ? message.ops.length : 1,
|
|
@@ -596,6 +619,8 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
596
619
|
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}
|
|
597
620
|
*/
|
|
598
621
|
protected reSubmitCore(content: any, localOpMetadata: unknown) {
|
|
622
|
+
const originalRefSeq = this.inFlightRefSeqs.shift();
|
|
623
|
+
assert(originalRefSeq !== undefined, "Expected a recorded refSeq when resubmitting an op");
|
|
599
624
|
if (
|
|
600
625
|
!this.intervalCollections.tryResubmitMessage(
|
|
601
626
|
content,
|
|
@@ -683,6 +708,12 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
683
708
|
local: boolean,
|
|
684
709
|
localOpMetadata: unknown,
|
|
685
710
|
) {
|
|
711
|
+
if (local) {
|
|
712
|
+
const recordedRefSeq = this.inFlightRefSeqs.shift();
|
|
713
|
+
assert(recordedRefSeq !== undefined, "No pending recorded refSeq found");
|
|
714
|
+
assert(recordedRefSeq <= message.referenceSequenceNumber, "RefSeq mismatch");
|
|
715
|
+
}
|
|
716
|
+
|
|
686
717
|
// if loading isn't complete, we need to cache all
|
|
687
718
|
// incoming ops to be applied after loading is complete
|
|
688
719
|
if (this.deferIncomingOps) {
|
|
@@ -730,6 +761,7 @@ export abstract class SharedSegmentSequence<T extends ISegment>
|
|
|
730
761
|
* {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}
|
|
731
762
|
*/
|
|
732
763
|
protected applyStashedOp(content: any): unknown {
|
|
764
|
+
this.inFlightRefSeqs.push(this.runtime.deltaManager.lastSequenceNumber);
|
|
733
765
|
const parsedContent = parseHandles(content, this.serializer);
|
|
734
766
|
const metadata =
|
|
735
767
|
this.intervalCollections.tryGetStashedOpLocalMetadata(parsedContent) ??
|
|
File without changes
|