@fluidframework/container-runtime 1.1.0 → 1.2.0-77818

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/dist/containerRuntime.d.ts +1 -1
  2. package/dist/containerRuntime.d.ts.map +1 -1
  3. package/dist/containerRuntime.js +8 -8
  4. package/dist/containerRuntime.js.map +1 -1
  5. package/dist/dataStore.d.ts +2 -2
  6. package/dist/dataStore.d.ts.map +1 -1
  7. package/dist/dataStore.js +2 -2
  8. package/dist/dataStore.js.map +1 -1
  9. package/dist/dataStoreContext.d.ts +4 -4
  10. package/dist/dataStoreContext.d.ts.map +1 -1
  11. package/dist/dataStoreContext.js.map +1 -1
  12. package/dist/dataStores.d.ts +2 -2
  13. package/dist/dataStores.d.ts.map +1 -1
  14. package/dist/dataStores.js +6 -5
  15. package/dist/dataStores.js.map +1 -1
  16. package/dist/garbageCollection.d.ts +12 -8
  17. package/dist/garbageCollection.d.ts.map +1 -1
  18. package/dist/garbageCollection.js +95 -68
  19. package/dist/garbageCollection.js.map +1 -1
  20. package/dist/packageVersion.d.ts +1 -1
  21. package/dist/packageVersion.d.ts.map +1 -1
  22. package/dist/packageVersion.js +1 -1
  23. package/dist/packageVersion.js.map +1 -1
  24. package/dist/summarizerTypes.d.ts +5 -2
  25. package/dist/summarizerTypes.d.ts.map +1 -1
  26. package/dist/summarizerTypes.js.map +1 -1
  27. package/dist/summaryGenerator.d.ts.map +1 -1
  28. package/dist/summaryGenerator.js +0 -1
  29. package/dist/summaryGenerator.js.map +1 -1
  30. package/garbageCollection.md +7 -7
  31. package/lib/containerRuntime.d.ts +1 -1
  32. package/lib/containerRuntime.d.ts.map +1 -1
  33. package/lib/containerRuntime.js +9 -9
  34. package/lib/containerRuntime.js.map +1 -1
  35. package/lib/dataStore.d.ts +2 -2
  36. package/lib/dataStore.d.ts.map +1 -1
  37. package/lib/dataStore.js +2 -2
  38. package/lib/dataStore.js.map +1 -1
  39. package/lib/dataStoreContext.d.ts +4 -4
  40. package/lib/dataStoreContext.d.ts.map +1 -1
  41. package/lib/dataStoreContext.js.map +1 -1
  42. package/lib/dataStores.d.ts +2 -2
  43. package/lib/dataStores.d.ts.map +1 -1
  44. package/lib/dataStores.js +6 -5
  45. package/lib/dataStores.js.map +1 -1
  46. package/lib/garbageCollection.d.ts +12 -8
  47. package/lib/garbageCollection.d.ts.map +1 -1
  48. package/lib/garbageCollection.js +95 -68
  49. package/lib/garbageCollection.js.map +1 -1
  50. package/lib/packageVersion.d.ts +1 -1
  51. package/lib/packageVersion.d.ts.map +1 -1
  52. package/lib/packageVersion.js +1 -1
  53. package/lib/packageVersion.js.map +1 -1
  54. package/lib/summarizerTypes.d.ts +5 -2
  55. package/lib/summarizerTypes.d.ts.map +1 -1
  56. package/lib/summarizerTypes.js.map +1 -1
  57. package/lib/summaryGenerator.d.ts.map +1 -1
  58. package/lib/summaryGenerator.js +0 -1
  59. package/lib/summaryGenerator.js.map +1 -1
  60. package/package.json +16 -16
  61. package/src/containerRuntime.ts +60 -58
  62. package/src/dataStore.ts +4 -4
  63. package/src/dataStoreContext.ts +4 -4
  64. package/src/dataStores.ts +5 -5
  65. package/src/garbageCollection.ts +128 -95
  66. package/src/packageVersion.ts +1 -1
  67. package/src/summarizerTypes.ts +6 -3
  68. package/src/summaryGenerator.ts +0 -2
