Work Intent: fix frozen NetIO/BlockIO in dockerContainerStats subscription
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Ferma
- Stack tecnologico
- docker, typescript
Direzione di ricerca
Start with DockerStatsService.startStatsStream() and the existing getDockerClient() helper, then compare dockerode usage in DockerEventService. Review docker-stats.service.spec.ts and run the listed pnpm checks. Done means fresh NetIO and BlockIO values, correct CPU and memory calculations, container event handling, cleanup, and an unchanged GraphQL response shape.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Overview
Fix #2007: the dockerContainerStats GraphQL subscription emits CPU updates correctly but the cumulative NetIO and BlockIO fields stay frozen at the first sample for the lifetime of the subscription. Consumers that derive per-second rates from consecutive emissions always read 0 B/s — verified against a live Unraid 7.3 box with an actively downloading qBittorrent container (docker stats --no-stream returned the same 40.1GB / 220GB across 12 s while /containers/<id>/stats on the Docker socket showed +109 MB rx in 3 s = 36 MB/s).
Root cause: DockerStatsService.startStatsStream() spawns execa('docker', ['stats', '--format', ..., '--no-trunc']) and parses each output line. The docker CLI's "live" mode keeps the cumulative counters from its initial snapshot — they don't refresh across output ticks the way the per-container /stats socket endpoint does.
Technical Approach
Rewrite DockerStatsService to stream from the Docker daemon socket directly using dockerode (already a dependency, used by DockerEventService):
startStatsStream()callsdocker.listContainers()and opens onecontainer.stats({ stream: true })socket per running container. It also subscribes todocker.getEvents({ filters: { type: ['container'] } })so streams are added onstartand torn down ondie/stop/kill/destroy.- Each stats chunk is parsed: CPU% via the standard
((cpu_delta / system_delta) × online_cpus × 100)formula, memory used asusage − stats.cache, sums overnetworksandblkio_stats.io_service_bytes_recursive, formatted with the existing binary units (KiB / MiB / GiB) so the GraphQL response shape is unchanged. stopStatsStream()destroys every active socket plus the events stream soOnModuleDestroyreleases all resources.- Reuses the existing
getDockerClient()helper so the socket path stays in one place.
The change is internal to the service — the DockerContainerStats model, the GraphQL schema, the resolver and the pubsub channel are all untouched. Consumers see fresh values without any client-side change.
Implementation already prepared on jandrop/api:fix/docker-stats-cli-cache for reference:
- 196 lines added / 76 removed in
docker-stats.service.ts - 22 vitest cases in a new
docker-stats.service.spec.tscovering CPU formula + edge cases, memory minus cache, network sum, blkio reads/writes, docker events (start adds, die/stop/kill/destroy remove), malformed JSON resilience, idempotentstartStatsStream,OnModuleDestroycleanup pnpm lint,pnpm type-check,pnpm testall clean (1991 tests pass)
Scope
- API
- Plugin
- Web UI
- Build/Deploy Process
- Documentation
Timeline & Impact
- Estimated time: implementation already done locally; ~1 day for review iteration + any reviewer-requested changes.
- Impact: behaviour fix only —
DockerContainerStatsGraphQL response shape is identical, just with non-frozen values. No new dependencies (dockerodeis already used byDockerEventServiceon the same socket). - Risk: low. Falls back to the existing fail-on-error path; events stream and per-container streams are independently recoverable.
Pre-submission Checklist
- I have searched for similar work/issues
- I understand this needs approval before starting
- I am willing to make adjustments based on feedback
- Lingua principale
- TypeScript
- Stelle
- 113
- Fork
- 23
- Merge medio
- 2g 15h
- PR unite (30g)
- 8
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di unraid/api
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
Work Intent: polish the combined header across mobile and desktopForse già presa @elibosley l’ha presa oggi. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 20/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 64/100
I maintainer di solito rispondono entro 1 giorno
-
Work Intent: File Manager integration for #1599Forse già presa @elibosley l’ha presa 8 giorni fa. Aperta
unraid/api#2103 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Issue simili
-
area/frontend area/v2 kind/bug priority/needs-triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
kubeflow/notebooks#1498 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
P1
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
SuruchBoss/Cwork#90 ·
-
bug cli service
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
521xueweihan/HelloGitHub#3922 ·