TestAnAppTooSlowToAnswerIsAnswered504 in internal/rproxy/limits_test.go failed once in four make check runs of #296, with the host's load average above 60:
The visitor's connection was closed with no answer, where the test expects a 504. The test sets SWRP_MAX_RESPONSE_TIME_MS to 300. The -v rerun in the same step passed.
Not established:
The cause. Whether a real visitor can get this closed connection instead of a 504 under load is the question to answer first, because that would be a bug in rproxy and not only in the test. setResponseDeadline and prepareOwnAnswer in internal/rproxy/request.go both set the write deadline on that connection.
How often it fails. It may fail more often since that PR, which runs the two test passes at the same time and so adds CPU contention during the race pass.
Definition of done: the cause is found; a visitor gets the 504 whenever the limit runs out; the test passes reliably at this host's usual load, with no test, request or value removed.
Model: opus-5-5
`TestAnAppTooSlowToAnswerIsAnswered504` in `internal/rproxy/limits_test.go` failed once in four `make check` runs of https://git.eeqj.de/sneak/smallwebwaf/pulls/296, with the host's load average above 60:
```
--- FAIL: TestAnAppTooSlowToAnswerIsAnswered504 (0.87s)
limits_test.go:594: request: EOF
```
The visitor's connection was closed with no answer, where the test expects a 504. The test sets `SWRP_MAX_RESPONSE_TIME_MS` to 300. The `-v` rerun in the same step passed.
**Not established:**
- The cause. Whether a real visitor can get this closed connection instead of a 504 under load is the question to answer first, because that would be a bug in `rproxy` and not only in the test. `setResponseDeadline` and `prepareOwnAnswer` in `internal/rproxy/request.go` both set the write deadline on that connection.
- How often it fails. It may fail more often since that PR, which runs the two test passes at the same time and so adds CPU contention during the race pass.
**Definition of done:** the cause is found; a visitor gets the 504 whenever the limit runs out; the test passes reliably at this host's usual load, with no test, request or value removed.
Model: opus-5-5
Plan. In internal/rproxy, whose doc says it is the proxy in front of the app, and its tests. Find the cause first; the fix follows from it.
Reproduce: run TestAnAppTooSlowToAnswerIsAnswered504 many times under CPU pressure, for example with -count and other work running beside it, until it fails. Read setResponseDeadline and prepareOwnAnswer in internal/rproxy/request.go, and what each does to the connection's write deadline when the two timers race.
Decide what it is, and say which on this issue, before fixing:
If a visitor can really get a closed connection instead of the 504 when the limit runs out, that is a bug in rproxy: fix it, and add a test that fails without the fix.
If only the test's own timing is wrong, fix the test so it no longer depends on how fast the host is. Do not lengthen the limit to hide it.
Check: the test passes repeatedly under CPU pressure. No test, request or value is removed.
Follow AGENTS.md: checks only through make targets. make fmt, then flock -w 1800 /srv/code/tmp/.gate-smallwebwaf.lock make check; a flock timeout also exits 1, so read the output. A repeated run of the one test while finding the cause is the exception, and is not committed. Start no subagent on another model. Label the PR needs-review, title ending (closes #295).
Model: opus-5-5
**Plan.** In `internal/rproxy`, whose doc says it is the proxy in front of the app, and its tests. Find the cause first; the fix follows from it.
- **Reproduce:** run `TestAnAppTooSlowToAnswerIsAnswered504` many times under CPU pressure, for example with `-count` and other work running beside it, until it fails. Read `setResponseDeadline` and `prepareOwnAnswer` in `internal/rproxy/request.go`, and what each does to the connection's write deadline when the two timers race.
- **Decide what it is, and say which on this issue, before fixing:**
- If a visitor can really get a closed connection instead of the 504 when the limit runs out, that is a bug in `rproxy`: fix it, and add a test that fails without the fix.
- If only the test's own timing is wrong, fix the test so it no longer depends on how fast the host is. Do not lengthen the limit to hide it.
- **Check:** the test passes repeatedly under CPU pressure. No test, request or value is removed.
Follow `AGENTS.md`: checks only through `make` targets. `make fmt`, then `flock -w 1800 /srv/code/tmp/.gate-smallwebwaf.lock make check`; a `flock` timeout also exits 1, so read the output. A repeated run of the one test while finding the cause is the exception, and is not committed. Start no subagent on another model. Label the PR `needs-review`, title ending ` (closes #295)`.
Model: opus-5-5
clawbot
self-assigned this 2026-11-10 17:43:57 +01:00
Verdict: a bug in rproxy, so a real visitor can get the closed connection. The write deadline of the 504 was as short as the limit itself, and a host stall that long fails the first write. The natural failure was not reproduced, so this cause rests on elimination and a forced stall. The fix and the evidence are in #297.
Model: opus-5-5
**Verdict: a bug in `rproxy`, so a real visitor can get the closed connection.** The write deadline of the 504 was as short as the limit itself, and a host stall that long fails the first write. The natural failure was not reproduced, so this cause rests on elimination and a forced stall. The fix and the evidence are in https://git.eeqj.de/sneak/smallwebwaf/pulls/297.
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.
TestAnAppTooSlowToAnswerIsAnswered504ininternal/rproxy/limits_test.gofailed once in fourmake checkruns of #296, with the host's load average above 60:The visitor's connection was closed with no answer, where the test expects a 504. The test sets
SWRP_MAX_RESPONSE_TIME_MSto 300. The-vrerun in the same step passed.Not established:
rproxyand not only in the test.setResponseDeadlineandprepareOwnAnswerininternal/rproxy/request.goboth set the write deadline on that connection.Definition of done: the cause is found; a visitor gets the 504 whenever the limit runs out; the test passes reliably at this host's usual load, with no test, request or value removed.
Model: opus-5-5
Plan. In
internal/rproxy, whose doc says it is the proxy in front of the app, and its tests. Find the cause first; the fix follows from it.TestAnAppTooSlowToAnswerIsAnswered504many times under CPU pressure, for example with-countand other work running beside it, until it fails. ReadsetResponseDeadlineandprepareOwnAnswerininternal/rproxy/request.go, and what each does to the connection's write deadline when the two timers race.rproxy: fix it, and add a test that fails without the fix.Follow
AGENTS.md: checks only throughmaketargets.make fmt, thenflock -w 1800 /srv/code/tmp/.gate-smallwebwaf.lock make check; aflocktimeout also exits 1, so read the output. A repeated run of the one test while finding the cause is the exception, and is not committed. Start no subagent on another model. Label the PRneeds-review, title ending(closes #295).Model: opus-5-5
Verdict: a bug in
rproxy, so a real visitor can get the closed connection. The write deadline of the 504 was as short as the limit itself, and a host stall that long fails the first write. The natural failure was not reproduced, so this cause rests on elimination and a forced stall. The fix and the evidence are in #297.Model: opus-5-5