@fluidframework/container-runtime 2.0.0-internal.1.1.1 → 2.0.0-internal.1.2.0.93071

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 (70) hide show
  1. package/dist/batchManager.d.ts +32 -0
  2. package/dist/batchManager.d.ts.map +1 -0
  3. package/dist/batchManager.js +71 -0
  4. package/dist/batchManager.js.map +1 -0
  5. package/dist/containerRuntime.d.ts +44 -17
  6. package/dist/containerRuntime.d.ts.map +1 -1
  7. package/dist/containerRuntime.js +197 -95
  8. package/dist/containerRuntime.js.map +1 -1
  9. package/dist/dataStoreContext.d.ts +4 -4
  10. package/dist/dataStoreContext.js +5 -5
  11. package/dist/dataStoreContext.js.map +1 -1
  12. package/dist/packageVersion.d.ts +1 -1
  13. package/dist/packageVersion.d.ts.map +1 -1
  14. package/dist/packageVersion.js +1 -1
  15. package/dist/packageVersion.js.map +1 -1
  16. package/dist/pendingStateManager.d.ts +0 -11
  17. package/dist/pendingStateManager.d.ts.map +1 -1
  18. package/dist/pendingStateManager.js +6 -43
  19. package/dist/pendingStateManager.js.map +1 -1
  20. package/dist/runningSummarizer.js +1 -1
  21. package/dist/runningSummarizer.js.map +1 -1
  22. package/dist/scheduleManager.js +1 -1
  23. package/dist/scheduleManager.js.map +1 -1
  24. package/dist/summarizerTypes.d.ts +3 -3
  25. package/dist/summarizerTypes.js +1 -1
  26. package/dist/summarizerTypes.js.map +1 -1
  27. package/dist/summaryCollection.d.ts +1 -0
  28. package/dist/summaryCollection.d.ts.map +1 -1
  29. package/dist/summaryCollection.js +32 -13
  30. package/dist/summaryCollection.js.map +1 -1
  31. package/lib/batchManager.d.ts +32 -0
  32. package/lib/batchManager.d.ts.map +1 -0
  33. package/lib/batchManager.js +67 -0
  34. package/lib/batchManager.js.map +1 -0
  35. package/lib/containerRuntime.d.ts +44 -17
  36. package/lib/containerRuntime.d.ts.map +1 -1
  37. package/lib/containerRuntime.js +200 -98
  38. package/lib/containerRuntime.js.map +1 -1
  39. package/lib/dataStoreContext.d.ts +4 -4
  40. package/lib/dataStoreContext.js +5 -5
  41. package/lib/dataStoreContext.js.map +1 -1
  42. package/lib/packageVersion.d.ts +1 -1
  43. package/lib/packageVersion.d.ts.map +1 -1
  44. package/lib/packageVersion.js +1 -1
  45. package/lib/packageVersion.js.map +1 -1
  46. package/lib/pendingStateManager.d.ts +0 -11
  47. package/lib/pendingStateManager.d.ts.map +1 -1
  48. package/lib/pendingStateManager.js +6 -43
  49. package/lib/pendingStateManager.js.map +1 -1
  50. package/lib/runningSummarizer.js +1 -1
  51. package/lib/runningSummarizer.js.map +1 -1
  52. package/lib/scheduleManager.js +2 -2
  53. package/lib/scheduleManager.js.map +1 -1
  54. package/lib/summarizerTypes.d.ts +3 -3
  55. package/lib/summarizerTypes.js +1 -1
  56. package/lib/summarizerTypes.js.map +1 -1
  57. package/lib/summaryCollection.d.ts +1 -0
  58. package/lib/summaryCollection.d.ts.map +1 -1
  59. package/lib/summaryCollection.js +32 -13
  60. package/lib/summaryCollection.js.map +1 -1
  61. package/package.json +17 -17
  62. package/src/batchManager.ts +88 -0
  63. package/src/containerRuntime.ts +273 -156
  64. package/src/dataStoreContext.ts +7 -7
  65. package/src/packageVersion.ts +1 -1
  66. package/src/pendingStateManager.ts +6 -56
  67. package/src/runningSummarizer.ts +1 -1
  68. package/src/scheduleManager.ts +2 -2
  69. package/src/summarizerTypes.ts +3 -3
  70. package/src/summaryCollection.ts +33 -16
