@naturalcycles/backend-lib 9.85.0 → 9.85.1

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.
@@ -29,6 +29,11 @@ export declare class EventLoopMonitor {
29
29
  private lastElu;
30
30
  private lastReportedAt;
31
31
  private paused;
32
+ /**
33
+ * performance.now() of the last resume() (or construction), to tell gc pauses that overlapped
34
+ * a paused period from those that ran while sampling was active.
35
+ */
36
+ private resumedAt;
32
37
  private readonly watchdogInterval;
33
38
  private watchdog?;
34
39
  /**
@@ -124,11 +129,13 @@ export interface EventLoopStats {
124
129
  */
125
130
  gcCPU: Integer;
126
131
  /**
127
- * Longest single GC pause in the last interval.
132
+ * Longest single GC pause in the last interval, among the pauses that ran while sampling was
133
+ * active (a pause overlapping a paused, CPU-throttled period is stretched by the throttling).
134
+ * `gcCount` and `gcTotalTime` are not gated.
128
135
  */
129
136
  gcMaxTime: NumberOfMilliseconds;
130
137
  /**
131
- * Kind of the longest GC pause. Undefined when no GC ran in the interval.
138
+ * Kind of the longest GC pause. Undefined when no such GC pause ran in the interval.
132
139
  */
133
140
  gcMaxKind: GcKind | undefined;
134
141
  /**
@@ -53,10 +53,15 @@ export class EventLoopMonitor {
53
53
  this.eld.enable();
54
54
  this.lastElu = performance.eventLoopUtilization();
55
55
  this.lastReportedAt = performance.now();
56
+ this.resumedAt = this.lastReportedAt;
56
57
  this.po = new PerformanceObserver(list => {
57
58
  for (const entry of list.getEntries()) {
58
59
  this.gcCount++;
59
60
  this.gcTotalTime += entry.duration;
61
+ // A pause overlapping a paused (CPU-throttled) period is stretched by the throttling and
62
+ // says nothing about GC: only pauses that ran while sampling was active compete for the max
63
+ if (this.paused || entry.startTime < this.resumedAt)
64
+ continue;
60
65
  if (entry.duration > this.gcMaxTime) {
61
66
  this.gcMaxTime = entry.duration;
62
67
  this.gcMaxKind = getGcKind(entry);
@@ -118,6 +123,11 @@ export class EventLoopMonitor {
118
123
  lastElu;
119
124
  lastReportedAt;
120
125
  paused = false;
126
+ /**
127
+ * performance.now() of the last resume() (or construction), to tell gc pauses that overlapped
128
+ * a paused period from those that ran while sampling was active.
129
+ */
130
+ resumedAt;
121
131
  watchdogInterval;
122
132
  watchdog;
123
133
  /**
@@ -165,6 +175,7 @@ export class EventLoopMonitor {
165
175
  if (!this.paused)
166
176
  return;
167
177
  this.paused = false;
178
+ this.resumedAt = performance.now();
168
179
  this.eld.enable();
169
180
  this.startWatchdog();
170
181
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/backend-lib",
3
3
  "type": "module",
4
- "version": "9.85.0",
4
+ "version": "9.85.1",
5
5
  "dependencies": {
6
6
  "@naturalcycles/db-lib": "^10",
7
7
  "@naturalcycles/js-lib": "^15",
@@ -69,11 +69,15 @@ export class EventLoopMonitor {
69
69
 
70
70
  this.lastElu = performance.eventLoopUtilization()
71
71
  this.lastReportedAt = performance.now()
72
+ this.resumedAt = this.lastReportedAt
72
73
 
73
74
  this.po = new PerformanceObserver(list => {
74
75
  for (const entry of list.getEntries()) {
75
76
  this.gcCount++
76
77
  this.gcTotalTime += entry.duration
78
+ // A pause overlapping a paused (CPU-throttled) period is stretched by the throttling and
79
+ // says nothing about GC: only pauses that ran while sampling was active compete for the max
80
+ if (this.paused || entry.startTime < this.resumedAt) continue
77
81
  if (entry.duration > this.gcMaxTime) {
78
82
  this.gcMaxTime = entry.duration
79
83
  this.gcMaxKind = getGcKind(entry)
@@ -145,6 +149,11 @@ export class EventLoopMonitor {
145
149
  private lastElu: EventLoopUtilization
146
150
  private lastReportedAt: NumberOfMilliseconds
147
151
  private paused = false
152
+ /**
153
+ * performance.now() of the last resume() (or construction), to tell gc pauses that overlapped
154
+ * a paused period from those that ran while sampling was active.
155
+ */
156
+ private resumedAt: NumberOfMilliseconds
148
157
  private readonly watchdogInterval: NumberOfMilliseconds
149
158
  private watchdog?: NodeJS.Timeout
150
159
  /**
@@ -194,6 +203,7 @@ export class EventLoopMonitor {
194
203
  resume(): void {
195
204
  if (!this.paused) return
196
205
  this.paused = false
206
+ this.resumedAt = performance.now()
197
207
  this.eld.enable()
198
208
  this.startWatchdog()
199
209
  }
@@ -303,11 +313,13 @@ export interface EventLoopStats {
303
313
  */
304
314
  gcCPU: Integer
305
315
  /**
306
- * Longest single GC pause in the last interval.
316
+ * Longest single GC pause in the last interval, among the pauses that ran while sampling was
317
+ * active (a pause overlapping a paused, CPU-throttled period is stretched by the throttling).
318
+ * `gcCount` and `gcTotalTime` are not gated.
307
319
  */
308
320
  gcMaxTime: NumberOfMilliseconds
309
321
  /**
310
- * Kind of the longest GC pause. Undefined when no GC ran in the interval.
322
+ * Kind of the longest GC pause. Undefined when no such GC pause ran in the interval.
311
323
  */
312
324
  gcMaxKind: GcKind | undefined
313
325
  /**