@fluidframework/container-runtime 2.0.0-dev-rc.5.0.0.271717 → 2.0.0-dev-rc.5.0.0.272251

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 (68) hide show
  1. package/api-extractor/api-extractor-lint-bundle.json +5 -0
  2. package/api-extractor/api-extractor-lint-legacy.cjs.json +5 -0
  3. package/api-extractor/api-extractor-lint-legacy.esm.json +5 -0
  4. package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
  5. package/api-extractor/api-extractor-lint-public.esm.json +5 -0
  6. package/api-report/container-runtime.alpha.api.md +1 -1
  7. package/container-runtime.test-files.tar +0 -0
  8. package/dist/channelCollection.d.ts +12 -2
  9. package/dist/channelCollection.d.ts.map +1 -1
  10. package/dist/channelCollection.js +85 -87
  11. package/dist/channelCollection.js.map +1 -1
  12. package/dist/containerRuntime.d.ts +2 -1
  13. package/dist/containerRuntime.d.ts.map +1 -1
  14. package/dist/containerRuntime.js +25 -4
  15. package/dist/containerRuntime.js.map +1 -1
  16. package/dist/dataStoreContext.d.ts +2 -1
  17. package/dist/dataStoreContext.d.ts.map +1 -1
  18. package/dist/dataStoreContext.js +3 -2
  19. package/dist/dataStoreContext.js.map +1 -1
  20. package/dist/gc/garbageCollection.d.ts +4 -2
  21. package/dist/gc/garbageCollection.d.ts.map +1 -1
  22. package/dist/gc/garbageCollection.js +10 -6
  23. package/dist/gc/garbageCollection.js.map +1 -1
  24. package/dist/gc/gcDefinitions.d.ts +7 -4
  25. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  26. package/dist/gc/gcDefinitions.js.map +1 -1
  27. package/dist/gc/gcTelemetry.d.ts +1 -1
  28. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  29. package/dist/gc/gcTelemetry.js +0 -5
  30. package/dist/gc/gcTelemetry.js.map +1 -1
  31. package/dist/packageVersion.d.ts +1 -1
  32. package/dist/packageVersion.js +1 -1
  33. package/dist/packageVersion.js.map +1 -1
  34. package/lib/channelCollection.d.ts +12 -2
  35. package/lib/channelCollection.d.ts.map +1 -1
  36. package/lib/channelCollection.js +85 -87
  37. package/lib/channelCollection.js.map +1 -1
  38. package/lib/containerRuntime.d.ts +2 -1
  39. package/lib/containerRuntime.d.ts.map +1 -1
  40. package/lib/containerRuntime.js +26 -5
  41. package/lib/containerRuntime.js.map +1 -1
  42. package/lib/dataStoreContext.d.ts +2 -1
  43. package/lib/dataStoreContext.d.ts.map +1 -1
  44. package/lib/dataStoreContext.js +3 -2
  45. package/lib/dataStoreContext.js.map +1 -1
  46. package/lib/gc/garbageCollection.d.ts +4 -2
  47. package/lib/gc/garbageCollection.d.ts.map +1 -1
  48. package/lib/gc/garbageCollection.js +10 -6
  49. package/lib/gc/garbageCollection.js.map +1 -1
  50. package/lib/gc/gcDefinitions.d.ts +7 -4
  51. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  52. package/lib/gc/gcDefinitions.js.map +1 -1
  53. package/lib/gc/gcTelemetry.d.ts +1 -1
  54. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  55. package/lib/gc/gcTelemetry.js +0 -5
  56. package/lib/gc/gcTelemetry.js.map +1 -1
  57. package/lib/packageVersion.d.ts +1 -1
  58. package/lib/packageVersion.js +1 -1
  59. package/lib/packageVersion.js.map +1 -1
  60. package/package.json +27 -18
  61. package/src/channelCollection.ts +133 -123
  62. package/src/containerRuntime.ts +31 -4
  63. package/src/dataStoreContext.ts +3 -2
  64. package/src/gc/garbageCollection.ts +24 -7
  65. package/src/gc/gcDefinitions.ts +16 -4
  66. package/src/gc/gcTelemetry.ts +1 -7
  67. package/src/packageVersion.ts +1 -1
  68. package/tsdoc.json +4 -0
