@naturalcycles/backend-lib 9.84.1 → 9.84.2
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.
|
@@ -11,8 +11,10 @@ import type { Integer, NonNegativeInteger, NumberOfMilliseconds, NumberOfPercent
|
|
|
11
11
|
* reported by older interval-based sampling.
|
|
12
12
|
*
|
|
13
13
|
* Beware of CPU-throttled processes (e.g. idle CloudRun instances with request-based billing):
|
|
14
|
-
* the
|
|
15
|
-
*
|
|
14
|
+
* the time the process spent runnable-but-unscheduled is recorded as event loop delay,
|
|
15
|
+
* and the interval timer fires late (see `intervalMs`).
|
|
16
|
+
* Use `pause()` / `resume()` to keep such periods out of the delay samples,
|
|
17
|
+
* e.g. pause when the last in-flight request finishes and resume when the next one arrives.
|
|
16
18
|
*/
|
|
17
19
|
export declare class EventLoopMonitor {
|
|
18
20
|
constructor(cfg?: EventLoopMonitorCfg);
|
|
@@ -20,6 +22,7 @@ export declare class EventLoopMonitor {
|
|
|
20
22
|
private eld;
|
|
21
23
|
private lastElu;
|
|
22
24
|
private lastReportedAt;
|
|
25
|
+
private paused;
|
|
23
26
|
/**
|
|
24
27
|
* Undefined until the first interval has completed.
|
|
25
28
|
*/
|
|
@@ -28,6 +31,22 @@ export declare class EventLoopMonitor {
|
|
|
28
31
|
gcCount: number;
|
|
29
32
|
gcTotalTime: number;
|
|
30
33
|
stop(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Stops sampling event loop delay until `resume()` is called.
|
|
36
|
+
* GC and ELU keep being tracked, and the samples recorded so far are kept.
|
|
37
|
+
*
|
|
38
|
+
* Meant for periods when the process is known to be CPU-throttled, e.g. a CloudRun instance
|
|
39
|
+
* (request-based billing) with no request in flight: a delay recorded there measures
|
|
40
|
+
* the throttling, not the application.
|
|
41
|
+
*/
|
|
42
|
+
pause(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Resumes sampling event loop delay after `pause()`.
|
|
45
|
+
* Safe to call from within the event that ended the throttled period (e.g. the middleware of
|
|
46
|
+
* the request that woke the instance): the histogram restarts its clock from this moment,
|
|
47
|
+
* so the stall that preceded it in the same loop iteration is not sampled.
|
|
48
|
+
*/
|
|
49
|
+
resume(): void;
|
|
31
50
|
}
|
|
32
51
|
export interface EventLoopMonitorCfg {
|
|
33
52
|
/**
|
|
@@ -27,8 +27,10 @@ import { monitorEventLoopDelay, performance, PerformanceObserver } from 'node:pe
|
|
|
27
27
|
* reported by older interval-based sampling.
|
|
28
28
|
*
|
|
29
29
|
* Beware of CPU-throttled processes (e.g. idle CloudRun instances with request-based billing):
|
|
30
|
-
* the
|
|
31
|
-
*
|
|
30
|
+
* the time the process spent runnable-but-unscheduled is recorded as event loop delay,
|
|
31
|
+
* and the interval timer fires late (see `intervalMs`).
|
|
32
|
+
* Use `pause()` / `resume()` to keep such periods out of the delay samples,
|
|
33
|
+
* e.g. pause when the last in-flight request finishes and resume when the next one arrives.
|
|
32
34
|
*/
|
|
33
35
|
export class EventLoopMonitor {
|
|
34
36
|
constructor(cfg = {}) {
|
|
@@ -92,6 +94,7 @@ export class EventLoopMonitor {
|
|
|
92
94
|
eld;
|
|
93
95
|
lastElu;
|
|
94
96
|
lastReportedAt;
|
|
97
|
+
paused = false;
|
|
95
98
|
/**
|
|
96
99
|
* Undefined until the first interval has completed.
|
|
97
100
|
*/
|
|
@@ -104,4 +107,28 @@ export class EventLoopMonitor {
|
|
|
104
107
|
this.eld.disable();
|
|
105
108
|
this.po.disconnect();
|
|
106
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Stops sampling event loop delay until `resume()` is called.
|
|
112
|
+
* GC and ELU keep being tracked, and the samples recorded so far are kept.
|
|
113
|
+
*
|
|
114
|
+
* Meant for periods when the process is known to be CPU-throttled, e.g. a CloudRun instance
|
|
115
|
+
* (request-based billing) with no request in flight: a delay recorded there measures
|
|
116
|
+
* the throttling, not the application.
|
|
117
|
+
*/
|
|
118
|
+
pause() {
|
|
119
|
+
this.paused = true;
|
|
120
|
+
this.eld.disable();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Resumes sampling event loop delay after `pause()`.
|
|
124
|
+
* Safe to call from within the event that ended the throttled period (e.g. the middleware of
|
|
125
|
+
* the request that woke the instance): the histogram restarts its clock from this moment,
|
|
126
|
+
* so the stall that preceded it in the same loop iteration is not sampled.
|
|
127
|
+
*/
|
|
128
|
+
resume() {
|
|
129
|
+
if (!this.paused)
|
|
130
|
+
return;
|
|
131
|
+
this.paused = false;
|
|
132
|
+
this.eld.enable();
|
|
133
|
+
}
|
|
107
134
|
}
|
package/package.json
CHANGED
|
@@ -36,8 +36,10 @@ import type {
|
|
|
36
36
|
* reported by older interval-based sampling.
|
|
37
37
|
*
|
|
38
38
|
* Beware of CPU-throttled processes (e.g. idle CloudRun instances with request-based billing):
|
|
39
|
-
* the
|
|
40
|
-
*
|
|
39
|
+
* the time the process spent runnable-but-unscheduled is recorded as event loop delay,
|
|
40
|
+
* and the interval timer fires late (see `intervalMs`).
|
|
41
|
+
* Use `pause()` / `resume()` to keep such periods out of the delay samples,
|
|
42
|
+
* e.g. pause when the last in-flight request finishes and resume when the next one arrives.
|
|
41
43
|
*/
|
|
42
44
|
export class EventLoopMonitor {
|
|
43
45
|
constructor(cfg: EventLoopMonitorCfg = {}) {
|
|
@@ -113,6 +115,7 @@ export class EventLoopMonitor {
|
|
|
113
115
|
private eld: ELDHistogram
|
|
114
116
|
private lastElu: EventLoopUtilization
|
|
115
117
|
private lastReportedAt: NumberOfMilliseconds
|
|
118
|
+
private paused = false
|
|
116
119
|
/**
|
|
117
120
|
* Undefined until the first interval has completed.
|
|
118
121
|
*/
|
|
@@ -127,6 +130,31 @@ export class EventLoopMonitor {
|
|
|
127
130
|
this.po.disconnect()
|
|
128
131
|
}
|
|
129
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Stops sampling event loop delay until `resume()` is called.
|
|
135
|
+
* GC and ELU keep being tracked, and the samples recorded so far are kept.
|
|
136
|
+
*
|
|
137
|
+
* Meant for periods when the process is known to be CPU-throttled, e.g. a CloudRun instance
|
|
138
|
+
* (request-based billing) with no request in flight: a delay recorded there measures
|
|
139
|
+
* the throttling, not the application.
|
|
140
|
+
*/
|
|
141
|
+
pause(): void {
|
|
142
|
+
this.paused = true
|
|
143
|
+
this.eld.disable()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Resumes sampling event loop delay after `pause()`.
|
|
148
|
+
* Safe to call from within the event that ended the throttled period (e.g. the middleware of
|
|
149
|
+
* the request that woke the instance): the histogram restarts its clock from this moment,
|
|
150
|
+
* so the stall that preceded it in the same loop iteration is not sampled.
|
|
151
|
+
*/
|
|
152
|
+
resume(): void {
|
|
153
|
+
if (!this.paused) return
|
|
154
|
+
this.paused = false
|
|
155
|
+
this.eld.enable()
|
|
156
|
+
}
|
|
157
|
+
|
|
130
158
|
// cfg: Required<EventLoopMonitorCfg>
|
|
131
159
|
}
|
|
132
160
|
|