@fluidframework/container-runtime 2.0.0-dev.7.3.0.207781 → 2.0.0-dev.7.3.0.209023

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 (90) hide show
  1. package/dist/containerRuntime.d.ts +5 -11
  2. package/dist/containerRuntime.d.ts.map +1 -1
  3. package/dist/containerRuntime.js +26 -32
  4. package/dist/containerRuntime.js.map +1 -1
  5. package/dist/gc/gcConfigs.d.ts.map +1 -1
  6. package/dist/gc/gcConfigs.js +4 -1
  7. package/dist/gc/gcConfigs.js.map +1 -1
  8. package/dist/gc/gcDefinitions.d.ts +7 -2
  9. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  10. package/dist/gc/gcDefinitions.js +8 -3
  11. package/dist/gc/gcDefinitions.js.map +1 -1
  12. package/dist/gc/gcTelemetry.d.ts +1 -1
  13. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  14. package/dist/gc/gcTelemetry.js +20 -8
  15. package/dist/gc/gcTelemetry.js.map +1 -1
  16. package/dist/gc/index.d.ts +1 -1
  17. package/dist/gc/index.d.ts.map +1 -1
  18. package/dist/gc/index.js +3 -1
  19. package/dist/gc/index.js.map +1 -1
  20. package/dist/messageTypes.d.ts +3 -6
  21. package/dist/messageTypes.d.ts.map +1 -1
  22. package/dist/messageTypes.js.map +1 -1
  23. package/dist/metadata.d.ts +6 -0
  24. package/dist/metadata.d.ts.map +1 -1
  25. package/dist/metadata.js.map +1 -1
  26. package/dist/opLifecycle/opGroupingManager.d.ts +10 -2
  27. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  28. package/dist/opLifecycle/opGroupingManager.js +23 -3
  29. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  30. package/dist/opLifecycle/outbox.d.ts +2 -1
  31. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  32. package/dist/opLifecycle/outbox.js +23 -1
  33. package/dist/opLifecycle/outbox.js.map +1 -1
  34. package/dist/packageVersion.d.ts +1 -1
  35. package/dist/packageVersion.js +1 -1
  36. package/dist/packageVersion.js.map +1 -1
  37. package/dist/pendingStateManager.d.ts.map +1 -1
  38. package/dist/pendingStateManager.js +1 -10
  39. package/dist/pendingStateManager.js.map +1 -1
  40. package/lib/containerRuntime.d.ts +5 -11
  41. package/lib/containerRuntime.d.ts.map +1 -1
  42. package/lib/containerRuntime.js +26 -32
  43. package/lib/containerRuntime.js.map +1 -1
  44. package/lib/gc/gcConfigs.d.ts.map +1 -1
  45. package/lib/gc/gcConfigs.js +5 -2
  46. package/lib/gc/gcConfigs.js.map +1 -1
  47. package/lib/gc/gcDefinitions.d.ts +7 -2
  48. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  49. package/lib/gc/gcDefinitions.js +7 -2
  50. package/lib/gc/gcDefinitions.js.map +1 -1
  51. package/lib/gc/gcTelemetry.d.ts +1 -1
  52. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  53. package/lib/gc/gcTelemetry.js +21 -9
  54. package/lib/gc/gcTelemetry.js.map +1 -1
  55. package/lib/gc/index.d.ts +1 -1
  56. package/lib/gc/index.d.ts.map +1 -1
  57. package/lib/gc/index.js +1 -1
  58. package/lib/gc/index.js.map +1 -1
  59. package/lib/messageTypes.d.ts +3 -6
  60. package/lib/messageTypes.d.ts.map +1 -1
  61. package/lib/messageTypes.js.map +1 -1
  62. package/lib/metadata.d.ts +6 -0
  63. package/lib/metadata.d.ts.map +1 -1
  64. package/lib/metadata.js.map +1 -1
  65. package/lib/opLifecycle/opGroupingManager.d.ts +10 -2
  66. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  67. package/lib/opLifecycle/opGroupingManager.js +23 -3
  68. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  69. package/lib/opLifecycle/outbox.d.ts +2 -1
  70. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  71. package/lib/opLifecycle/outbox.js +23 -1
  72. package/lib/opLifecycle/outbox.js.map +1 -1
  73. package/lib/packageVersion.d.ts +1 -1
  74. package/lib/packageVersion.js +1 -1
  75. package/lib/packageVersion.js.map +1 -1
  76. package/lib/pendingStateManager.d.ts.map +1 -1
  77. package/lib/pendingStateManager.js +1 -10
  78. package/lib/pendingStateManager.js.map +1 -1
  79. package/package.json +21 -21
  80. package/src/containerRuntime.ts +41 -39
  81. package/src/gc/gcConfigs.ts +8 -2
  82. package/src/gc/gcDefinitions.ts +10 -2
  83. package/src/gc/gcTelemetry.ts +28 -17
  84. package/src/gc/index.ts +2 -0
  85. package/src/messageTypes.ts +2 -7
  86. package/src/metadata.ts +7 -0
  87. package/src/opLifecycle/opGroupingManager.ts +37 -2
  88. package/src/opLifecycle/outbox.ts +38 -2
  89. package/src/packageVersion.ts +1 -1
  90. package/src/pendingStateManager.ts +2 -11
