@fluidframework/container-runtime 2.4.0 → 2.5.0

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.
Files changed (95) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/api-report/container-runtime.legacy.alpha.api.md +3 -1
  3. package/container-runtime.test-files.tar +0 -0
  4. package/dist/blobManager/blobManager.d.ts +3 -3
  5. package/dist/blobManager/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager/blobManager.js +1 -1
  7. package/dist/blobManager/blobManager.js.map +1 -1
  8. package/dist/channelCollection.d.ts +20 -5
  9. package/dist/channelCollection.d.ts.map +1 -1
  10. package/dist/channelCollection.js +183 -119
  11. package/dist/channelCollection.js.map +1 -1
  12. package/dist/containerRuntime.d.ts +12 -4
  13. package/dist/containerRuntime.d.ts.map +1 -1
  14. package/dist/containerRuntime.js +155 -66
  15. package/dist/containerRuntime.js.map +1 -1
  16. package/dist/dataStoreContext.d.ts +15 -3
  17. package/dist/dataStoreContext.d.ts.map +1 -1
  18. package/dist/dataStoreContext.js +48 -19
  19. package/dist/dataStoreContext.js.map +1 -1
  20. package/dist/gc/garbageCollection.d.ts +5 -6
  21. package/dist/gc/garbageCollection.d.ts.map +1 -1
  22. package/dist/gc/garbageCollection.js +23 -22
  23. package/dist/gc/garbageCollection.js.map +1 -1
  24. package/dist/gc/gcDefinitions.d.ts +2 -2
  25. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  26. package/dist/gc/gcDefinitions.js.map +1 -1
  27. package/dist/opLifecycle/outbox.d.ts +3 -0
  28. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  29. package/dist/opLifecycle/outbox.js +9 -0
  30. package/dist/opLifecycle/outbox.js.map +1 -1
  31. package/dist/opLifecycle/remoteMessageProcessor.d.ts +1 -0
  32. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  33. package/dist/opLifecycle/remoteMessageProcessor.js +2 -0
  34. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  35. package/dist/opProperties.js +1 -1
  36. package/dist/opProperties.js.map +1 -1
  37. package/dist/packageVersion.d.ts +1 -1
  38. package/dist/packageVersion.js +1 -1
  39. package/dist/packageVersion.js.map +1 -1
  40. package/dist/summary/documentSchema.d.ts +11 -0
  41. package/dist/summary/documentSchema.d.ts.map +1 -1
  42. package/dist/summary/documentSchema.js +45 -30
  43. package/dist/summary/documentSchema.js.map +1 -1
  44. package/lib/blobManager/blobManager.d.ts +3 -3
  45. package/lib/blobManager/blobManager.d.ts.map +1 -1
  46. package/lib/blobManager/blobManager.js +1 -1
  47. package/lib/blobManager/blobManager.js.map +1 -1
  48. package/lib/channelCollection.d.ts +20 -5
  49. package/lib/channelCollection.d.ts.map +1 -1
  50. package/lib/channelCollection.js +183 -119
  51. package/lib/channelCollection.js.map +1 -1
  52. package/lib/containerRuntime.d.ts +12 -4
  53. package/lib/containerRuntime.d.ts.map +1 -1
  54. package/lib/containerRuntime.js +155 -66
  55. package/lib/containerRuntime.js.map +1 -1
  56. package/lib/dataStoreContext.d.ts +15 -3
  57. package/lib/dataStoreContext.d.ts.map +1 -1
  58. package/lib/dataStoreContext.js +48 -19
  59. package/lib/dataStoreContext.js.map +1 -1
  60. package/lib/gc/garbageCollection.d.ts +5 -6
  61. package/lib/gc/garbageCollection.d.ts.map +1 -1
  62. package/lib/gc/garbageCollection.js +23 -22
  63. package/lib/gc/garbageCollection.js.map +1 -1
  64. package/lib/gc/gcDefinitions.d.ts +2 -2
  65. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  66. package/lib/gc/gcDefinitions.js.map +1 -1
  67. package/lib/opLifecycle/outbox.d.ts +3 -0
  68. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  69. package/lib/opLifecycle/outbox.js +9 -0
  70. package/lib/opLifecycle/outbox.js.map +1 -1
  71. package/lib/opLifecycle/remoteMessageProcessor.d.ts +1 -0
  72. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  73. package/lib/opLifecycle/remoteMessageProcessor.js +2 -0
  74. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  75. package/lib/opProperties.js +1 -1
  76. package/lib/opProperties.js.map +1 -1
  77. package/lib/packageVersion.d.ts +1 -1
  78. package/lib/packageVersion.js +1 -1
  79. package/lib/packageVersion.js.map +1 -1
  80. package/lib/summary/documentSchema.d.ts +11 -0
  81. package/lib/summary/documentSchema.d.ts.map +1 -1
  82. package/lib/summary/documentSchema.js +45 -30
  83. package/lib/summary/documentSchema.js.map +1 -1
  84. package/package.json +24 -24
  85. package/src/blobManager/blobManager.ts +2 -2
  86. package/src/channelCollection.ts +227 -160
  87. package/src/containerRuntime.ts +197 -80
  88. package/src/dataStoreContext.ts +66 -23
  89. package/src/gc/garbageCollection.ts +32 -32
  90. package/src/gc/gcDefinitions.ts +3 -3
  91. package/src/opLifecycle/outbox.ts +12 -0
  92. package/src/opLifecycle/remoteMessageProcessor.ts +3 -0
  93. package/src/opProperties.ts +1 -1
  94. package/src/packageVersion.ts +1 -1
  95. package/src/summary/documentSchema.ts +58 -39