@@ -704,7 +704,7 @@ export abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidData
704
704
 
705
705
  public abstract generateAttachMessage(): IAttachMessage;
706
706
 
707
- protected abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
707
+ public abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
708
708
 
709
709
  /**
710
710
  * @deprecated - Sets the datastore as root, for aliasing purposes: #7948
@@ -858,7 +858,7 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
858
858
  };
859
859
  });
860
860
 
861
- protected async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {
861
+ public async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {
862
862
  return this.initialSnapshotDetailsP;
863
863
  }
864
864
 
@@ -947,7 +947,7 @@ export class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
947
947
  return message;
948
948
  }
949
949
 
950
- protected async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {
950
+ public async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {
951
951
  let snapshot = this.snapshotTree;
952
952
  let attributes: ReadFluidDataStoreAttributes;
953
953
  let isRootDataStore = false;
@@ -1050,7 +1050,7 @@ export class LocalDetachedFluidDataStoreContext
1050
1050
  }
1051
1051
  }
1052
1052
 
1053
- protected async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {
1053
+ public async getInitialSnapshotDetails(): Promise<ISnapshotDetails> {
1054
1054
  if (this.detachedRuntimeCreation) {
1055
1055
  throw new Error("Detached Fluid Data Store context can't be realized! Please attach runtime first!");
1056
1056
  }
package/src/dataStores.ts CHANGED
@@ -647,13 +647,13 @@ export class DataStores implements IDisposable {
647
647
  }
648
648
 
649
649
  /**
650
- * Called during GC to retrieve the package path of a data store node with the given path.
650
+ * Called by GC to retrieve the package path of a data store node with the given path.
651
651
  */