@@ -700,7 +700,7 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
700
700
  public abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
701
701
 
702
702
  /**
703
- * @deprecated - Sets the datastore as root, for aliasing purposes: #7948
703
+ * @deprecated Sets the datastore as root, for aliasing purposes: #7948
704
704
  * This method should not be used outside of the aliasing context.
705
705
  * It will be removed, as the source of truth for this flag will be the aliasing blob.
706
706
  */
@@ -709,7 +709,7 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
709
709
  }
710
710
 
711
711
  /**
712
- * @deprecated - Renamed to getBaseGCDetails().
712
+ * @deprecated Renamed to `{@link FluidDataStoreContext.getBaseGCDetails}()`.
713
713
  */
714
714
  public abstract getInitialGCSummaryDetails(): Promise<IGarbageCollectionSummaryDetails>;
715
715
 
@@ -851,7 +851,7 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
851
851
  }
852
852
 
853
853
  /**
854
- * @deprecated - Renamed to getBaseGCDetails.
854
+ * @deprecated Renamed to {@link RemoteFluidDataStoreContext.getBaseGCDetails}.
855
855
  */
856
856
  public async getInitialGCSummaryDetails(): Promise<IGarbageCollectionSummaryDetails> {
857
857
  return this.getBaseGCDetails();
@@ -965,7 +965,7 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
965
965
  }
966
966
 
967
967
  /**
968
- * @deprecated - Renamed to getBaseGCDetails.
968
+ * @deprecated Renamed to {@link LocalFluidDataStoreContextBase.getBaseGCDetails}.
969
969
  */
