@fluidframework/container-runtime 0.57.0-51086 → 0.58.0-55561

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 (114) hide show
  1. package/dist/batchTracker.d.ts +26 -0
  2. package/dist/batchTracker.d.ts.map +1 -0
  3. package/dist/batchTracker.js +59 -0
  4. package/dist/batchTracker.js.map +1 -0
  5. package/dist/containerRuntime.d.ts +12 -7
  6. package/dist/containerRuntime.d.ts.map +1 -1
  7. package/dist/containerRuntime.js +125 -55
  8. package/dist/containerRuntime.js.map +1 -1
  9. package/dist/dataStore.d.ts +1 -36
  10. package/dist/dataStore.d.ts.map +1 -1
  11. package/dist/dataStore.js +5 -27
  12. package/dist/dataStore.js.map +1 -1
  13. package/dist/dataStoreContext.d.ts +5 -7
  14. package/dist/dataStoreContext.d.ts.map +1 -1
  15. package/dist/dataStoreContext.js +12 -7
  16. package/dist/dataStoreContext.js.map +1 -1
  17. package/dist/dataStores.d.ts +1 -1
  18. package/dist/dataStores.d.ts.map +1 -1
  19. package/dist/dataStores.js +3 -3
  20. package/dist/dataStores.js.map +1 -1
  21. package/dist/garbageCollection.d.ts +25 -11
  22. package/dist/garbageCollection.d.ts.map +1 -1
  23. package/dist/garbageCollection.js +100 -57
  24. package/dist/garbageCollection.js.map +1 -1
  25. package/dist/index.d.ts +0 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/packageVersion.d.ts +1 -1
  30. package/dist/packageVersion.js +1 -1
  31. package/dist/packageVersion.js.map +1 -1
  32. package/dist/pendingStateManager.d.ts.map +1 -1
  33. package/dist/pendingStateManager.js +1 -6
  34. package/dist/pendingStateManager.js.map +1 -1
  35. package/dist/runningSummarizer.d.ts +1 -1
  36. package/dist/runningSummarizer.d.ts.map +1 -1
  37. package/dist/runningSummarizer.js +1 -1
  38. package/dist/runningSummarizer.js.map +1 -1
  39. package/dist/summarizer.d.ts +3 -4
  40. package/dist/summarizer.d.ts.map +1 -1
  41. package/dist/summarizer.js +8 -9
  42. package/dist/summarizer.js.map +1 -1
  43. package/dist/summaryGenerator.d.ts +1 -1
  44. package/dist/summaryGenerator.d.ts.map +1 -1
  45. package/dist/summaryGenerator.js +1 -1
  46. package/dist/summaryGenerator.js.map +1 -1
  47. package/dist/summaryManager.d.ts +2 -6
  48. package/dist/summaryManager.d.ts.map +1 -1
  49. package/dist/summaryManager.js +4 -10
  50. package/dist/summaryManager.js.map +1 -1
  51. package/lib/batchTracker.d.ts +26 -0
  52. package/lib/batchTracker.d.ts.map +1 -0
  53. package/lib/batchTracker.js +54 -0
  54. package/lib/batchTracker.js.map +1 -0
  55. package/lib/containerRuntime.d.ts +12 -7
  56. package/lib/containerRuntime.d.ts.map +1 -1
  57. package/lib/containerRuntime.js +126 -56
  58. package/lib/containerRuntime.js.map +1 -1
  59. package/lib/dataStore.d.ts +1 -36
  60. package/lib/dataStore.d.ts.map +1 -1
  61. package/lib/dataStore.js +4 -26
  62. package/lib/dataStore.js.map +1 -1
  63. package/lib/dataStoreContext.d.ts +5 -7
  64. package/lib/dataStoreContext.d.ts.map +1 -1
  65. package/lib/dataStoreContext.js +13 -8
  66. package/lib/dataStoreContext.js.map +1 -1
  67. package/lib/dataStores.d.ts +1 -1
  68. package/lib/dataStores.d.ts.map +1 -1
  69. package/lib/dataStores.js +3 -3
  70. package/lib/dataStores.js.map +1 -1
  71. package/lib/garbageCollection.d.ts +25 -11
  72. package/lib/garbageCollection.d.ts.map +1 -1
  73. package/lib/garbageCollection.js +98 -55
  74. package/lib/garbageCollection.js.map +1 -1
  75. package/lib/index.d.ts +0 -1
  76. package/lib/index.d.ts.map +1 -1
  77. package/lib/index.js +0 -1
  78. package/lib/index.js.map +1 -1
  79. package/lib/packageVersion.d.ts +1 -1
  80. package/lib/packageVersion.js +1 -1
  81. package/lib/packageVersion.js.map +1 -1
  82. package/lib/pendingStateManager.d.ts.map +1 -1
  83. package/lib/pendingStateManager.js +1 -6
  84. package/lib/pendingStateManager.js.map +1 -1
  85. package/lib/runningSummarizer.d.ts +1 -1
  86. package/lib/runningSummarizer.d.ts.map +1 -1
  87. package/lib/runningSummarizer.js +1 -1
  88. package/lib/runningSummarizer.js.map +1 -1
  89. package/lib/summarizer.d.ts +3 -4
  90. package/lib/summarizer.d.ts.map +1 -1
  91. package/lib/summarizer.js +8 -9
  92. package/lib/summarizer.js.map +1 -1
  93. package/lib/summaryGenerator.d.ts +1 -1
  94. package/lib/summaryGenerator.d.ts.map +1 -1
  95. package/lib/summaryGenerator.js +1 -1
  96. package/lib/summaryGenerator.js.map +1 -1
  97. package/lib/summaryManager.d.ts +2 -6
  98. package/lib/summaryManager.d.ts.map +1 -1
  99. package/lib/summaryManager.js +5 -11
  100. package/lib/summaryManager.js.map +1 -1
  101. package/package.json +12 -12
  102. package/src/batchTracker.ts +80 -0
  103. package/src/containerRuntime.ts +180 -63
  104. package/src/dataStore.ts +6 -42
  105. package/src/dataStoreContext.ts +17 -15
  106. package/src/dataStores.ts +9 -4
  107. package/src/garbageCollection.ts +125 -67
  108. package/src/index.ts +0 -1
  109. package/src/packageVersion.ts +1 -1
  110. package/src/pendingStateManager.ts +4 -8
  111. package/src/runningSummarizer.ts +3 -3
  112. package/src/summarizer.ts +8 -8
  113. package/src/summaryGenerator.ts +2 -2
  114. package/src/summaryManager.ts +5 -20