@@ -121,6 +121,7 @@ import {
121
121
  loggerToMonitoringContext,
122
122
  raiseConnectedEvent,
123
123
  wrapError,
124
+ tagCodeArtifacts,
124
125
  } from "@fluidframework/telemetry-utils/internal";
125
126
  import { v4 as uuid } from "uuid";
126
127
 
@@ -1663,7 +1664,11 @@ export class ContainerRuntime
1663
1664
  snapshot,
1664
1665
  parentContext,
1665
1666
  this.mc.logger,
1666
- (props) => this.garbageCollector.nodeUpdated(props),
1667
+ (props) =>
1668
+ this.garbageCollector.nodeUpdated({
1669
+ ...props,
1670
+ timestampMs: props.timestampMs ?? this.getCurrentReferenceTimestampMs(),
1671
+ }),
1667
1672
  (path: string) => this.garbageCollector.isNodeDeleted(path),
1668
1673
  new Map<string, string>(dataStoreAliasMap),
1669
1674
  async (runtime: ChannelCollection) => provideEntryPoint,
@@ -1689,6 +1694,7 @@ export class ContainerRuntime
1689
1694
  this.garbageCollector.nodeUpdated({
1690
1695
  node: { type: "Blob", path: blobPath },
1691
1696
  reason: "Loaded",
1697
+ timestampMs: this.getCurrentReferenceTimestampMs(),
1692
1698
  }),
1693
1699
  isBlobDeleted: (blobPath: string) => this.garbageCollector.isNodeDeleted(blobPath),
1694
1700
  runtime: this,
@@ -2715,7 +2721,11 @@ export class ContainerRuntime
2715
2721
  }
2716
2722
  break;
2717
2723
  case ContainerMessageType.GC:
2718
- this.garbageCollector.processMessage(messageWithContext.message, local);
2724
+ this.garbageCollector.processMessage(
2725
+ messageWithContext.message,
2726
+ messageWithContext.message.timestamp,
2727
+ local,
2728
+ );
2719
2729
  break;
2720
2730
  case ContainerMessageType.ChunkedOp:
2721
2731
  // From observability POV, we should not exppse the rest of the system (including "op" events on object) to these messages.
@@ -2949,6 +2959,7 @@ export class ContainerRuntime
2949
2959
  node: { type: "DataStore", path: `/${internalId}` },
2950
2960
  reason: "Loaded",
2951
2961
  packagePath: context.packagePath,
2962
+ timestampMs: this.getCurrentReferenceTimestampMs(),
2952
2963
  });
2953
2964
  return channel.entryPoint;
2954
2965
  }
@@ -3402,9 +3413,25 @@ export class ContainerRuntime
3402
3413
  * all references added in the system.
3403
3414
  * @param fromPath - The absolute path of the node that added the reference.
3404
3415
  * @param toPath - The absolute path of the outbound node that is referenced.
3416
+ * @param messageTimestampMs - The timestamp of the message that added the reference.
3405
3417
  */