970
970
  public async getInitialGCSummaryDetails(): Promise<IGarbageCollectionSummaryDetails> {
971
971
  // Local data store does not have initial summary.
@@ -1008,7 +1008,10 @@ export class LocalDetachedFluidDataStoreContext
1008
1008
  registry: IProvideFluidDataStoreFactory,
1009
1009
  dataStoreChannel: IFluidDataStoreChannel) {
1010
1010
  assert(this.detachedRuntimeCreation, 0x154 /* "runtime creation is already attached" */);
1011
+ this.detachedRuntimeCreation = false;
1012
+
1011
1013
  assert(this.channelDeferred === undefined, 0x155 /* "channel deferral is already set" */);
1014
+ this.channelDeferred = new Deferred<IFluidDataStoreChannel>();
1012
1015
 
1013
1016
  const factory = registry.IFluidDataStoreFactory;
1014
1017
 
@@ -1018,9 +1021,6 @@ export class LocalDetachedFluidDataStoreContext
1018
1021
  assert(this.registry === undefined, 0x157 /* "datastore registry already attached" */);
1019
1022
  this.registry = entry.registry;
1020
1023
 
1021
- this.detachedRuntimeCreation = false;
1022
- this.channelDeferred = new Deferred<IFluidDataStoreChannel>();
1023
-
1024
1024
  super.bindRuntime(dataStoreChannel);
1025
1025
 
1026
1026
  if (await this.isRoot()) {
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-internal.1.1.1";
9
+ export const pkgVersion = "2.0.0-internal.1.2.0.93071";
@@ -11,7 +11,6 @@ import {
11
11
  ISequencedDocumentMessage,
12
12
  } from "@fluidframework/protocol-definitions";
13
13
  import { FlushMode } from "@fluidframework/runtime-definitions";
14
- import { wrapError } from "@fluidframework/telemetry-utils";
15
14
  import Deque from "double-ended-queue";
16
15
  import { ContainerMessageType } from "./containerRuntime";
17
16
  import { pkgVersion } from "./packageVersion";
@@ -69,10 +68,6 @@ export interface IRuntimeStateHandler{
69
68
  content: any,
70
69
  localOpMetadata: unknown,
71
70
  opMetadata: Record<string, unknown> | undefined): void;
72
- rollback(
73
- type: ContainerMessageType,
74
- content: any,
75
- localOpMetadata: unknown): void;
76
71
  }
77
72
 
78
73
  /**
@@ -233,7 +228,11 @@ export class PendingStateManager implements IDisposable {
233
228
 
234
229
  // then we push onto pendingStates which will cause PendingStateManager to resubmit when we connect
235
230
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
236
- this.pendingStates.push(this.initialStates.shift()!);
231
+ const firstPendingState = this.initialStates.shift()!;
232
+ this.pendingStates.push(firstPendingState);
233
+ if (firstPendingState.type === "message") {
234
+ this._pendingMessagesCount++;
235
+ }
237
236
  }
238
237
  }
239
238
 
@@ -267,6 +266,7 @@ export class PendingStateManager implements IDisposable {
267
266
  }
268
267
 
269
268
  this._pendingMessagesCount--;
269
+ assert(this._pendingMessagesCount >= 0, "positive");
270
270
 
271
271
  // Post-processing part - If we are processing a batch then this could be the last message in the batch.
272
272
  this.maybeProcessBatchEnd(message);
@@ -393,31 +393,6 @@ export class PendingStateManager implements IDisposable {
393
393
  this.isProcessingBatch = false;
394
394
  }
395
395
 
396
- /**
397
- * Capture the pending state at this point
398
- */
399
- public checkpoint() {
400
- const checkpointHead = this.pendingStates.peekBack();
401
- return {
402
- rollback: () => {
403
- try {
404
- while (this.pendingStates.peekBack() !== checkpointHead) {
405
- this.rollbackNextPendingState();
406
- }
407
- } catch (err) {
408
- const error = wrapError(err, (message) => {
409
- return DataProcessingError.create(
410
- `RollbackError: ${message}`,
411
- "checkpointRollback",
412
- undefined) as DataProcessingError;
413
- });
414
- this.stateHandler.close(error);
415
- throw error;
416
- }
417
- },
418
- };
419
- }
420
-
421
396
  /**
422
397
  * Returns the next pending state from the pending state queue.
423
398
  */
@@ -427,31 +402,6 @@ export class PendingStateManager implements IDisposable {
427
402
  return nextPendingState;
428
403
  }
429
404
 
430
- /**
431
- * Undo the last pending state
432
- */
433
- private rollbackNextPendingState() {
434
- const pendingStatesCount = this.pendingStates.length;
435
- if (pendingStatesCount === 0) {
436
- return;
437
- }
438
-
439
- this._pendingMessagesCount--;
440
-
441
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
442
- const pendingState = this.pendingStates.pop()!;
443
- switch (pendingState.type) {
444
- case "message":
445
- this.stateHandler.rollback(
446
- pendingState.messageType,
447
- pendingState.content,
448
- pendingState.localOpMetadata);
449
- break;
450
- default:
451
- throw new Error(`Can't rollback state ${pendingState.type}`);
452
- }
453
- }
454
-
455
405
  /**
456
406
  * Called when the Container's connection state changes. If the Container gets connected, it replays all the pending
457
407
  * states in its queue. This includes setting the FlushMode and triggering resubmission of unacked ops.
@@ -239,7 +239,7 @@ export class RunningSummarizer implements IDisposable {
239
239
  public handleOp(op: ISequencedDocumentMessage) {
240
240
  this.heuristicData.lastOpSequenceNumber = op.sequenceNumber;
241
241
 
242
- if (op.type !== MessageType.Summarize && isRuntimeMessage(op)) {
242
+ if (isRuntimeMessage(op)) {
243
243
  this.heuristicData.numRuntimeOps++;
244
244
  } else {
245
245
  this.heuristicData.numNonRuntimeOps++;
@@ -8,7 +8,7 @@ import { IDocumentMessage, ISequencedDocumentMessage } from "@fluidframework/pro
8
8
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
9
9
  import { ChildLogger } from "@fluidframework/telemetry-utils";
10
10
  import { assert, performance } from "@fluidframework/common-utils";
11
- import { isUnpackedRuntimeMessage } from "@fluidframework/driver-utils";
11
+ import { isRuntimeMessage } from "@fluidframework/driver-utils";
12
12
  import { DataCorruptionError, extractSafePropertiesFromMessage } from "@fluidframework/container-utils";
13
13
  import { DeltaScheduler } from "./deltaScheduler";
14
14
  import { pkgVersion } from "./packageVersion";
@@ -234,7 +234,7 @@ class ScheduleManagerCore {
234
234
  const batchMetadata = metadata?.batch;
235
235
 
236
236
  // Protocol messages are never part of a runtime batch of messages
237
- if (!isUnpackedRuntimeMessage(message)) {
237
+ if (!isRuntimeMessage(message)) {
238
238
  // Protocol messages should never show up in the middle of the batch!
239
239
  assert(this.currentBatchClientId === undefined, 0x29a /* "System message in the middle of batch!" */);
