diff --git a/.env.example b/.env.example index 31f1caf..e6ffdd6 100644 --- a/.env.example +++ b/.env.example @@ -21,3 +21,16 @@ INFLUXDB_TOKEN=mytoken123456789 INFLUXDB_ORG=mikrotik-manager INFLUXDB_BUCKET=metrics INFLUXDB_ADMIN_PASSWORD=admin_password_123 + +# ─── Poller tuning (see GET /api/system/poller) ────────────────────────────── +# Raise concurrency if `headroom` in the poller health endpoint drops near 1.0 — +# below that the queue grows every cycle and devices go stale. +# POLLER_CONCURRENCY=12 +# POLLER_JOB_TIMEOUT_MS=45000 +# POLLER_INTERVAL_MS=30000 +# POLLER_JOB_RETENTION_SEC=3600 +# POLLER_JOB_RETENTION_COUNT=5000 + +# Redis memory ceiling. Only TTL-bearing keys are evicted (volatile-lru), so +# queued jobs are never discarded; the cap exists to protect the host. +# REDIS_MAXMEMORY=512mb diff --git a/README.md b/README.md index f131f26..3da4552 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@
-
+
diff --git a/backend/package.json b/backend/package.json
index fcb9841..d2636fa 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -1,6 +1,6 @@
{
"name": "mikrotik-manager-backend",
- "version": "0.23.17-beta",
+ "version": "0.23.18-beta",
"description": "Mikrotik Network Management Platform - Backend API",
"main": "dist/index.js",
"scripts": {
diff --git a/backend/src/services/PollerService.ts b/backend/src/services/PollerService.ts
index e36f86f..76ac9ba 100644
--- a/backend/src/services/PollerService.ts
+++ b/backend/src/services/PollerService.ts
@@ -159,12 +159,19 @@ export class PollerService {
attempts: 3,
backoff: { type: 'exponential', delay: 5000 },
});
+ // Periodic polls are not retried in-job: the schedule is the retry. A device
+ // that just failed to answer is unlikely to answer a second later, and each
+ // extra attempt occupies a worker for up to the job timeout. On a fleet with
+ // several devices down that doubles the capacity they waste, which is exactly
+ // the capacity the rest of the fleet is short of (#114). Historically this
+ // also doubled the recorded failure count: 231k failed jobs on a four-device
+ // fleet turned out to be ~1,000 hours of genuine downtime, counted twice.
} else if (type === 'fast') {
- await this.fastQueue.add('device-fast-poll', jobData, { attempts: 2 });
+ await this.fastQueue.add('device-fast-poll', jobData, { attempts: 1 });
} else if (type === 'slow') {
- await this.slowQueue.add('device-slow-poll', jobData, { attempts: 2 });
+ await this.slowQueue.add('device-slow-poll', jobData, { attempts: 1 });
} else if (type === 'logs') {
- await this.logsQueue.add('device-logs-poll', jobData, { attempts: 2 });
+ await this.logsQueue.add('device-logs-poll', jobData, { attempts: 1 });
} else if (type === 'macscan') {
await this.fastQueue.add('device-macscan', jobData, { attempts: 1 });
} else if (type === 'spectral') {
diff --git a/docker-compose.yml b/docker-compose.yml
index 6fe9683..c48f867 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -85,7 +85,16 @@ services:
redis:
image: redis:7-alpine
- command: redis-server --appendonly yes
+ # A memory ceiling so a runaway producer can never take the host down. The
+ # eviction policy is deliberately volatile-lru rather than allkeys-*: BullMQ
+ # job data carries no TTL and must never be evicted (that would silently
+ # destroy queued work), while the poller's caches and in-flight claims all
+ # set one and are safe to drop. If pressure ever exhausts the volatile keys
+ # Redis refuses writes instead of evicting queue state — loud, and survivable.
+ command: >
+ redis-server --appendonly yes
+ --maxmemory ${REDIS_MAXMEMORY:-512mb}
+ --maxmemory-policy volatile-lru
volumes:
- redis_data:/data
restart: unless-stopped
diff --git a/frontend/package.json b/frontend/package.json
index 2d064da..822ff00 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "mikrotik-manager-frontend",
- "version": "0.23.17-beta",
+ "version": "0.23.18-beta",
"private": true,
"type": "module",
"scripts": {
diff --git a/frontend/src/version.ts b/frontend/src/version.ts
index 2252b75..a457959 100644
--- a/frontend/src/version.ts
+++ b/frontend/src/version.ts
@@ -1 +1 @@
-export const APP_VERSION = 'v0.23.17 Beta';
+export const APP_VERSION = 'v0.23.18 Beta';