@@ -5,6 +5,8 @@
5
5
 
6
6
  import { assert } from "@fluidframework/core-utils";
7
7
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
8
+ import { createChildLogger } from "@fluidframework/telemetry-utils";
9
+ import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
8
10
  import { ContainerMessageType } from "../messageTypes";
9
11
  import { IBatch } from "./definitions";
10
12
 
@@ -26,16 +28,38 @@ function isGroupContents(opContents: any): opContents is IGroupedBatchMessageCon
26
28
  return opContents?.type === OpGroupingManager.groupedBatchOp;
27
29
  }
28
30
 
31
+ export interface OpGroupingManagerConfig {
32
+ readonly groupedBatchingEnabled: boolean;
33
+ readonly opCountThreshold: number;
34
+ readonly reentrantBatchGroupingEnabled: boolean;
35
+ }
36
+
29
37
  export class OpGroupingManager {
30
38
  static readonly groupedBatchOp = "groupedBatch";
39
+ private readonly logger;
31
40
 
32
- constructor(private readonly groupedBatchingEnabled: boolean) {}
41
+ constructor(
42
+ private readonly config: OpGroupingManagerConfig,
43
+ logger: ITelemetryBaseLogger,
44
+ ) {
45
+ this.logger = createChildLogger({ logger, namespace: "OpGroupingManager" });
46
+ }
33
47
 
34
48
  public groupBatch(batch: IBatch): IBatch {
35
- if (batch.content.length < 2 || !this.groupedBatchingEnabled) {
49
+ if (!this.shouldGroup(batch)) {
36
50
  return batch;
37
51
  }
38
52
 
53
+ if (batch.content.length >= 1000) {
54
+ this.logger.sendTelemetryEvent({
55
+ eventName: "GroupLargeBatch",
56
+ length: batch.content.length,
57
+ threshold: this.config.opCountThreshold,
58
+ reentrant: batch.hasReentrantOps,
59
+ referenceSequenceNumber: batch.content[0].referenceSequenceNumber,
60
+ });
61
+ }
62
+
39
63
  for (const message of batch.content) {
40
64
  if (message.metadata) {
41
65
  const keys = Object.keys(message.metadata);
@@ -86,4 +110,15 @@ export class OpGroupingManager {
86
110
  compression: subMessage.compression,
87
111
  }));
88
112
  }
113
+
114
+ public shouldGroup(batch: IBatch): boolean {
115
+ return (
116
+ // Grouped batching must be enabled
117
+ this.config.groupedBatchingEnabled &&
118
+ // The number of ops in the batch must surpass the configured threshold
119
+ batch.content.length >= this.config.opCountThreshold &&
120
+ // Support for reentrant batches must be explicitly enabled
121
+ (this.config.reentrantBatchGroupingEnabled || batch.hasReentrantOps !== true)
122
+ );
123
+ }
89
124
  }
@@ -30,7 +30,6 @@ export interface IOutboxConfig {
30
30
  // The maximum size of a batch that we can send over the wire.
31
31
  readonly maxBatchSizeInBytes: number;
32
32
  readonly disablePartialFlush: boolean;
33
- readonly enableGroupedBatching: boolean;
34
33
  }
35
34
 
36
35
  export interface IOutboxParameters {
@@ -90,6 +89,7 @@ export class Outbox {
90
89
  private readonly attachFlowBatch: BatchManager;
91
90
  private readonly mainBatch: BatchManager;
92
91
  private readonly blobAttachBatch: BatchManager;
92
+ private readonly idAllocationBatch: BatchManager;
93
93
  private readonly defaultAttachFlowSoftLimitInBytes = 320 * 1024;
94
94
  private batchRebasesToReport = 5;
95
95
  private rebasing = false;
@@ -115,6 +115,7 @@ export class Outbox {
115
115
  this.attachFlowBatch = new BatchManager({ hardLimit, softLimit });
116
116
  this.mainBatch = new BatchManager({ hardLimit });
117
117
  this.blobAttachBatch = new BatchManager({ hardLimit });
118
+ this.idAllocationBatch = new BatchManager({ hardLimit });
118
119
  }
119
120
 
120
121
  public get messageCount(): number {
@@ -231,6 +232,37 @@ export class Outbox {
231
232
  }
232
233
  }
233
234
 
235
+ public submitIdAllocation(message: BatchMessage) {
236
+ this.maybeFlushPartialBatch();
237
+
238
+ if (
239
+ !this.idAllocationBatch.push(
240
+ message,
241
+ this.isContextReentrant(),
242
+ this.params.getCurrentSequenceNumbers().clientSequenceNumber,
243
+ )
244
+ ) {
245
+ // BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged
246
+ // when queue is not empty.
247
+ // Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit
248
+ this.flushInternal(this.idAllocationBatch);
249
+
250
+ this.addMessageToBatchManager(this.idAllocationBatch, message);
251
+ }
252
+
253
+ // If compression is enabled, we will always successfully receive
254
+ // attach ops and compress then send them at the next JS turn, regardless
255
+ // of the overall size of the accumulated ops in the batch.
256
+ // However, it is more efficient to flush these ops faster, preferably
257
+ // after they reach a size which would benefit from compression.
258
+ if (
259
+ this.idAllocationBatch.contentSizeInBytes >=
260
+ this.params.config.compressionOptions.minimumBatchSizeInBytes
261
+ ) {
262
+ this.flushInternal(this.idAllocationBatch);
263
+ }
264
+ }
265
+
234
266
  private addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {
235
267
  if (
236
268
  !batchManager.push(
@@ -259,6 +291,7 @@ export class Outbox {
259
291
  }
260
292
 
261
293
  private flushAll() {
294
+ this.flushInternal(this.idAllocationBatch);
262
295
  this.flushInternal(this.attachFlowBatch);
263
296
  this.flushInternal(this.blobAttachBatch, true /* disableGroupedBatching */);
264
297
  this.flushInternal(this.mainBatch);
@@ -270,7 +303,10 @@ export class Outbox {
270
303
  }
271
304
 
272
305
  const rawBatch = batchManager.popBatch();
273
- if (rawBatch.hasReentrantOps === true && this.params.config.enableGroupedBatching) {
306
+ if (
307
+ rawBatch.hasReentrantOps === true &&
308
+ this.params.groupingManager.shouldGroup(rawBatch)
309
+ ) {
274
310
  assert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);
275
311
  // If a batch contains reentrant ops (ops created as a result from processing another op)
276
312
  // it needs to be rebased so that we can ensure consistent reference sequence numbers
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-dev.7.3.0.207781";
9
+ export const pkgVersion = "2.0.0-dev.7.3.0.209023";
@@ -11,7 +11,7 @@ import { ICriticalContainerError } from "@fluidframework/container-definitions";
11
11
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
12
12
  import { DataProcessingError, ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
13
13
 
14
- import { ContainerMessageType, InboundSequencedContainerRuntimeMessage } from "./messageTypes";
14
+ import { InboundSequencedContainerRuntimeMessage } from "./messageTypes";
15
15
  import { pkgVersion } from "./packageVersion";
16
16
  import { IBatchMetadata } from "./metadata";
17
17
 
@@ -128,18 +128,9 @@ export class PendingStateManager implements IDisposable {
128
128
  return {
129
129
  pendingStates: [...this.savedOps, ...this.pendingMessages.toArray()].map(
130
130
  (message) => {
131
- let content = message.content;
132
- const parsedContent = JSON.parse(content);
133
- // IdAllocations need their localOpMetadata stashed in the contents
134
- // of the op to correctly resume the session when processing stashed ops
135
- if (parsedContent.type === ContainerMessageType.IdAllocation) {
136
- parsedContent.contents.stashedState = message.localOpMetadata;
137
- content = JSON.stringify(parsedContent);
138
- }
139
-
140
131
  // delete localOpMetadata since it may not be serializable
141
132
  // and will be regenerated by applyStashedOp()
142
- return { ...message, content, localOpMetadata: undefined };
133
+ return { ...message, localOpMetadata: undefined };
143
134
  },
144
135
  ),
145
136
  };