3406
- public addedGCOutboundRoute(fromPath: string, toPath: string) {
3407
- this.garbageCollector.addedOutboundReference(fromPath, toPath);
3418
+ public addedGCOutboundRoute(fromPath: string, toPath: string, messageTimestampMs?: number) {
3419
+ // This is always called when processing an op so messageTimestampMs should exist. Due to back-compat
3420
+ // across the data store runtime / container runtime boundary, this may be undefined and if so, get
3421
+ // the timestamp from the last processed message which should exist.
3422
+ // If a timestamp doesn't exist, log so we can learn about these cases and return.
3423
+ const timestampMs = messageTimestampMs ?? this.getCurrentReferenceTimestampMs();
3424
+ if (timestampMs === undefined) {
3425
+ this.mc.logger.sendTelemetryEvent({
3426
+ eventName: "NoTimestampInGCOutboundRoute",
3427
+ ...tagCodeArtifacts({
3428
+ id: toPath,
3429
+ fromId: fromPath,
3430
+ }),
3431
+ });
3432
+ return;
3433
+ }
3434
+ this.garbageCollector.addedOutboundReference(fromPath, toPath, timestampMs);
3408
3435
  }
3409
3436
 
3410
3437
  /**
@@ -719,9 +719,10 @@ export abstract class FluidDataStoreContext
719
719
  *
720
720
  * @param fromPath - The absolute path of the node that added the reference.
721
721
  * @param toPath - The absolute path of the outbound node that is referenced.
722
+ * @param messageTimestampMs - The timestamp of the message that added the reference.
722
723
  */
723
- public addedGCOutboundRoute(fromPath: string, toPath: string) {
724
- this.parentContext.addedGCOutboundRoute(fromPath, toPath);
724
+ public addedGCOutboundRoute(fromPath: string, toPath: string, messageTimestampMs?: number) {
725
+ this.parentContext.addedGCOutboundRoute(fromPath, toPath, messageTimestampMs);
725
726
  }
726
727
 
727
728
  /**
@@ -892,9 +892,14 @@ export class GarbageCollector implements IGarbageCollector {
892
892
  /**
893
893
  * Process a GC message.
894
894
  * @param message - The GC message from the container runtime.
895
+ * @param messageTimestampMs - The timestamp of the message.
895
896
  * @param local - Whether it was send by this client.
896
897
  */
897
- public processMessage(message: ContainerRuntimeGCMessage, local: boolean) {
898
+ public processMessage(
899
+ message: ContainerRuntimeGCMessage,
900
+ messageTimestampMs: number,
901
+ local: boolean,
902
+ ) {
898
903
  const gcMessageType = message.contents.type;
899
904
  switch (gcMessageType) {
900
905
  case GarbageCollectionMessageType.Sweep: {
@@ -909,7 +914,12 @@ export class GarbageCollector implements IGarbageCollector {
909
914
 
910
915
  // Mark the node as referenced to ensure it isn't Swept
911
916
  const tombstonedNodePath = message.contents.nodePath;
912
- this.addedOutboundReference("/", tombstonedNodePath, true /* autorecovery */);
917
+ this.addedOutboundReference(
918
+ "/",
919
+ tombstonedNodePath,
920
+ messageTimestampMs,
921
+ true /* autorecovery */,
922
+ );
913
923
 
914
924
  // In case the cause of the TombstoneLoaded event is incorrect GC Data (i.e. the object is actually reachable),
915
925
  // do fullGC on the next run to get a chance to repair (in the likely case the bug is not deterministic)
@@ -990,7 +1000,9 @@ export class GarbageCollector implements IGarbageCollector {
990
1000
  request,
991
1001
  headerData,
992
1002
  }: IGCNodeUpdatedProps) {
993
- if (!this.shouldRunGC) {
1003
+ // If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
1004
+ // logging as nothing interesting would have happened worth logging.
1005
+ if (!this.shouldRunGC || timestampMs === undefined) {
994
1006
  return;
995
1007
  }
996
1008
 
@@ -1005,8 +1017,7 @@ export class GarbageCollector implements IGarbageCollector {
1005
1017
  this.telemetryTracker.nodeUsed(trackedId, {
1006
1018
  id: fullPath,
1007
1019
  usageType: reason,
1008
- currentReferenceTimestampMs:
1009
- timestampMs ?? this.runtime.getCurrentReferenceTimestampMs(),
1020
+ currentReferenceTimestampMs: timestampMs,
1010
1021
  packagePath,
1011
1022
  completedGCRuns: this.completedRuns,
1012
1023
  isTombstoned,
@@ -1096,9 +1107,15 @@ export class GarbageCollector implements IGarbageCollector {
1096
1107
  *
1097
1108
  * @param fromNodePath - The node from which the reference is added.
1098
1109
  * @param toNodePath - The node to which the reference is added.
1110
+ * @param timestampMs - The timestamp of the message that added the reference.
1099
1111
  * @param autorecovery - This reference is added artificially, for autorecovery. Used for logging.
1100
1112
  */
1101
- public addedOutboundReference(fromNodePath: string, toNodePath: string, autorecovery?: true) {
1113
+ public addedOutboundReference(
1114
+ fromNodePath: string,
1115
+ toNodePath: string,
1116
+ timestampMs: number,
1117
+ autorecovery?: true,
1118
+ ) {
1102
1119
  if (!this.shouldRunGC) {
1103
1120
  return;
1104
1121
  }
@@ -1129,7 +1146,7 @@ export class GarbageCollector implements IGarbageCollector {
1129
1146
  id: toNodePath,
1130
1147
  fromId: fromNodePath,
1131
1148
  usageType: "Revived",
1132
- currentReferenceTimestampMs: this.runtime.getCurrentReferenceTimestampMs(),
1149
+ currentReferenceTimestampMs: timestampMs,
1133
1150
  packagePath: undefined,
1134
1151
  completedGCRuns: this.completedRuns,
1135
1152
  isTombstoned: this.tombstones.includes(trackedId),
@@ -365,9 +365,18 @@ export interface IGarbageCollector {
365
365
  */
366
366
  nodeUpdated(props: IGCNodeUpdatedProps): void;
367
367
  /** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */
368
- addedOutboundReference(fromNodePath: string, toNodePath: string, autorecovery?: true): void;
368
+ addedOutboundReference(
369
+ fromNodePath: string,
370
+ toNodePath: string,
371
+ timestampMs: number,
372
+ autorecovery?: true,
373
+ ): void;
369
374
  /** Called to process a garbage collection message. */
370
- processMessage(message: ContainerRuntimeGCMessage, local: boolean): void;
375
+ processMessage(
376
+ message: ContainerRuntimeGCMessage,
377
+ messageTimestampMs: number,
378
+ local: boolean,
379
+ ): void;
371
380
  /** Returns true if this node has been deleted by GC during sweep phase. */
372
381
  isNodeDeleted(nodePath: string): boolean;
373
382
  setConnectionState(connected: boolean, clientId?: string): void;
@@ -383,8 +392,11 @@ export interface IGCNodeUpdatedProps {
383
392
  node: { type: (typeof GCNodeType)["DataStore" | "Blob"]; path: string };
384
393
  /** Whether the node (or a subpath) was loaded or changed. */
385
394
  reason: "Loaded" | "Changed";
386
- /** The op-based timestamp when the node changed, if applicable */
387
- timestampMs?: number;
395
+ /**
396
+ * The op-based timestamp when the node changed. If the update is from receiving an op, this should
397
+ * be the timestamp of the op. If not, this should be the timestamp of the last op processed.
398
+ */
399
+ timestampMs: number | undefined;
388
400
  /** The package path of the node. This may not be available if the node hasn't been loaded yet */
389
401
  packagePath?: readonly string[];
390
402
  /** The original request for loads to preserve it in telemetry */
@@ -63,7 +63,7 @@ interface INodeUsageProps extends ICommonProps {
63
63
  /** The full path (in GC Path format) to the node in question */
64
64
  id: string;
65
65
  /** Latest timestamp received from the server, as a baseline for computing GC state/age */
66
- currentReferenceTimestampMs: number | undefined;
66
+ currentReferenceTimestampMs: number;
67
67
  /** The package path of the node. This may not be available if the node hasn't been loaded yet */
68
68
  packagePath: readonly string[] | undefined;
69
69
  /** In case of Revived - what node added the reference? */
@@ -165,12 +165,6 @@ export class GCTelemetryTracker {
165
165
  ...otherNodeUsageProps
166
166
  }: INodeUsageProps,
167
167
  ) {
168
- // If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
169
- // logging as nothing interesting would have happened worth logging.
170
- if (currentReferenceTimestampMs === undefined) {
171
- return;
172
- }
173
-
174
168
  // Note: For SubDataStore Load usage, trackedId will be the DataStore's id, not the full path in question.
175
169
  // This is necessary because the SubDataStore path may be unrecognized by GC (if suited for a custom request handler)
176
170
  const nodeStateTracker = this.getNodeStateTracker(trackedId);
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-dev-rc.5.0.0.271717";
9
+ export const pkgVersion = "2.0.0-dev-rc.5.0.0.272251";
package/tsdoc.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
3
+ "extends": ["../../../common/build/build-common/tsdoc-base.json"]
4
+ }