@@ -12,6 +12,7 @@ import { IGCRuntimeOptions } from "./containerRuntime";
12
12
  import { IContainerRuntimeMetadata } from "./summaryFormat";
13
13
  export declare const gcTreeKey = "gc";
14
14
  export declare const gcBlobPrefix = "__gc";
15
+ export declare const defaultSessionExpiryDurationMs: number;
15
16
  /** The statistics of the system state after a garbage collection run. */
16
17
  export interface IGCStats {
17
18
  /** The number of nodes in the container. */
@@ -35,6 +36,8 @@ export interface IGarbageCollectionRuntime {
35
36
  getGCData(fullGC?: boolean): Promise<IGarbageCollectionData>;
36
37
  /** After GC has run, called to notify the runtime of routes that are used in it. */
37
38
  updateUsedRoutes(usedRoutes: string[], gcTimestamp?: number): void;
39
+ /** Called when the runtime should close because of an error. */
40
+ closeFn(error?: ICriticalContainerError): void;
38
41
  }
39
42
  /** Defines the contract for the garbage collector. */
40
43
  export interface IGarbageCollector {
@@ -66,7 +69,7 @@ export interface IGarbageCollector {
66
69
  /** Called when the latest summary of the system has been refreshed. */
67
70
  latestSummaryStateRefreshed(result: RefreshSummaryResult, readAndParseBlob: ReadAndParseBlob): Promise<void>;
68
71
  /** Called when a node is updated. Used to detect and log when an inactive node is changed or loaded. */
69
- nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
72
+ nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", timestampMs?: number, packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
70
73
  /** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */
71
74
  addedOutboundReference(fromNodePath: string, toNodePath: string): void;
72
75
  dispose(): void;
@@ -82,10 +85,15 @@ export declare class GarbageCollector implements IGarbageCollector {
82
85
  private readonly deleteUnusedRoutes;
83
86
  /** For a given node path, returns the node's package path. */
84
87
  private readonly getNodePackagePath;
85
- /** Returns the current timestamp to be assigned to nodes that become unreferenced. */
86
- private readonly getCurrentTimestampMs;
87
- private readonly closeFn;
88
- static create(provider: IGarbageCollectionRuntime, gcOptions: IGCRuntimeOptions, deleteUnusedRoutes: (unusedRoutes: string[]) => void, getNodePackagePath: (nodeId: string) => readonly string[] | undefined, getCurrentTimestampMs: () => number, closeFn: (error?: ICriticalContainerError) => void, baseSnapshot: ISnapshotTree | undefined, readAndParseBlob: ReadAndParseBlob, baseLogger: ITelemetryLogger, existing: boolean, metadata?: IContainerRuntimeMetadata): IGarbageCollector;
88
+ /**
89
+ * Returns a referenced timestamp to be used to track unreferenced nodes. This is a server generated timestamp
90
+ * and may not be available if there aren't any ops processed yet. If so, we skip tracking unreferenced state
91
+ * such as time when node becomes unreferenced or inactive.
92
+ */
93
+ private readonly getCurrentReferenceTimestampMs;
94
+ /** Returns the timestamp of the last summary generated for this container. */
95
+ private readonly getLastSummaryTimestampMs;
96
+ static create(provider: IGarbageCollectionRuntime, gcOptions: IGCRuntimeOptions, deleteUnusedRoutes: (unusedRoutes: string[]) => void, getNodePackagePath: (nodeId: string) => readonly string[] | undefined, getCurrentReferenceTimestampMs: () => number | undefined, getLastSummaryTimestampMs: () => number | undefined, baseSnapshot: ISnapshotTree | undefined, readAndParseBlob: ReadAndParseBlob, baseLogger: ITelemetryLogger, existing: boolean, metadata?: IContainerRuntimeMetadata): IGarbageCollector;
89
97
  /**
90
98
  * Tells whether GC should be run based on the GC options and local storage flags.
91
99
  */
@@ -149,8 +157,14 @@ export declare class GarbageCollector implements IGarbageCollector {
149
157
  deleteUnusedRoutes: (unusedRoutes: string[]) => void,
150
158
  /** For a given node path, returns the node's package path. */
151
159
  getNodePackagePath: (nodePath: string) => readonly string[] | undefined,
152
- /** Returns the current timestamp to be assigned to nodes that become unreferenced. */
153
- getCurrentTimestampMs: () => number, closeFn: (error?: ICriticalContainerError) => void, baseSnapshot: ISnapshotTree | undefined, readAndParseBlob: ReadAndParseBlob, baseLogger: ITelemetryLogger, existing: boolean, metadata?: IContainerRuntimeMetadata);
160
+ /**
161
+ * Returns a referenced timestamp to be used to track unreferenced nodes. This is a server generated timestamp
162
+ * and may not be available if there aren't any ops processed yet. If so, we skip tracking unreferenced state
163
+ * such as time when node becomes unreferenced or inactive.
164
+ */
165
+ getCurrentReferenceTimestampMs: () => number | undefined,
166
+ /** Returns the timestamp of the last summary generated for this container. */
167
+ getLastSummaryTimestampMs: () => number | undefined, baseSnapshot: ISnapshotTree | undefined, readAndParseBlob: ReadAndParseBlob, baseLogger: ITelemetryLogger, existing: boolean, metadata?: IContainerRuntimeMetadata);
154
168
  /**
155
169
  * Runs garbage collection and udpates the reference / used state of the nodes in the container.
156
170
  * @returns the number of data stores that have been marked as unreferenced.
@@ -183,10 +197,11 @@ export declare class GarbageCollector implements IGarbageCollector {
183
197
  * Called when a node with the given id is updated. If the node is inactive, log an error.
184
198
  * @param nodePath - The id of the node that changed.
185
199
  * @param reason - Whether the node was loaded or changed.
200
+ * @param timestampMs - The timestamp when the node changed.
186
201
  * @param packagePath - The package path of the node. This may not be available if the node hasn't been loaded yet.
187
202
  * @param requestHeaders - If the node was loaded via request path, the headers in the request.
188
203
  */
189
- nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
204
+ nodeUpdated(nodePath: string, reason: "Loaded" | "Changed", timestampMs?: number, packagePath?: readonly string[], requestHeaders?: IRequestHeader): void;
190
205
  /**
191
206
  * Called when an outbound reference is added to a node. This is used to identify all nodes that have been
192
207
  * referenced between summaries so that their unreferenced timestamp can be reset.
@@ -207,7 +222,7 @@ export declare class GarbageCollector implements IGarbageCollector {
207
222
  * 3. Clears tracking for nodes that were unreferenced but became referenced in this run.
208
223
  * @param gcData - The data representing the reference graph on which GC is run.
209
224
  * @param gcResult - The result of the GC run on the gcData.
210
- * @param currentTimestampMs - The current timestamp to be used for unreferenced nodes' timestamp.
225
+ * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
211
226
  */
212
227
  private updateCurrentState;
213
228
  /**
@@ -236,8 +251,7 @@ export declare class GarbageCollector implements IGarbageCollector {
236
251
  */
237
252
  private generateStatsAndLogEvents;
238
253
  /**
239
- * Logs an event if a node is inactive and is used. If the package data for the node exists, log immediately. Else,
240
- * queue it and it will be logged the next time GC runs as the package data should be available then.
254
+ * Logs an event if a node is inactive and is used.
241
255
  */
242
256
  private logIfInactive;
243
257
  }
@@ -1 +1 @@
1
- {"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../src/garbageCollection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"garbageCollection.d.ts","sourceRoot":"","sources":["../src/garbageCollection.ts"],"names":[],"mappings":"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"}
@@ -28,30 +28,48 @@ const writeAtRootKey = "Fluid.GarbageCollection.WriteDataAtRoot";
28
28
  // Feature gate key to expire a session after a set period of time.
29
29
  const runSessionExpiry = "Fluid.GarbageCollection.RunSessionExpiry";
30
30
  const defaultDeleteTimeoutMs = 7 * 24 * 60 * 60 * 1000; // 7 days
31
- const defaultSessionExpiryDurationMs = 30 * 24 * 60 * 60 * 1000; // 30 days
31
+ export const defaultSessionExpiryDurationMs = 30 * 24 * 60 * 60 * 1000; // 30 days
32
32
  ;
33
33
  /**
34
34
  * Helper class that tracks the state of an unreferenced node such as the time it was unreferenced. It also sets
35
35
  * the node's state to inactive if it remains unreferenced for a given amount of time (inactiveTimeoutMs).
36
36
  */
37
37
  class UnreferencedStateTracker {
38
- constructor(unreferencedTimestampMs, inactiveTimeoutMs) {
38
+ constructor(unreferencedTimestampMs, inactiveTimeoutMs, currentReferenceTimestampMs) {
39
39
  this.unreferencedTimestampMs = unreferencedTimestampMs;
40
+ this.inactiveTimeoutMs = inactiveTimeoutMs;
40
41
  this._inactive = false;
41
- // If the timeout has already expired, the node should become inactive immediately. Otherwise, start a timer of
42
- // inactiveTimeoutMs after which the node will become inactive.
43
- if (inactiveTimeoutMs <= 0) {
44
- this._inactive = true;
45
- }
46
- else {
47
- this.timer = new Timer(inactiveTimeoutMs, () => { this._inactive = true; });
48
- this.timer.start();
42
+ // If there is no current reference timestamp, don't track the node's inactive state. This will happen later
43
+ // when updateTracking is called with a reference timestamp.
44
+ if (currentReferenceTimestampMs !== undefined) {
45
+ this.updateTracking(currentReferenceTimestampMs);
49
46
  }
50
47
  }
51
48
  get inactive() {
52
49
  return this._inactive;
53
50
  }
54
- /** Stop tracking this node. Reset the unreferenced timer, if any, and reset inactive state. */
51
+ /**
52
+ * Updates the tracking state based on the provided timestamp.
53
+ */
54
+ updateTracking(currentReferenceTimestampMs) {
55
+ var _a;
56
+ const unreferencedDurationMs = currentReferenceTimestampMs - this.unreferencedTimestampMs;
57
+ // If the timeout has already expired, the node has become inactive.
58
+ if (unreferencedDurationMs > this.inactiveTimeoutMs) {
59
+ this._inactive = true;
60
+ (_a = this.timer) === null || _a === void 0 ? void 0 : _a.clear();
61
+ return;
62
+ }
63
+ // The node isn't inactive yet. Restart a timer for the duration remaining for it to become inactive.
64
+ const remainingDurationMs = this.inactiveTimeoutMs - unreferencedDurationMs;
65
+ if (this.timer === undefined) {
66
+ this.timer = new Timer(remainingDurationMs, () => { this._inactive = true; });
67
+ }
68
+ this.timer.restart(remainingDurationMs);
69
+ }
70
+ /**
71
+ * Stop tracking this node. Reset the unreferenced timer, if any, and reset inactive state.
72
+ */
55
73
  stopTracking() {
56
74
  var _a;
57
75
  (_a = this.timer) === null || _a === void 0 ? void 0 : _a.clear();
@@ -68,15 +86,21 @@ export class GarbageCollector {
68
86
  deleteUnusedRoutes,
69
87
  /** For a given node path, returns the node's package path. */
70
88
  getNodePackagePath,
71
- /** Returns the current timestamp to be assigned to nodes that become unreferenced. */
72
- getCurrentTimestampMs, closeFn, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata) {
89
+ /**
90
+ * Returns a referenced timestamp to be used to track unreferenced nodes. This is a server generated timestamp
91
+ * and may not be available if there aren't any ops processed yet. If so, we skip tracking unreferenced state
92
+ * such as time when node becomes unreferenced or inactive.
93
+ */
94
+ getCurrentReferenceTimestampMs,
95
+ /** Returns the timestamp of the last summary generated for this container. */
96
+ getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata) {
73
97
  var _a, _b, _c, _d, _e;
74
98
  this.provider = provider;
75
99
  this.gcOptions = gcOptions;
76
100
  this.deleteUnusedRoutes = deleteUnusedRoutes;
77
101
  this.getNodePackagePath = getNodePackagePath;
78
- this.getCurrentTimestampMs = getCurrentTimestampMs;
79
- this.closeFn = closeFn;
102
+ this.getCurrentReferenceTimestampMs = getCurrentReferenceTimestampMs;
103
+ this.getLastSummaryTimestampMs = getLastSummaryTimestampMs;
80
104
  /**
81
105
  * Tells whether the GC data should be written to the root of the summary tree.
82
106
  */
@@ -129,7 +153,7 @@ export class GarbageCollector {
129
153
  if (this.sessionExpiryTimeoutMs !== undefined) {
130
154
  const timeoutMs = this.sessionExpiryTimeoutMs;
131
155
  setLongTimeout(timeoutMs, () => {
132
- this.closeFn(new ClientSessionExpiredError(`Client session expired.`, timeoutMs));
156
+ this.provider.closeFn(new ClientSessionExpiredError(`Client session expired.`, timeoutMs));
133
157
  }, (timer) => {
134
158
  this.sessionExpiryTimer = timer;
135
159
  });
@@ -212,22 +236,21 @@ export class GarbageCollector {
212
236
  // very first summary generated by detached container. In both cases, GC was not run - return undefined.
213
237
  return Object.keys(gcState.gcNodes).length === 1 ? undefined : gcState;
214
238
  });
215
- // Set up the initializer which initializes the base GC state from the base snapshot. Use lazy promise because
216
- // we only do this once - the very first time we run GC.
239
+ /**
240
+ * Set up the initializer which initializes the base GC state from the base snapshot. Note that the reference
241
+ * timestamp maybe from old ops which were not summarized and stored in the file. So, the unreferenced state
242
+ * may be out of date. This is fine because the state is updated every time GC runs based on the time then.
243
+ */
217
244
  this.initializeBaseStateP = new LazyPromise(async () => {
218
- const currentTimestampMs = this.getCurrentTimestampMs();
245
+ const currentReferenceTimestampMs = this.getCurrentReferenceTimestampMs();
219
246
  const baseState = await baseSummaryStateP;
220
247
  if (baseState === undefined) {
221
248
  return;
222
249
  }
223
250
  const gcNodes = {};
224
251
  for (const [nodeId, nodeData] of Object.entries(baseState.gcNodes)) {
225
- const unreferencedTimestampMs = nodeData.unreferencedTimestampMs;
226
- if (unreferencedTimestampMs !== undefined) {
227
- // Get how long it has been since the node was unreferenced. Start a timeout for the remaining time
228
- // left for it to be eligible for deletion.
229
- const unreferencedDurationMs = currentTimestampMs - unreferencedTimestampMs;
230
- this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(unreferencedTimestampMs, this.deleteTimeoutMs - unreferencedDurationMs));
252
+ if (nodeData.unreferencedTimestampMs !== undefined) {
253
+ this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(nodeData.unreferencedTimestampMs, this.deleteTimeoutMs, currentReferenceTimestampMs));
231
254
  }
232
255
  gcNodes[nodeId] = Array.from(nodeData.outboundRoutes);
233
256
  }
@@ -265,18 +288,20 @@ export class GarbageCollector {
265
288
  // used in the container.
266
289
  if (this.shouldRunGC) {
267
290
  this.initializeBaseStateP.catch((error) => {
268
- throw new DataProcessingError(error === null || error === void 0 ? void 0 : error.message, "FailedToInitializeGC", {
291
+ const dpe = DataProcessingError.wrapIfUnrecognized(error, "FailedToInitializeGC");
292
+ dpe.addTelemetryProperties({
269
293
  gcEnabled: this.gcEnabled,
270
294
  runSweep: this.shouldRunSweep,
271
295
  writeAtRoot: this._writeDataAtRoot,
272
296
  testMode: this.testMode,
273
297
  sessionExpiry: this.sessionExpiryTimeoutMs,
274
298
  });
299
+ throw dpe;
275
300
  });
276
301
  }
277
302
  }
278
- static create(provider, gcOptions, deleteUnusedRoutes, getNodePackagePath, getCurrentTimestampMs, closeFn, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata) {
279
- return new GarbageCollector(provider, gcOptions, deleteUnusedRoutes, getNodePackagePath, getCurrentTimestampMs, closeFn, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata);
303
+ static create(provider, gcOptions, deleteUnusedRoutes, getNodePackagePath, getCurrentReferenceTimestampMs, getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata) {
304
+ return new GarbageCollector(provider, gcOptions, deleteUnusedRoutes, getNodePackagePath, getCurrentReferenceTimestampMs, getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata);
280
305
  }
281
306
  /**
282
307
  * This tracks two things:
@@ -319,9 +344,9 @@ export class GarbageCollector {
319
344
  // the current run. We need to identify than and update their unreferenced state if needed.
320
345
  this.updateStateSinceLastRun(gcData);
321
346
  // Update the current state of the system based on the GC run.
322
- const currentTimestampMs = this.getCurrentTimestampMs();
323
- this.updateCurrentState(gcData, gcResult, currentTimestampMs);
324
- this.provider.updateUsedRoutes(gcResult.referencedNodeIds, currentTimestampMs);
347
+ const currentReferenceTimestampMs = this.getCurrentReferenceTimestampMs();
348
+ this.updateCurrentState(gcData, gcResult, currentReferenceTimestampMs);
349
+ this.provider.updateUsedRoutes(gcResult.referencedNodeIds, currentReferenceTimestampMs);
325
350
  if (runSweep) {
326
351
  // Placeholder for running sweep logic.
327
352
  }
@@ -387,14 +412,15 @@ export class GarbageCollector {
387
412
  * Called when a node with the given id is updated. If the node is inactive, log an error.
388
413
  * @param nodePath - The id of the node that changed.
389
414
  * @param reason - Whether the node was loaded or changed.
415
+ * @param timestampMs - The timestamp when the node changed.
390
416
  * @param packagePath - The package path of the node. This may not be available if the node hasn't been loaded yet.
391
417
  * @param requestHeaders - If the node was loaded via request path, the headers in the request.
392
418
  */
393
- nodeUpdated(nodePath, reason, packagePath, requestHeaders) {
419
+ nodeUpdated(nodePath, reason, timestampMs, packagePath, requestHeaders) {
394
420
  if (!this.shouldRunGC) {
395
421
  return;
396
422
  }
397
- this.logIfInactive(reason, nodePath, this.getCurrentTimestampMs(), packagePath, requestHeaders);
423
+ this.logIfInactive(reason, nodePath, timestampMs, packagePath, requestHeaders);
398
424
  }
399
425
  /**
400
426
  * Called when an outbound reference is added to a node. This is used to identify all nodes that have been
@@ -412,7 +438,7 @@ export class GarbageCollector {
412
438
  outboundRoutes.push(toNodePath);
413
439
  this.referencesSinceLastRun.set(fromNodePath, outboundRoutes);
414
440
  // If the node that got referenced is inactive, log an event as that may indicate use-after-delete.
415
- this.logIfInactive("Revived", toNodePath, this.getCurrentTimestampMs(), this.getNodePackagePath(toNodePath));
441
+ this.logIfInactive("Revived", toNodePath);
416
442
  }
417
443
  dispose() {
418
444
  if (this.sessionExpiryTimer !== undefined) {
@@ -437,24 +463,11 @@ export class GarbageCollector {
437
463
  * 3. Clears tracking for nodes that were unreferenced but became referenced in this run.
438
464
  * @param gcData - The data representing the reference graph on which GC is run.
439
465
  * @param gcResult - The result of the GC run on the gcData.
440
- * @param currentTimestampMs - The current timestamp to be used for unreferenced nodes' timestamp.
466
+ * @param currentReferenceTimestampMs - The timestamp to be used for unreferenced nodes' timestamp.
441
467
  */
442
- updateCurrentState(gcData, gcResult, currentTimestampMs) {
468
+ updateCurrentState(gcData, gcResult, currentReferenceTimestampMs) {
443
469
  this.gcDataFromLastRun = cloneGCData(gcData);
444
470
  this.referencesSinceLastRun.clear();
445
- // Iterate through the deleted nodes and start tracking if they became unreferenced in this run.
446
- for (const nodeId of gcResult.deletedNodeIds) {
447
- // The time when the node became unreferenced. This is added to the current GC state.
448
- let unreferencedTimestampMs = currentTimestampMs;
449
- const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
450
- if (nodeStateTracker !== undefined) {
451
- unreferencedTimestampMs = nodeStateTracker.unreferencedTimestampMs;
452
- }
453
- else {
454
- // Start tracking this node as it became unreferenced in this run.
455
- this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(unreferencedTimestampMs, this.deleteTimeoutMs));
456
- }
457
- }
458
471
  // Iterate through the referenced nodes and stop tracking if they were unreferenced before.
459
472
  for (const nodeId of gcResult.referencedNodeIds) {
460
473
  const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
@@ -465,6 +478,28 @@ export class GarbageCollector {
465
478
  this.unreferencedNodesState.delete(nodeId);
466
479
  }
467
480
  }
481
+ /**
482
+ * If there is no current reference time, skip tracking when a node becomes unreferenced. This would happen
483
+ * if no ops have been processed ever and we still try to run GC. If so, there is nothing interesting to track
484
+ * anyway.
485
+ */
486
+ if (currentReferenceTimestampMs === undefined) {
487
+ return;
488
+ }
489
+ /**
490
+ * If a node became unreferenced in this run, start tracking it.
491
+ * If a node was already unreferenced, update its tracking information. Since the current reference time is
492
+ * from the ops seen, this will ensure that we keep updating the unreferenced state as time moves forward.
493
+ */
494
+ for (const nodeId of gcResult.deletedNodeIds) {
495
+ const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
496
+ if (nodeStateTracker === undefined) {
497
+ this.unreferencedNodesState.set(nodeId, new UnreferencedStateTracker(currentReferenceTimestampMs, this.deleteTimeoutMs, currentReferenceTimestampMs));
498
+ }
499
+ else {
500
+ nodeStateTracker.updateTracking(currentReferenceTimestampMs);
501
+ }
502
+ }
468
503
  }
469
504
  /**
470
505
  * Since GC runs periodically, the GC data that is generated only tells us the state of the world at that point in
@@ -628,10 +663,14 @@ export class GarbageCollector {
628
663
  return gcStats;
629
664
  }
630
665
  /**
631
- * Logs an event if a node is inactive and is used. If the package data for the node exists, log immediately. Else,
632
- * queue it and it will be logged the next time GC runs as the package data should be available then.
666
+ * Logs an event if a node is inactive and is used.
633
667
  */
634
- logIfInactive(eventSuffix, nodeId, timestampMs, packagePath, requestHeaders) {
668
+ logIfInactive(eventSuffix, nodeId, currentReferenceTimestampMs = this.getCurrentReferenceTimestampMs(), packagePath, requestHeaders) {
669
+ // If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
670
+ // logging as nothing interesting would have happened worth logging.
671
+ if (currentReferenceTimestampMs === undefined) {
672
+ return;
673
+ }
635
674
  const eventName = `inactiveObject_${eventSuffix}`;
636
675
  // We log a particular event for a given node only once so that it is not too noisy.
637
676
  const uniqueEventId = `${nodeId}-${eventName}`;
@@ -641,13 +680,17 @@ export class GarbageCollector {
641
680
  const event = {
642
681
  eventName,
643
682
  id: nodeId,
644
- age: timestampMs - nodeState.unreferencedTimestampMs,
683
+ age: currentReferenceTimestampMs - nodeState.unreferencedTimestampMs,
645
684
  timeout: this.deleteTimeoutMs,
685
+ lastSummaryTime: this.getLastSummaryTimestampMs(),
646
686
  externalRequest: requestHeaders === null || requestHeaders === void 0 ? void 0 : requestHeaders[RuntimeHeaders.externalRequest],
647
687
  viaHandle: requestHeaders === null || requestHeaders === void 0 ? void 0 : requestHeaders[RuntimeHeaders.viaHandle],
648
688
  };
649
- if (packagePath !== undefined) {
650
- this.mc.logger.sendErrorEvent(Object.assign(Object.assign({}, event), { pkg: { value: `/${packagePath.join("/")}`, tag: TelemetryDataTag.PackageData } }));
689
+ // If the package data for the node exists, log immediately. Otherwise, queue it and it will be logged the
690
+ // next time GC runs as the package data should be available then.
691
+ const pkg = packagePath !== null && packagePath !== void 0 ? packagePath : this.getNodePackagePath(nodeId);
692
+ if (pkg !== undefined) {
693
+ this.mc.logger.sendErrorEvent(Object.assign(Object.assign({}, event), { pkg: { value: `/${pkg.join("/")}`, tag: TelemetryDataTag.PackageData } }));
651
694
  }
652
695
  else {
653
696
  this.pendingEventsQueue.push(event);