652
- public getDataStorePackagePath(nodePath: string): readonly string[] | undefined {
653
- // If the node belongs to a data store, return its package path if the data store is loaded. For DDSs, we return
654
- // the package path of the data store that contains it.
652
+ public async getDataStorePackagePath(nodePath: string): Promise<readonly string[] | undefined> {
653
+ // If the node belongs to a data store, return its package path. For DDSes, we return the package path of the
654
+ // data store that contains it.
655
655
  const context = this.contexts.get(nodePath.split("/")[1]);
656
- return context?.isLoaded ? context.packagePath : undefined;
656
+ return (await context?.getInitialSnapshotDetails())?.pkg;
657
657
  }
658
658
 
659
659
  /**
@@ -115,12 +115,13 @@ export type GCNodeType = typeof GCNodeType[keyof typeof GCNodeType];
115
115
 
116
116
  /** The event that is logged when unreferenced node is used after a certain time. */
117
117
  interface IUnreferencedEvent {
118
- eventName: string;
118
+ usageType: "Changed" | "Loaded" | "Revived";
119
119
  id: string;
120
120
  type: GCNodeType;
121
121
  age: number;
122
122
  timeout: number;
123
123
  completedGCRuns: number;
124
+ fromId?: string;
124
125
  lastSummaryTime?: number;
125
126
  externalRequest?: boolean;
126
127
  viaHandle?: boolean;
@@ -191,7 +192,7 @@ export interface IGarbageCollectorCreateParams {
191
192
  readonly metadata: IContainerRuntimeMetadata | undefined;
192
193
  readonly baseSnapshot: ISnapshotTree | undefined;
193
194
  readonly isSummarizerClient: boolean;
194
- readonly getNodePackagePath: (nodePath: string) => readonly string[] | undefined;
195
+ readonly getNodePackagePath: (nodePath: string) => Promise<readonly string[] | undefined>;
195
196
  readonly getLastSummaryTimestampMs: () => number | undefined;
196
197
  readonly readAndParseBlob: ReadAndParseBlob;
197
198
  }
@@ -370,7 +371,7 @@ export class GarbageCollector implements IGarbageCollector {
370
371
  // per event per node.
371
372
  private readonly loggedUnreferencedEvents: Set<string> = new Set();
372
373
  // Queue for unreferenced events that should be logged the next time GC runs.
373
- private readonly pendingEventsQueue: IUnreferencedEvent[] = [];
374
+ private pendingEventsQueue: IUnreferencedEvent[] = [];
374
375
 
375
376
  // The number of times GC has successfully completed on this instance of GarbageCollector.
376
377
  private completedRuns = 0;
@@ -380,7 +381,7 @@ export class GarbageCollector implements IGarbageCollector {
380
381
  private readonly isSummarizerClient: boolean;
381
382
 
382
383
  /** For a given node path, returns the node's package path. */
383
- private readonly getNodePackagePath: (nodePath: string) => readonly string[] | undefined;
384
+ private readonly getNodePackagePath: (nodePath: string) => Promise<readonly string[] | undefined>;
384
385
  /** Returns the timestamp of the last summary generated for this container. */
385
386
  private readonly getLastSummaryTimestampMs: () => number | undefined;
386
387
 
@@ -678,7 +679,6 @@ export class GarbageCollector implements IGarbageCollector {
678
679
  },
679
680
  ): Promise<IGCStats> {
680
681
  const {
681
- runSweep = this.shouldRunSweep,
682
682
  fullGC = this.gcOptions.runFullGC === true || this.summaryStateNeedsReset,
683
683
  } = options;
684
684
 
@@ -687,42 +687,52 @@ export class GarbageCollector implements IGarbageCollector {
687
687
  : this.mc.logger;
688
688
 
689
689
  return PerformanceEvent.timedExecAsync(logger, { eventName: "GarbageCollection" }, async (event) => {
690
- await this.initializeBaseStateP;
691
-
692
- // Let the runtime update its pending state before GC runs.
693
- await this.runtime.updateStateBeforeGC();
690
+ await this.runPreGCSteps();
694
691
 
695
692
  // Get the runtime's GC data and run GC on the reference graph in it.
696
693
  const gcData = await this.runtime.getGCData(fullGC);
697
694
  const gcResult = runGarbageCollection(gcData.gcNodes, ["/"]);
698
- const gcStats = this.generateStatsAndLogEvents(gcResult, logger);
699
695
 
700
- // Update the state since the last GC run. There can be nodes that were referenced between the last and
701
- // the current run. We need to identify than and update their unreferenced state if needed.
702
- this.updateStateSinceLastRun(gcData, logger);
696
+ const gcStats = await this.runPostGCSteps(gcData, gcResult, logger);
697
+ event.end({ ...gcStats });
698
+ this.completedRuns++;
699
+ return gcStats;
700
+ }, { end: true, cancel: "error" });
701
+ }
703
702
 
704
- // Update the current state of the system based on the GC run.
705
- const currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();
706
- this.updateCurrentState(gcData, gcResult, currentReferenceTimestampMs);
703
+ private async runPreGCSteps() {
704
+ // Ensure that base state has been initialized.
705
+ await this.initializeBaseStateP;
706
+ // Let the runtime update its pending state before GC runs.
707
+ await this.runtime.updateStateBeforeGC();
708
+ }
707
709
 
708
- this.runtime.updateUsedRoutes(gcResult.referencedNodeIds, currentReferenceTimestampMs);
710
+ private async runPostGCSteps(gcData: IGarbageCollectionData, gcResult: IGCResult, logger: ITelemetryLogger) {
711
+ // Generate statistics from the current run. This is done before updating the current state because it
712
+ // generates some of its data based on previous state of the system.
713
+ const gcStats = this.generateStats(gcResult);
709
714
 
710
- if (runSweep) {
711
- // Placeholder for running sweep logic.
712
- }
715
+ // Update the state since the last GC run. There can be nodes that were referenced between the last and
716
+ // the current run. We need to identify than and update their unreferenced state if needed.
717
+ this.updateStateSinceLastRun(gcData, logger);
713
718
 
714
- // If we are running in GC test mode, delete objects for unused routes. This enables testing scenarios
715
- // involving access to deleted data.
716
- if (this.testMode) {
717
- this.runtime.deleteUnusedRoutes(gcResult.deletedNodeIds);
718
- }
719
+ // Update the current state and update the runtime of all routes or ids that used as per the GC run.
720
+ const currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs();
721
+ this.updateCurrentState(gcData, gcResult, currentReferenceTimestampMs);
722
+ this.runtime.updateUsedRoutes(gcResult.referencedNodeIds, currentReferenceTimestampMs);
719
723
 
720
- event.end({ ...gcStats });
724
+ // If we are running in GC test mode, delete objects for unused routes. This enables testing scenarios
725
+ // involving access to deleted data.
726
+ if (this.testMode) {
727
+ this.runtime.deleteUnusedRoutes(gcResult.deletedNodeIds);
728
+ }
721
729
 
722
- this.completedRuns++;
730
+ // Log pending unreferenced events such as a node being used after inactive. This is done after GC runs and
731
+ // updates its state so that we don't send false positives based on intermediate state. For example, we may get
732
+ // reference to an unreferenced node from another unreferenced node which means the node wasn't revived.
733
+ await this.logPendingEvents(logger);
723
734
 
724
- return gcStats;
725
- }, { end: true, cancel: "error" });
735
+ return gcStats;
726
736
  }
727
737
 
728
738
  /**
@@ -863,13 +873,18 @@ export class GarbageCollector implements IGarbageCollector {
863
873
  return;
864
874
  }
865
875
 
866
- this.logIfInactive(
867
- reason,
868
- nodePath,
869
- timestampMs,
870
- packagePath,
871
- requestHeaders,
872
- );
876
+ const unreferencedState = this.unreferencedNodesState.get(nodePath);
877
+ if (unreferencedState?.inactive) {
878
+ this.inactiveNodeUsed(
879
+ reason,
880
+ nodePath,
881
+ unreferencedState,
882
+ undefined /* fromNodeId */,
883
+ packagePath,
884
+ timestampMs,
885
+ requestHeaders,
886
+ );
887
+ }
873
888
  }
