muaddib-scanner 2.10.80 → 2.10.81

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muaddib-scanner",
3
- "version": "2.10.80",
3
+ "version": "2.10.81",
4
4
  "description": "Supply-chain threat detection & response for npm & PyPI/Python",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -480,15 +480,37 @@ async function startMonitor(options, stats, dailyAlerts, recentlyScanned, downlo
480
480
  console.log('[MONITOR] Deferred sandbox worker started (30s interval, dedicated slot)');
481
481
  }
482
482
 
483
- // Initial poll + scan (sequential for first run)
483
+ // ─── Initial poll ───
484
+ // Fills the queue with pending packages. Processing starts in the main loop
485
+ // via ensureWorkers (non-blocking) — NOT await processQueue (blocking).
486
+ // A blocking processQueue here would prevent adaptive concurrency from
487
+ // firing until the entire initial batch is drained at BASE_CONCURRENCY.
484
488
  await poll(state, scanQueue, stats);
485
489
  // Atomicity fix: persist queue AND seq together after each poll.
486
490
  // Previously, seq was saved inside pollNpmChanges() but queue persisted
487
- // every 60s ��� crash between the two lost queued items permanently.
491
+ // every 60s crash between the two lost queued items permanently.
488
492
  persistQueue(scanQueue, state);
489
493
  saveNpmSeq(state.npmLastSeq);
490
494
  saveState(state, stats);
491
- await processQueue(scanQueue, stats, dailyAlerts, recentlyScanned, downloadsCache, sandboxAvailableRef.value);
495
+ console.log(`[MONITOR] Initial poll complete ${scanQueue.length} packages queued for processing`);
496
+
497
+ // ─── Adaptive concurrency ───
498
+ // Set up BEFORE the main loop so it fires during the initial batch.
499
+ // Adjusts scan worker count every 30s based on queue depth, memory, timeout rate.
500
+ // Scale-up is aggressive (+4) during backlog, scale-down is gradual (-2) when idle.
501
+ concurrencyAdjustHandle = setInterval(() => {
502
+ if (!running) return;
503
+ const current = getTargetConcurrency();
504
+ const { target, reason } = computeTarget(current, scanQueue.length, stats);
505
+ if (target !== current) {
506
+ console.log(`[MONITOR] ADAPTIVE: concurrency ${current} → ${target} (${reason}, active=${getActiveWorkers()})`);
507
+ setTargetConcurrency(target);
508
+ // Immediately spawn new workers if scaling up (don't wait for next loop tick)
509
+ if (target > current) {
510
+ ensureWorkers(scanQueue, stats, dailyAlerts, recentlyScanned, downloadsCache, sandboxAvailableRef.value);
511
+ }
512
+ }
513
+ }, ADJUST_INTERVAL_MS);
492
514
 
493
515
  // ─── Decoupled polling ───
494
516
  // Poll runs on its own interval, independent of processing.
@@ -523,23 +545,6 @@ async function startMonitor(options, stats, dailyAlerts, recentlyScanned, downlo
523
545
  persistDeferredQueue(); // Piggyback: persist deferred sandbox queue on same interval
524
546
  }, QUEUE_PERSIST_INTERVAL);
525
547
 
526
- // ─── Adaptive concurrency ───
527
- // Adjusts scan worker count every 30s based on queue depth, memory, timeout rate.
528
- // Scale-up is aggressive (+4) during backlog, scale-down is gradual (-2) when idle.
529
- concurrencyAdjustHandle = setInterval(() => {
530
- if (!running) return;
531
- const current = getTargetConcurrency();
532
- const { target, reason } = computeTarget(current, scanQueue.length, stats);
533
- if (target !== current) {
534
- console.log(`[MONITOR] ADAPTIVE: concurrency ${current} → ${target} (${reason}, active=${getActiveWorkers()})`);
535
- setTargetConcurrency(target);
536
- // Immediately spawn new workers if scaling up (don't wait for next loop tick)
537
- if (target > current) {
538
- ensureWorkers(scanQueue, stats, dailyAlerts, recentlyScanned, downloadsCache, sandboxAvailableRef.value);
539
- }
540
- }
541
- }, ADJUST_INTERVAL_MS);
542
-
543
548
  // ─── Continuous processing loop ───
544
549
  // Non-blocking: ensureWorkers spawns fire-and-forget background workers.
545
550
  // This loop tops up workers every 2s AND runs housekeeping (memory, daily report)