POST /api/v1/reports answers 200 {"status":"ok"} once a report is in memory; it is written to DATA_DIR up to a minute later. When that write fails (disk full, directory gone, no permission), its reports are dropped and the failure is only logged, and every later report is still answered 200 for as long as writes keep failing. The page moves its marks past samples it was told were stored, so it never sends them again.
Where, on next at b1eefe0: backend/internal/reportbuf/reportbuf.go: Append (line 175) never looks at whether writes succeed; a failed write is only logged, by flushLoop (line 258) or by the size flush (line 204), and writeFile drops its reports (line 310). backend/internal/handlers/report.go answers ok at line 64.
How to see it: start the buffer, append a report, remove DATA_DIR, flush (it fails), then append another report: Append returns nil, which the handler answers 200. In the image the same happens when the /data volume is full.
What is right: #23, definition of done: "A storage failure results in a non-2xx response. The client is never told "ok" for a report that was not persisted." README.md, Reporting: the page's mark advances only on a delivered report, so a refused report is sent again at the next interval.
Severity: medium. Every report is lost while storage fails, and only the server's log shows it.
Definition of done
While report files cannot be written, a report is answered with a non-2xx status, so the page keeps its samples and sends them again.
Once writing works again, reports are stored and answered 200, with no restart.
A test makes a write fail, posts a report and gets a non-2xx answer, then lets writes succeed and finds the next report stored.
TODO.md updated in the same commit; commit title ends (closes #N).
Model: opus-5-5
`POST /api/v1/reports` answers 200 `{"status":"ok"}` once a report is in memory; it is written to `DATA_DIR` up to a minute later. When that write fails (disk full, directory gone, no permission), its reports are dropped and the failure is only logged, and every later report is still answered 200 for as long as writes keep failing. The page moves its marks past samples it was told were stored, so it never sends them again.
**Where**, on `next` at `b1eefe0`: `backend/internal/reportbuf/reportbuf.go`: `Append` (line 175) never looks at whether writes succeed; a failed write is only logged, by `flushLoop` (line 258) or by the size flush (line 204), and `writeFile` drops its reports (line 310). `backend/internal/handlers/report.go` answers ok at line 64.
**How to see it**: start the buffer, append a report, remove `DATA_DIR`, flush (it fails), then append another report: `Append` returns nil, which the handler answers 200. In the image the same happens when the `/data` volume is full.
**What is right**: https://git.eeqj.de/sneak/netwatch/issues/23, definition of done: "A storage failure results in a non-2xx response. The client is never told "ok" for a report that was not persisted." `README.md`, Reporting: the page's mark advances only on a delivered report, so a refused report is sent again at the next interval.
**Severity**: medium. Every report is lost while storage fails, and only the server's log shows it.
## Definition of done
- [ ] While report files cannot be written, a report is answered with a non-2xx status, so the page keeps its samples and sends them again.
- [ ] Once writing works again, reports are stored and answered 200, with no restart.
- [ ] A test makes a write fail, posts a report and gets a non-2xx answer, then lets writes succeed and finds the next report stored.
- [ ] `TODO.md` updated in the same commit; commit title ends ` (closes #N)`.
Model: opus-5-5
clawbot
self-assigned this 2026-10-14 11:00:48 +02:00
#130: a failed write of a report file keeps its reports in memory, and every report after it is refused with 500 until a write succeeds. The flush that runs every minute tries the held reports again, so storing resumes with no restart once writing works. Reports already answered 200 are written by the next write that succeeds; they are lost only if the server stops while writes still fail, and the process then exits non-zero.
Judgement call: 500, not 507, because a failed write is a storage failure, not a full cap; 507 keeps its one meaning.
Model: opus-5-5
https://git.eeqj.de/sneak/netwatch/pulls/130: a failed write of a report file keeps its reports in memory, and every report after it is refused with 500 until a write succeeds. The flush that runs every minute tries the held reports again, so storing resumes with no restart once writing works. Reports already answered 200 are written by the next write that succeeds; they are lost only if the server stops while writes still fail, and the process then exits non-zero.
Judgement call: 500, not 507, because a failed write is a storage failure, not a full cap; 507 keeps its one meaning.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
POST /api/v1/reportsanswers 200{"status":"ok"}once a report is in memory; it is written toDATA_DIRup to a minute later. When that write fails (disk full, directory gone, no permission), its reports are dropped and the failure is only logged, and every later report is still answered 200 for as long as writes keep failing. The page moves its marks past samples it was told were stored, so it never sends them again.Where, on
nextatb1eefe0:backend/internal/reportbuf/reportbuf.go:Append(line 175) never looks at whether writes succeed; a failed write is only logged, byflushLoop(line 258) or by the size flush (line 204), andwriteFiledrops its reports (line 310).backend/internal/handlers/report.goanswers ok at line 64.How to see it: start the buffer, append a report, remove
DATA_DIR, flush (it fails), then append another report:Appendreturns nil, which the handler answers 200. In the image the same happens when the/datavolume is full.What is right: #23, definition of done: "A storage failure results in a non-2xx response. The client is never told "ok" for a report that was not persisted."
README.md, Reporting: the page's mark advances only on a delivered report, so a refused report is sent again at the next interval.Severity: medium. Every report is lost while storage fails, and only the server's log shows it.
Definition of done
TODO.mdupdated in the same commit; commit title ends(closes #N).Model: opus-5-5
#130: a failed write of a report file keeps its reports in memory, and every report after it is refused with 500 until a write succeeds. The flush that runs every minute tries the held reports again, so storing resumes with no restart once writing works. Reports already answered 200 are written by the next write that succeeds; they are lost only if the server stops while writes still fail, and the process then exits non-zero.
Judgement call: 500, not 507, because a failed write is a storage failure, not a full cap; 507 keeps its one meaning.
Model: opus-5-5