@@ -145,6 +145,18 @@ export class Outbox {
145
145
  return this.mainBatch.length + this.blobAttachBatch.length + this.idAllocationBatch.length;
146
146
  }
147
147
 
148
+ public get mainBatchMessageCount(): number {
149
+ return this.mainBatch.length;
150
+ }
151
+
152
+ public get blobAttachBatchMessageCount(): number {
153
+ return this.blobAttachBatch.length;
154
+ }
155
+
156
+ public get idAllocationBatchMessageCount(): number {
157
+ return this.idAllocationBatch.length;
158
+ }
159
+
148
160
  public get isEmpty(): boolean {
149
161
  return this.messageCount === 0;
150
162
  }
@@ -59,6 +59,7 @@ export type InboundMessageResult =
59
59
  messages: InboundSequencedContainerRuntimeMessage[];
60
60
  batchStart: BatchStartInfo;
61
61
  length: number;
62
+ groupedBatch: boolean; // Messages in a grouped batches are sent to the runtime in bunches.
62
63
  }
63
64
  | {
64
65
  type: "batchStartingMessage";
@@ -171,6 +172,7 @@ export class RemoteMessageProcessor {
171
172
  keyMessage: groupedMessages[0] ?? message, // For an empty batch, this is the empty grouped batch message. Needed for sequence numbers for this batch
172
173
  },
173
174
  length: groupedMessages.length, // Will be 0 for an empty batch
175
+ groupedBatch: true,
174
176
  };
175
177
  }
176
178
 
@@ -220,6 +222,7 @@ export class RemoteMessageProcessor {
220
222
  keyMessage: message,
221
223
  },
222
224
  length: 1,
225
+ groupedBatch: false,
223
226
  };
224
227
  }
225
228
  assert(batchMetadataFlag !== true, 0x9d6 /* Unexpected batch start marker */);
