muaddib-scanner 2.10.79 → 2.10.80
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.
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Adjusts target concurrency every ADJUST_INTERVAL_MS based on three signals:
|
|
7
7
|
* 1. Queue depth — scale up when backlog grows, down when idle
|
|
8
|
-
* 2. Memory pressure — always reduce under
|
|
8
|
+
* 2. Memory pressure — always reduce under system RAM pressure
|
|
9
9
|
* 3. Timeout rate — reduce when system is saturated (I/O contention)
|
|
10
10
|
*
|
|
11
11
|
* Scale-up is aggressive (+4) because backlog = lost coverage.
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* Memory pressure overrides everything (OOM kills lose the in-memory queue).
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
const os = require('os');
|
|
17
|
+
|
|
16
18
|
const MIN_CONCURRENCY = 4;
|
|
17
19
|
const BASE_CONCURRENCY = Math.max(MIN_CONCURRENCY, parseInt(process.env.MUADDIB_SCAN_CONCURRENCY, 10) || 8);
|
|
18
20
|
const MAX_CONCURRENCY = Math.max(BASE_CONCURRENCY, parseInt(process.env.MUADDIB_MAX_CONCURRENCY, 10) || 32);
|
|
@@ -23,7 +25,11 @@ const QUEUE_BACKLOG_THRESHOLD = 1000;
|
|
|
23
25
|
const QUEUE_IDLE_THRESHOLD = 100;
|
|
24
26
|
|
|
25
27
|
// System pressure thresholds
|
|
26
|
-
|
|
28
|
+
// Uses os.freemem()/os.totalmem() (real system RAM), NOT process.memoryUsage()
|
|
29
|
+
// heapUsed/heapTotal. V8 adjusts heapTotal dynamically — the ratio is structurally
|
|
30
|
+
// 75-85% even when the OS has 8+ GB free. On a 12GB VPS with 3MB heap,
|
|
31
|
+
// heapUsed/heapTotal = 76% but freemem/totalmem = 75% (8.3GB available).
|
|
32
|
+
const MEMORY_FREE_THRESHOLD = 0.15; // < 15% system RAM free = pressure
|
|
27
33
|
const TIMEOUT_RATE_THRESHOLD = 0.15;
|
|
28
34
|
const TIMEOUT_RATE_MIN_SAMPLES = 20;
|
|
29
35
|
|
|
@@ -41,15 +47,18 @@ let _prevTimeouts = 0;
|
|
|
41
47
|
* @returns {{ target: number, reason: string }}
|
|
42
48
|
*/
|
|
43
49
|
function computeTarget(current, queueDepth, stats) {
|
|
44
|
-
|
|
45
|
-
const
|
|
50
|
+
// Use system RAM, not V8 heap ratio (see MEMORY_FREE_THRESHOLD comment above)
|
|
51
|
+
const freeMem = os.freemem();
|
|
52
|
+
const totalMem = os.totalmem();
|
|
53
|
+
const freeRatio = totalMem > 0 ? freeMem / totalMem : 1;
|
|
46
54
|
|
|
47
|
-
// Priority 1:
|
|
48
|
-
if (
|
|
55
|
+
// Priority 1: System memory pressure — always reduce, overrides everything
|
|
56
|
+
if (freeRatio < MEMORY_FREE_THRESHOLD) {
|
|
49
57
|
const target = clamp(current - 4);
|
|
50
58
|
_prevScanned = stats.scanned || 0;
|
|
51
59
|
_prevTimeouts = (stats.errorsByType && stats.errorsByType.static_timeout) || 0;
|
|
52
|
-
|
|
60
|
+
const freeMB = Math.round(freeMem / 1024 / 1024);
|
|
61
|
+
return { target, reason: `memory_pressure (${freeMB}MB free, ${(freeRatio * 100).toFixed(0)}%)` };
|
|
53
62
|
}
|
|
54
63
|
|
|
55
64
|
// Compute timeout rate from stats deltas (sliding window between adjustments)
|