874
889
 
875
890
  /**
@@ -888,11 +903,10 @@ export class GarbageCollector implements IGarbageCollector {
888
903
  outboundRoutes.push(toNodePath);
889
904
  this.newReferencesSinceLastRun.set(fromNodePath, outboundRoutes);
890
905
 
891
- // If the node that got referenced is inactive, log an event as that may indicate use-after-delete.
892
- this.logIfInactive(
893
- "Revived",
894
- toNodePath,
895
- );
906
+ const unreferencedState = this.unreferencedNodesState.get(toNodePath);
907
+ if (unreferencedState?.inactive) {
908
+ this.inactiveNodeUsed("Revived", toNodePath, unreferencedState, fromNodePath);
909
+ }
896
910
  }
897
911
 
898
912
  public dispose(): void {
@@ -1009,10 +1023,10 @@ export class GarbageCollector implements IGarbageCollector {
1009
1023
  * references added new outbound references before getting deleted, we need to detect them.
1010
1024
  * 2. We need new outbound references since last run because some of them may have been deleted later. If those
1011
1025
  * references added new outbound references before getting deleted, we need to detect them.
1012
- * 3. We need data from the current run because currently we may not detect when DDSs are referenced:
1013
- * - We don't require DDSs handles to be stored in a referenced DDS. For this, we need GC at DDS level
1026
+ * 3. We need data from the current run because currently we may not detect when DDSes are referenced:
1027
+ * - We don't require DDSes handles to be stored in a referenced DDS. For this, we need GC at DDS level
1014
1028
  * which is tracked by https://github.com/microsoft/FluidFramework/issues/8470.
1015
- * - A new data store may have "root" DDSs already created and we don't detect them today.
1029
+ * - A new data store may have "root" DDSes already created and we don't detect them today.
1016
1030
  */
