@fluidframework/container-runtime 2.0.0-dev.4.4.0.161516 → 2.0.0-dev.4.4.0.161784

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 (51) hide show
  1. package/dist/blobManager.d.ts.map +1 -1
  2. package/dist/blobManager.js +3 -2
  3. package/dist/blobManager.js.map +1 -1
  4. package/dist/gc/garbageCollection.d.ts +53 -43
  5. package/dist/gc/garbageCollection.d.ts.map +1 -1
  6. package/dist/gc/garbageCollection.js +210 -199
  7. package/dist/gc/garbageCollection.js.map +1 -1
  8. package/dist/gc/gcHelpers.d.ts +11 -1
  9. package/dist/gc/gcHelpers.d.ts.map +1 -1
  10. package/dist/gc/gcHelpers.js +18 -3
  11. package/dist/gc/gcHelpers.js.map +1 -1
  12. package/dist/gc/gcTelemetry.d.ts +2 -2
  13. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  14. package/dist/gc/gcTelemetry.js +42 -22
  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 +2 -1
  19. package/dist/gc/index.js.map +1 -1
  20. package/dist/packageVersion.d.ts +1 -1
  21. package/dist/packageVersion.js +1 -1
  22. package/dist/packageVersion.js.map +1 -1
  23. package/lib/blobManager.d.ts.map +1 -1
  24. package/lib/blobManager.js +3 -2
  25. package/lib/blobManager.js.map +1 -1
  26. package/lib/gc/garbageCollection.d.ts +53 -43
  27. package/lib/gc/garbageCollection.d.ts.map +1 -1
  28. package/lib/gc/garbageCollection.js +210 -199
  29. package/lib/gc/garbageCollection.js.map +1 -1
  30. package/lib/gc/gcHelpers.d.ts +11 -1
  31. package/lib/gc/gcHelpers.d.ts.map +1 -1
  32. package/lib/gc/gcHelpers.js +16 -2
  33. package/lib/gc/gcHelpers.js.map +1 -1
  34. package/lib/gc/gcTelemetry.d.ts +2 -2
  35. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  36. package/lib/gc/gcTelemetry.js +43 -23
  37. package/lib/gc/gcTelemetry.js.map +1 -1
  38. package/lib/gc/index.d.ts +1 -1
  39. package/lib/gc/index.d.ts.map +1 -1
  40. package/lib/gc/index.js +1 -1
  41. package/lib/gc/index.js.map +1 -1
  42. package/lib/packageVersion.d.ts +1 -1
  43. package/lib/packageVersion.js +1 -1
  44. package/lib/packageVersion.js.map +1 -1
  45. package/package.json +15 -15
  46. package/src/blobManager.ts +3 -2
  47. package/src/gc/garbageCollection.ts +264 -251
  48. package/src/gc/gcHelpers.ts +20 -2
  49. package/src/gc/gcTelemetry.ts +52 -37
  50. package/src/gc/index.ts +1 -0
  51. package/src/packageVersion.ts +1 -1
@@ -6,11 +6,7 @@
6
6
  import { ITelemetryGenericEvent, ITelemetryLogger } from "@fluidframework/common-definitions";
7
7
  import { IGarbageCollectionData } from "@fluidframework/runtime-definitions";
8
8
  import { packagePathToTelemetryProperty } from "@fluidframework/runtime-utils";
9
- import {
10
- generateStack,
11
- MonitoringContext,
12
- TelemetryDataTag,
13
- } from "@fluidframework/telemetry-utils";
9
+ import { generateStack, MonitoringContext } from "@fluidframework/telemetry-utils";
14
10
  import { ICreateContainerMetadata } from "../summary";
