Ensure no more than one response per request
Overview
Due to a retry loop in erlfb:transactional couchdb might try to send multiple http responses for a single request which is clearly an error.
This PR ensures the second attempt is prevented, closing the TCP socket instead.
Testing recommendations
I induced this by making a large db (10,000 docs) and queried a view that emitted a row for each, but any long-running streamed response endpoint (except _changes) will suffice. If you use curl with --raw you will see a new 200 OK starting after approximately 5 seconds. With this PR applied you will instead get a curl: (18) transfer closed with outstanding read data remaining error.
Related Issues or Pull Requests
N/A
Checklist
- [x] Code is written and works correctly
- [ ] Changes are covered by tests
- [ ] Any new configurable parameters are documented in
rel/overlay/etc/default.ini - [ ] A PR for documentation changes has been made in https://github.com/apache/couchdb-documentation
[notice] 2020-11-12T12:42:34.897280Z [email protected] <0.984.0> 92483dbd6f localhost:15984 127.0.0.1 foo GET /db1/_design/foo/_view/bar?include_docs=true&reduce=false 500 aborted 3091
[error] 2020-11-12T12:42:34.897318Z [email protected] <0.984.0> 92483dbd6f Response abnormally terminated: multiple_responses_attempted
This is how a response is logged if two responses are sent for the same request (due to the erlfdb retry loop). What do we think?
@rnewson : is this PR applicable for 3.x? I know there is no erlfb:transactional, but does the issue ever happen there?
This is a nice PR to have. I will test with with buggify mode enabled and with some of the recent fixes to handle multiple-responses reverted (to validate that we get nicer error than retransmitted responses when they happen).
@bessbd may not apply to 3.x as much as don't usually retry top level request handling closures