1017
1031
  const gcDataSuperSet = concatGarbageCollectionData(this.previousGCDataFromLastRun, currentGCData);
1018
1032
  this.newReferencesSinceLastRun.forEach((outboundRoutes: string[], sourceNodeId: string) => {
@@ -1093,25 +1107,11 @@ export class GarbageCollector implements IGarbageCollector {
1093
1107
  }
1094
1108
 
1095
1109
  /**
1096
- * Generates the stats of a garbage collection run from the given results of the run. Also, logs any pending events
1097
- * in the pendingEventsQueue. This should be called before updating the current state because it generates stats
1098
- * based on previous state of the system.
1110
+ * Generates the stats of a garbage collection run from the given results of the run.
1099
1111
  * @param gcResult - The result of a GC run.
1100
1112
  * @returns the GC stats of the GC run.
1101
1113
  */
1102
- private generateStatsAndLogEvents(gcResult: IGCResult, logger: ITelemetryLogger): IGCStats {
1103
- // Log pending events for unreferenced nodes after GC has run. We should have the package data available for
1104
- // them now since the GC run should have loaded these nodes.
1105
- let event = this.pendingEventsQueue.shift();
1106
- while (event !== undefined) {
1107
- const pkg = this.getNodePackagePath(event.id);
1108
- logger.sendErrorEvent({
1109
- ...event,
1110
- pkg: pkg ? { value: `/${pkg.join("/")}`, tag: TelemetryDataTag.PackageData } : undefined,
1111
- });
1112
- event = this.pendingEventsQueue.shift();
1113
- }
1114
-
1114
+ private generateStats(gcResult: IGCResult): IGCStats {
1115
1115
  const gcStats: IGCStats = {
1116
1116
  nodeCount: 0,
1117
1117
  dataStoreCount: 0,
@@ -1169,13 +1169,15 @@ export class GarbageCollector implements IGarbageCollector {
1169
1169
  }
1170
1170
 
1171
1171
  /**
1172
- * Logs an event if a node is inactive and is used.
1172
+ * Called when a node is used. If the node is inactive, queue up an event that will be logged next time GC runs.
1173
1173
  */
1174
- private logIfInactive(
1175
- eventType: "Changed" | "Loaded" | "Revived",
1174
+ private inactiveNodeUsed(
1175
+ usageType: "Changed" | "Loaded" | "Revived",
1176
1176
  nodeId: string,
1177
- currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs(),
1177
+ unreferencedState: UnreferencedStateTracker,
1178
+ fromNodeId?: string,
1178
1179
  packagePath?: readonly string[],
1180
+ currentReferenceTimestampMs = this.runtime.getCurrentReferenceTimestampMs(),
1179
1181
  requestHeaders?: IRequestHeader,
1180
1182
  ) {
1181
1183
  // If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
@@ -1184,6 +1186,12 @@ export class GarbageCollector implements IGarbageCollector {
1184
1186
  return;
1185
1187
  }
1186
1188
 
1189
+ // For non-summarizer clients, only log "Loaded" type events since these objects may not be loaded in the
1190
+ // summarizer clients if they are based off of user actions (such as scrolling to content for these objects).
1191
+ if (!this.isSummarizerClient && usageType !== "Loaded") {
1192
+ return;
1193
+ }
1194
+
1187
1195
  // We only care about data stores and attachment blobs for this telemetry since GC only marks these objects
1188
1196
  // as unreferenced. Also, if an inactive DDS is used, the corresponding data store store will also be used.
1189
1197
  const nodeType = this.runtime.getNodeType(nodeId);
@@ -1191,43 +1199,68 @@ export class GarbageCollector implements IGarbageCollector {
1191
1199
  return;
1192
1200
  }
1193
1201
 
1194
- // For non-summarizer clients, only log "Loaded" type events since these objects may not be loaded in the
1195
- // summarizer clients if they are based off of user actions (such as scrolling to content for these objects).
1196
- if (!this.isSummarizerClient && eventType !== "Loaded") {
1202
+ // A particular event is logged for a given node only once so that it is not too noisy.
1203
+ const uniqueEventId = `${nodeId}-${usageType}`;
1204
+ if (this.loggedUnreferencedEvents.has(uniqueEventId)) {
1197
1205
  return;
1198
1206
  }
1207
+ this.loggedUnreferencedEvents.add(uniqueEventId);
1208
+
1209
+ const event: IUnreferencedEvent = {
1210
+ usageType,
1211
+ id: nodeId,
1212
+ type: nodeType,
1213
+ age: currentReferenceTimestampMs - unreferencedState.unreferencedTimestampMs,
1214
+ timeout: this.inactiveTimeoutMs,
1215
+ completedGCRuns: this.completedRuns,
1216
+ lastSummaryTime: this.getLastSummaryTimestampMs(),
1217
+ externalRequest: requestHeaders?.[RuntimeHeaders.externalRequest],
1218
+ viaHandle: requestHeaders?.[RuntimeHeaders.viaHandle],
1219
+ fromId: fromNodeId,
1220
+ };
1199
1221
 
1200
- const eventName = `inactiveObject_${eventType}`;
1201
- // We log a particular event for a given node only once so that it is not too noisy.
1202
- const uniqueEventId = `${nodeId}-${eventName}`;
1203
- const nodeState = this.unreferencedNodesState.get(nodeId);
1204
- if (nodeState?.inactive && !this.loggedUnreferencedEvents.has(uniqueEventId)) {
1205
- this.loggedUnreferencedEvents.add(uniqueEventId);
1206
- // Save all the properties at this point in time so that if we log this later, these values are preserved.
1207
- const event: IUnreferencedEvent = {
1208
- eventName,
1209
- id: nodeId,
1210
- type: nodeType,
1211
- age: currentReferenceTimestampMs - nodeState.unreferencedTimestampMs,
1212
- timeout: this.inactiveTimeoutMs,
1213
- completedGCRuns: this.completedRuns,
1214
- lastSummaryTime: this.getLastSummaryTimestampMs(),
1215
- externalRequest: requestHeaders?.[RuntimeHeaders.externalRequest],
1216
- viaHandle: requestHeaders?.[RuntimeHeaders.viaHandle],
1217
- };
1222
+ // For summarizer client, queue the event so it is logged the next time GC runs if the event is still valid.
1223
+ // For non-summarizer client, log the event now since GC won't run on it. This may result in false positives
1224
+ // but it's a good signal nonetheless and we can consume it with a grain of salt.
1225
+ if (this.isSummarizerClient) {
1226
+ this.pendingEventsQueue.push(event);
1227
+ } else {
1228
+ this.mc.logger.sendErrorEvent({
1229
+ ...event,
1230
+ eventName: `inactiveObject-${usageType}`,
1231
+ pkg: packagePath ? { value: packagePath.join("/"), tag: TelemetryDataTag.PackageData } : undefined,
1232
+ });
1233
+ }
1234
+ }
1218
1235
 
1219
- // If the package data for the node exists, log immediately. Otherwise, queue it and it will be logged the
1220
- // next time GC runs as the package data should be available then.
1221
- const pkg = packagePath ?? this.getNodePackagePath(nodeId);
1222
- if (pkg !== undefined) {
1223
- this.mc.logger.sendErrorEvent({
1224
- ...event,
1225
- pkg: { value: pkg.join("/"), tag: TelemetryDataTag.PackageData },
1226
- });
1227
- } else {
1228
- this.pendingEventsQueue.push(event);
1236
+ /**
1237
+ * Logs pending unreferenced events if they are still valid.
1238
+ */
1239
+ private async logPendingEvents(logger: ITelemetryLogger) {
1240
+ for (const event of this.pendingEventsQueue) {
1241
+ const unreferencedState = this.unreferencedNodesState.get(event.id);
1242
+ // Only log revived event if the node is not inactive anymore. If the node is still inactive, the
1243
+ // reference was from another unreferenced node and we don't care about logging this scenario.
1244
+ if (event.usageType === "Revived" && unreferencedState?.inactive) {
1245
+ continue;
1229
1246
  }
1247
+
1248
+ // Only log loaded and changed event if the node is still inactive. If the node is not inactive, it was
1249
+ // revived and a revived event will be logged for it.
1250
+ if (event.usageType !== "Revived" && !unreferencedState?.inactive) {
1251
+ continue;
1252
+ }
1253
+
1254
+ const pkg = await this.getNodePackagePath(event.id);
1255
+ const fromPkg = event.fromId ? await this.getNodePackagePath(event.fromId) : undefined;
1256
+ logger.sendErrorEvent({
1257
+ ...event,
1258
+ eventName: `inactiveObject_${event.usageType}`,
1259
+ pkg: pkg ? { value: pkg.join("/"), tag: TelemetryDataTag.PackageData } : undefined,
1260
+ fromPkg: fromPkg ? { value: fromPkg.join("/"), tag: TelemetryDataTag.PackageData } : undefined,
1261
+ });
1230
1262
  }
1263
+ this.pendingEventsQueue = [];
1231
1264
  }
1232
1265
  }
1233
1266
 
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "1.1.0";
9
+ export const pkgVersion = "1.2.0-77818";
@@ -152,7 +152,7 @@ export interface IGeneratedSummaryStats extends ISummaryStats {
152
152
  readonly gcBlobNodeCount?: number;
153
153
  /** Sum of the sizes of all op contents since the last summary */
154
154
  readonly opsSizesSinceLastSummary: number;
155
- /** Number of non-system ops since the last summary @see isSystemMessage */
155
+ /** Number of non-system ops since the last summary. See {@link @fluidframework/protocol-base#isSystemMessage} */
156
156
  readonly nonSystemOpsSinceLastSummary: number;
157
157
  /** The summary number for a container's summary. Incremented on summaries throughout its lifetime. */
158
158
  readonly summaryNumber: number;
@@ -300,7 +300,7 @@ export interface ISummarizerEvents extends IEvent {
300
300
  }
301
301
 
302
302
  export interface ISummarizer extends
303
- IEventProvider<ISummarizerEvents>, IFluidLoadable, Partial<IProvideSummarizer>{
303
+ IEventProvider<ISummarizerEvents>, IFluidLoadable, Partial<IProvideSummarizer> {
304
304
  /*
305
305
  * Asks summarizer to move to exit.
306
306
  * Summarizer will finish current processes, which may take a while.
@@ -428,7 +428,10 @@ type SummaryGeneratorOptionalTelemetryProperties =
428
428
  /** Delta in sum of op sizes between the current reference sequence number and the reference
429
429
  * sequence number of the last summary */
430
430
  "opsSizesSinceLastSummary" |
431
- /** Delta between the number of non-system ops since the last summary @see isSystemMessage */
431
+ /**
432
+ * Delta between the number of non-system ops since the last summary.
433
+ * See {@link @fluidframework/protocol-base#isSystemMessage}
434
+ */
432
435
  "nonSystemOpsSinceLastSummary" |
433
436
  /** Time it took to generate the summary tree and stats. */
434
437
  "generateDuration" |
@@ -393,8 +393,6 @@ export class SummaryGenerator {
393
393
 
394
394
  // pre-0.58 error message prefix: summaryNack
395
395
  const error = new LoggingError(`Received summaryNack: ${message}`, { retryAfterSeconds });
396
- logger.sendErrorEvent(
397
- { eventName: "SummaryNack", ...summarizeTelemetryProps, retryAfterSeconds }, error);
398
396
 
399
397
  assert(getRetryDelaySecondsFromError(error) === retryAfterSeconds, 0x25f /* "retryAfterSeconds" */);
400
398
  // This will only set resultsBuilder.receivedSummaryAckOrNack, as other promises are already set.