15
11
  import {
16
12
  disableSweepLogKey,
@@ -23,6 +19,7 @@ import {
23
19
  runSweepKey,
24
20
  } from "./gcDefinitions";
25
21
  import { UnreferencedStateTracker } from "./gcUnreferencedStateTracker";
22
+ import { tagAsCodeArtifact } from "./gcHelpers";
26
23
 
27
24
  type NodeUsageType = "Changed" | "Loaded" | "Revived";
28
25
 
@@ -32,25 +29,32 @@ interface ICommonProps {
32
29
  completedGCRuns: number;
33
30
  isTombstoned: boolean;
34
31
  lastSummaryTime?: number;
35
- fromId?: string;
36
32
  viaHandle?: boolean;
37
33
  }
38
34
 
39
35
  /** The event that is logged when unreferenced node is used after a certain time. */
40
36
  interface IUnreferencedEventProps extends ICreateContainerMetadata, ICommonProps {
41
37
  state: UnreferencedState;
42
- id: string;
38
+ id: {
39
+ value: string;
40
+ tag: string;
41
+ };
43
42
  type: GCNodeType;
44
43
  unrefTime: number;
45
44
  age: number;
46
45
  timeout?: number;
46
+ fromId?: {
47
+ value: string;
48
+ tag: string;
49
+ };
47
50
  }
48
51
 
49
52
  /** Properties passed to nodeUsed function when a node is used. */
50
53
  interface INodeUsageProps extends ICommonProps {
51
- nodeId: string;
54
+ id: string;
52
55
  currentReferenceTimestampMs: number | undefined;
53
56
  packagePath: readonly string[] | undefined;
57
+ fromId?: string;
54
58
  }
55
59
 
56
60
  /**
@@ -125,18 +129,18 @@ export class GCTelemetryTracker {
125
129
  // If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
126
130
  // logging as nothing interesting would have happened worth logging.
127
131
  // If the node is not unreferenced, skip logging.
128
- const nodeStateTracker = this.getNodeStateTracker(nodeUsageProps.nodeId);
132
+ const nodeStateTracker = this.getNodeStateTracker(nodeUsageProps.id);
129
133
  if (!nodeStateTracker || nodeUsageProps.currentReferenceTimestampMs === undefined) {
130
134
  return;
131
135
  }
132
136
 
133
137
  // We log these events once per event per node. A unique id is generated by joining node state (inactive / sweep ready),
134
138
  // node's id and usage (loaded / changed / revived).
135
- const uniqueEventId = `${nodeStateTracker.state}-${nodeUsageProps.nodeId}-${nodeUsageProps.usageType}`;
136
- const nodeType = this.getNodeType(nodeUsageProps.nodeId);
139
+ const uniqueEventId = `${nodeStateTracker.state}-${nodeUsageProps.id}-${nodeUsageProps.usageType}`;
140
+ const nodeType = this.getNodeType(nodeUsageProps.id);
137
141
  if (
138
142
  !this.shouldLogNonActiveEvent(
139
- nodeUsageProps.nodeId,
143
+ nodeUsageProps.id,
140
144
  nodeType,
141
145
  nodeUsageProps.usageType,
142
146
  nodeStateTracker,
@@ -150,10 +154,10 @@ export class GCTelemetryTracker {
150
154
  this.loggedUnreferencedEvents.add(uniqueEventId);
151
155
 
152
156
  const state = nodeStateTracker.state;
153
- const { usageType, currentReferenceTimestampMs, packagePath, ...propsToLog } =
157
+ const { usageType, currentReferenceTimestampMs, packagePath, id, fromId, ...propsToLog } =
154
158
  nodeUsageProps;
155
159
  const eventProps: Omit<IUnreferencedEventProps, "state" | "usageType"> = {
156
- id: nodeUsageProps.nodeId,
160
+ id: tagAsCodeArtifact(id),
157
161
  type: nodeType,
158
162
  unrefTime: nodeStateTracker.unreferencedTimestampMs,
159
163
  age:
@@ -163,6 +167,7 @@ export class GCTelemetryTracker {
163
167
  state === UnreferencedState.Inactive
164
168
  ? this.configs.inactiveTimeoutMs
165
169
  : this.configs.sweepTimeoutMs,
170
+ fromId: fromId ? tagAsCodeArtifact(fromId) : undefined,
166
171
  ...propsToLog,
167
172
  ...this.createContainerMetadata,
168
173
  };
@@ -175,7 +180,7 @@ export class GCTelemetryTracker {
175
180
  {
176
181
  eventName: `GC_Tombstone_${nodeType}_Revived`,
177
182
  category: "generic",
178
- url: nodeUsageProps.nodeId,
183
+ url: tagAsCodeArtifact(id),
179
184
  gcTombstoneEnforcementAllowed: this.gcTombstoneEnforcementAllowed,
180
185
  },
181
186
  undefined /* packagePath */,
@@ -199,11 +204,16 @@ export class GCTelemetryTracker {
199
204
  // Events generated:
200
205
  // InactiveObject_Loaded, SweepReadyObject_Loaded
201
206
  if (nodeUsageProps.usageType === "Loaded") {
207
+ const { id: taggedId, fromId: taggedFromId, ...otherProps } = eventProps;
202
208
  const event = {
203
209
  eventName: `${state}Object_${nodeUsageProps.usageType}`,
204
210
  pkg: packagePathToTelemetryProperty(nodeUsageProps.packagePath),
205
211
  stack: generateStack(),
206
- ...eventProps,
212
+ id: taggedId,
213
+ fromId: taggedFromId,
214
+ details: JSON.stringify({
215
+ ...otherProps,
216
+ }),
207
217
  };
208
218
 
209
219
  // Do not log the inactive object x events as error events as they are not the best signal for
@@ -263,8 +273,8 @@ export class GCTelemetryTracker {
263
273
  if (missingExplicitRoutes.length > 0) {
264
274
  logger.sendErrorEvent({
265
275
  eventName: "gcUnknownOutboundReferences",
266
- gcNodeId: nodeId,
267
- gcRoutes: JSON.stringify(missingExplicitRoutes),
276
+ id: tagAsCodeArtifact(nodeId),
277
+ routes: tagAsCodeArtifact(JSON.stringify(missingExplicitRoutes)),
268
278
  });
269
279
  }
270
280
  }
@@ -281,31 +291,31 @@ export class GCTelemetryTracker {
281
291
  // InactiveObject_Loaded, InactiveObject_Changed, InactiveObject_Revived
282
292
  // SweepReadyObject_Loaded, SweepReadyObject_Changed, SweepReadyObject_Revived
283
293
  for (const eventProps of this.pendingEventsQueue) {
284
- const { usageType, state, ...propsToLog } = eventProps;
294
+ const { usageType, state, id, fromId, ...propsToLog } = eventProps;
285
295
  /**
286
296
  * Revived event is logged only if the node is active. If the node is not active, the reference to it was
287
297
  * from another unreferenced node and this scenario is not interesting to log.
288
298
  * Loaded and Changed events are logged only if the node is not active. If the node is active, it was
289
299
  * revived and a Revived event will be logged for it.
290
300
  */
291
- const nodeStateTracker = this.getNodeStateTracker(eventProps.id);
301
+ const nodeStateTracker = this.getNodeStateTracker(eventProps.id.value);
292
302
  const active =
293
303
  nodeStateTracker === undefined ||
294
304
  nodeStateTracker.state === UnreferencedState.Active;
295
305
  if ((usageType === "Revived") === active) {
296
- const pkg = await this.getNodePackagePath(eventProps.id);
306
+ const pkg = await this.getNodePackagePath(eventProps.id.value);
297
307
  const fromPkg = eventProps.fromId
298
- ? await this.getNodePackagePath(eventProps.fromId)
308
+ ? await this.getNodePackagePath(eventProps.fromId.value)
299
309
  : undefined;
300
310
  const event = {
301
- ...propsToLog,
302
311
  eventName: `${state}Object_${usageType}`,
303
- pkg: pkg
304
- ? { value: pkg.join("/"), tag: TelemetryDataTag.CodeArtifact }
305
- : undefined,
306
- fromPkg: fromPkg
307
- ? { value: fromPkg.join("/"), tag: TelemetryDataTag.CodeArtifact }
308
- : undefined,
312
+ details: JSON.stringify({
313
+ ...propsToLog,
314
+ }),
315
+ id,
316
+ fromId,
317
+ pkg: pkg ? tagAsCodeArtifact(pkg.join("/")) : undefined,
318
+ fromPkg: fromPkg ? tagAsCodeArtifact(fromPkg.join("/")) : undefined,
309
319
  };
310
320
 
311
321
  if (state === UnreferencedState.Inactive) {
@@ -336,6 +346,7 @@ export class GCTelemetryTracker {
336
346
  return;
337
347
  }
338
348
 
349
+ const deletedNodeIds: string[] = [];
339
350
  for (const [nodeId, nodeStateTracker] of unreferencedNodesState) {
340
351
  if (nodeStateTracker.state !== UnreferencedState.SweepReady) {
341
352
  return;
@@ -352,15 +363,19 @@ export class GCTelemetryTracker {
352
363
  return;
353
364
  }
354
365
  this.loggedUnreferencedEvents.add(uniqueEventId);
366
+ deletedNodeIds.push(nodeId);
367
+ }
368
+
369
+ if (deletedNodeIds.length > 0) {
355
370
  logger.sendTelemetryEvent({
356
- eventName: "GCObjectDeleted",
357
- id: nodeId,
358
- type: nodeType,
359
- age: currentReferenceTimestampMs - nodeStateTracker.unreferencedTimestampMs,
360
- timeout: this.configs.sweepTimeoutMs,
361
- completedGCRuns,
362
- lastSummaryTime,
363
- ...this.createContainerMetadata,
371
+ eventName: "GC_SweepReadyObjects_Delete",
372
+ details: JSON.stringify({
373
+ timeout: this.configs.sweepTimeoutMs,
374
+ completedGCRuns,
375
+ lastSummaryTime,
376
+ ...this.createContainerMetadata,
377
+ }),
378
+ id: tagAsCodeArtifact(JSON.stringify(deletedNodeIds)),
364
379
  });
365
380
  }
366
381
  }
package/src/gc/index.ts CHANGED
@@ -43,6 +43,7 @@ export {
43
43
  shouldAllowGcSweep,
44
44
  trimLeadingAndTrailingSlashes,
45
45
  unpackChildNodesGCDetails,
46
+ tagAsCodeArtifact,
46
47
  } from "./gcHelpers";
47
48
  export { runGarbageCollection } from "./gcReferenceGraphAlgorithm";
48
49
  export {
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-dev.4.4.0.161516";
9
+ export const pkgVersion = "2.0.0-dev.4.4.0.161784";