240
240
  assert(batchMetadata === undefined, 0x29b /* "system op in a batch?" */);
@@ -25,16 +25,16 @@ import { SummarizeReason } from "./summaryGenerator";
25
25
  import { ISummaryConfigurationHeuristics } from ".";
26
26
 
27
27
  /**
28
- * @deprecated - This will be removed in a later release.
28
+ * @deprecated This will be removed in a later release.
29
29
  */
30
30
  export const ISummarizer: keyof IProvideSummarizer = "ISummarizer";
31
31
 
32
32
  /**
33
- * @deprecated - This will be removed in a later release.
33
+ * @deprecated This will be removed in a later release.
34
34
  */
35
35
  export interface IProvideSummarizer {
36
36
  /**
37
- * @deprecated - This will be removed in a later release.
37
+ * @deprecated This will be removed in a later release.
38
38
  */
39
39
  readonly ISummarizer: ISummarizer;
40
40
  }
@@ -239,9 +239,7 @@ export class SummaryCollection extends TypedEventEmitter<ISummaryCollectionOpEve
239
239
  private readonly logger: ITelemetryLogger,
240
240
  ) {
241
241
  super();
242
- this.deltaManager.on(
243
- "op",
244
- (op) => this.handleOp(op));
242
+ this.deltaManager.on("op", (op) => this.handleOp(op));
245
243
  }
246
244
 
247
245
  /**
@@ -295,24 +293,43 @@ export class SummaryCollection extends TypedEventEmitter<ISummaryCollectionOpEve
295
293
  return this.lastAck;
296
294
  }
297
295
 
296
+ private parseContent(op: ISequencedDocumentMessage) {
297
+ // back-compat: ADO #1385: Make this unconditional in the future,
298
+ // when Container.processRemoteMessage stops parsing contents. That said, we should move to
299
+ // listen for "op" events from ContainerRuntime, and parsing may not be required at all if
300
+ // ContainerRuntime.process() would parse it for all types of ops.
301
+ // Can make either of those changes only when LTS moves to a version that has no content
302
+ // parsing in loader layer!
303
+ if (typeof op.contents === "string") {
304
+ op.contents = JSON.parse(op.contents);
305
+ }
306
+ }
307
+
298
308
  /**
299
309
  * Handler for ops; only handles ops relating to summaries.
300
310
  * @param op - op message to handle
301
311
  */
302
- private handleOp(op: ISequencedDocumentMessage) {
312
+ private handleOp(opArg: ISequencedDocumentMessage) {
313
+ const op = { ...opArg };
314
+
303
315
  switch (op.type) {
304
- case MessageType.Summarize: {
305
- this.handleSummaryOp(op as ISummaryOpMessage);
306
- return;
307
- }
308
- case MessageType.SummaryAck: {
309
- this.handleSummaryAck(op as ISummaryAckMessage);
310
- return;
311
- }
312
- case MessageType.SummaryNack: {
313
- this.handleSummaryNack(op as ISummaryNackMessage);
314
- return;
315
- }
316
+ case MessageType.Summarize:
317
+ this.parseContent(op);
318
+ return this.handleSummaryOp(op as ISummaryOpMessage);
319
+ case MessageType.SummaryAck:
320
+ case MessageType.SummaryNack:
321
+ // Old files (prior to PR #10077) may not contain this info
322
+ // back-compat: ADO #1385: remove cast when ISequencedDocumentMessage changes are propagated
323
+ if ((op as any).data !== undefined) {
324
+ op.contents = JSON.parse((op as any).data);
325
+ } else {
326
+ this.parseContent(op);
327
+ }
328
+ if (op.type === MessageType.SummaryAck) {
329
+ return this.handleSummaryAck(op as ISummaryAckMessage);
330
+ } else {
331
+ return this.handleSummaryNack(op as ISummaryNackMessage);
332
+ }
316
333
  default: {
317
334
  // If the difference between timestamp of current op and last summary op is greater than
318
335
  // the maxAckWaitTime, then we need to inform summarizer to not wait and summarize