@@ -12,7 +12,7 @@ export const opSize = (op: ISequencedDocumentMessage): number => {
12
12
  // Some messages may already have string contents,
13
13
  // so stringifying them again will add inaccurate overhead.
14
14
  const content =
15
- typeof op.contents === "string" ? op.contents : JSON.stringify(op.contents) ?? "";
15
+ typeof op.contents === "string" ? op.contents : (JSON.stringify(op.contents) ?? "");
16
16
  const data = opHasData(op) ? op.data : "";
17
17
  return content.length + data.length;
18
18
  };
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.4.0";
9
+ export const pkgVersion = "2.5.0";
@@ -429,6 +429,7 @@ function arrayToProp(arr: string[]) {
429
429
  *
430
430
  * @legacy
431
431
  * @alpha
432
+ * @sealed
432
433
  */
433
434
  export class DocumentsSchemaController {
434
435
  private explicitSchemaControl: boolean;
@@ -489,7 +490,7 @@ export class DocumentsSchemaController {
489
490
  // Latter is importnat sure that's what will go into summary.
490
491
  this.documentSchema = !existing
491
492
  ? this.desiredSchema
492
- : (documentMetadataSchema as IDocumentSchemaCurrent) ??
493
+ : ((documentMetadataSchema as IDocumentSchemaCurrent) ??
493
494
  ({
494
495
  version: currentDocumentVersionSchema,
495
496
  // see comment in summarizeDocumentSchema() on why it has to stay zero
@@ -499,7 +500,7 @@ export class DocumentsSchemaController {
499
500
  runtime: {
500
501
  explicitSchemaControl: boolToProp(!existing && features.explicitSchemaControl),
501
502
  },
502
- } satisfies IDocumentSchemaCurrent);
503
+ } satisfies IDocumentSchemaCurrent));
503
504
 
504
505
  checkRuntimeCompatibility(this.documentSchema, "document");
505
506
  this.validateSeqNumber(this.documentSchema.refSeq, snapshotSequenceNumber, "summary");
@@ -601,55 +602,73 @@ export class DocumentsSchemaController {
601
602
  * @param local - whether op is local
602
603
  * @param sequenceNumber - sequence number of the op
603
604
  * @returns - true if schema was accepted, otherwise false (rejected due to failed CAS)
605
+ * @deprecated It has been replaced by processDocumentSchemaMessages instead.
604
606
  */
605
607
  public processDocumentSchemaOp(
606
608
  content: IDocumentSchemaChangeMessage,
607
609
  local: boolean,
608
610
  sequenceNumber: number,
609
611
  ) {
610
- this.validateSeqNumber(content.refSeq, this.documentSchema.refSeq, "content.refSeq");
611
- this.validateSeqNumber(this.documentSchema.refSeq, sequenceNumber, "refSeq");
612
- // validate is strickly less, not equal
613
- assert(
614
- this.documentSchema.refSeq < sequenceNumber,
615
- 0x950 /* time should move forward only! */,
616
- );
617
-
618
- if (content.refSeq !== this.documentSchema.refSeq) {
619
- // CAS failed
620
- return false;
621
- }
622
-
623
- // This assert should be after checking for successful CAS above.
624
- // This will ensure we do not trip on our own messages that are no longer wanted as we processed someone else schema change message.
625
- assert(
626
- !local || (this.explicitSchemaControl && this.futureSchema !== undefined),
627
- 0x951 /* not sending ops */,
628
- );
612
+ return this.processDocumentSchemaMessages([content], local, sequenceNumber);
613
+ }
629
614
 
630
- // Changes are in effect. Immediately check that this client understands these changes
631
- checkRuntimeCompatibility(content, "change");
615
+ /**
616
+ * Process document schema change messages
617
+ * Called by ContainerRuntime whenever it sees document schema messages.
618
+ * @param contents - contents of the messages
619
+ * @param local - whether op is local
620
+ * @param sequenceNumber - sequence number of the op
621
+ * @returns - true if schema was accepted, otherwise false (rejected due to failed CAS)
622
+ */
623
+ public processDocumentSchemaMessages(
624
+ contents: IDocumentSchemaChangeMessage[],
625
+ local: boolean,
626
+ sequenceNumber: number,
627
+ ) {
628
+ for (const content of contents) {
629
+ this.validateSeqNumber(content.refSeq, this.documentSchema.refSeq, "content.refSeq");
630
+ this.validateSeqNumber(this.documentSchema.refSeq, sequenceNumber, "refSeq");
631
+ // validate is strickly less, not equal
632
+ assert(
633
+ this.documentSchema.refSeq < sequenceNumber,
634
+ 0x950 /* time should move forward only! */,
635
+ );
632
636
 
633
- const schema: IDocumentSchema = { ...content, refSeq: sequenceNumber };
634
- this.documentSchema = schema as IDocumentSchemaCurrent;
635
- this.sessionSchema = and(this.documentSchema, this.desiredSchema);
636
- assert(this.sessionSchema.refSeq === sequenceNumber, 0x97d /* seq# */);
637
+ if (content.refSeq !== this.documentSchema.refSeq) {
638
+ // CAS failed
639
+ return false;
640
+ }
637
641
 
638
- // legacy behavior is automatically off for the document once someone sends a schema op -
639
- // from now on it's fully controlled by ops.
640
- // This is very important, as summarizeDocumentSchema() should use this new schema!
641
- this.explicitSchemaControl = true;
642
+ // This assert should be after checking for successful CAS above.
643
+ // This will ensure we do not trip on our own messages that are no longer wanted as we processed someone else schema change message.
644
+ assert(
645
+ !local || (this.explicitSchemaControl && this.futureSchema !== undefined),
646
+ 0x951 /* not sending ops */,
647
+ );
642
648
 
643
- // Stop attempting changing schema.
644
- // If it was local op, then we succeeded and do not need to try again.
645
- // If it was remote op, then some changes happened to schema.
646
- // We would need to recalculate this.futureSchema by merging changes that we just received.
647
- // Avoid this complexity for now - a new client session (loading from new summary with these changes)
648
- // will automatically do this recalculation and will figure out
649
- this.futureSchema = undefined;
649
+ // Changes are in effect. Immediately check that this client understands these changes
650
+ checkRuntimeCompatibility(content, "change");
650
651
 
651
- this.onSchemaChange(this.sessionSchema);
652
+ const schema: IDocumentSchema = { ...content, refSeq: sequenceNumber };
653
+ this.documentSchema = schema as IDocumentSchemaCurrent;
654
+ this.sessionSchema = and(this.documentSchema, this.desiredSchema);
655
+ assert(this.sessionSchema.refSeq === sequenceNumber, 0x97d /* seq# */);
656
+
657
+ // legacy behavior is automatically off for the document once someone sends a schema op -
658
+ // from now on it's fully controlled by ops.
659
+ // This is very important, as summarizeDocumentSchema() should use this new schema!
660
+ this.explicitSchemaControl = true;
661
+
662
+ // Stop attempting changing schema.
663
+ // If it was local op, then we succeeded and do not need to try again.
664
+ // If it was remote op, then some changes happened to schema.
665
+ // We would need to recalculate this.futureSchema by merging changes that we just received.
666
+ // Avoid this complexity for now - a new client session (loading from new summary with these changes)
667
+ // will automatically do this recalculation and will figure out
668
+ this.futureSchema = undefined;
652
669
 
670
+ this.onSchemaChange(this.sessionSchema);
671
+ }
653
672
  return true;
654
673
  }
655
674