Client-side HTTP pipelining does not work
- Dominant language
- Scala
- Stars
- 1.4k
- Forks
- 584
- Avg merge
- 14h 33m
- Merged PRs (30d)
- 24
Description
**Issue by [jrudolph](https://github.com/jrudolph)**
_Monday Sep 05, 2016 at 12:39 GMT_
_Originally opened as https://github.com/akka/akka/issues/21368_
---
HTTP pipelining doesn't work any more in the low-level client-side implementation.
We do not seem to have any tests that exercise that pipelining actually works over the wire.
This test (to be added in LowLevelOutgoingConnectionSpec) fails on the last `expectWireData`:
``` scala
"supports two pipelined requests" in new TestSetup {
requestsSub.sendNext(HttpRequest(uri = "/a"))
expectWireData(
"""GET /a HTTP/1.1
|Host: example.com
|User-Agent: akka-http/test
|
|""")
responsesSub.request(10)
requestsSub.sendNext(HttpRequest(uri = "/b"))
expectWireData(
"""GET /b HTTP/1.1
|Host: example.com
|User-Agent: akka-http/test
|
|""")
}
```
since
```
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[5afab017b08c1ed97099ade57aef83e6b9490383] add fusing
```
(which is not surprising since fusing changed all kinds of buffering behavior).
In the commit where it worked the last time, I tried a similar test:
``` scala
responsesSub.request(10)
def sendOne(id: Int): Unit = {
println(id)
requestsSub.sendNext(HttpRequest(uri = s"/$id"))
expectWireData(
s"""GET /$id HTTP/1.1
|Host: example.com
|User-Agent: akka-http/test
|
|""")
}
(1 to 1000).foreach(sendOne)
```
which will fail only on the 49th request when backpressure kicks in (but where and why?).
In ConnectionPoolSpec, we should have these additional tests:
```
"pipeline several requests on one slot if all running requests are idempotent" in pending
"do not pipeline a further request on one slot if one request is non-idempotent" in pending
"retry idempotent request pipelined after a request with a response that closed the connection" in pending
"retry idempotent request pipelined on a connection that was aborted" in pending
"do not retry non-idempotent request pipelined after a request with a response that closed the connection" in pending
"do not retry non-idempotent request pipelined on a connection that was aborted" in pending
```
When the issue has been fixed, changes from #21316 to PoolSlot need to be revisited to see if everything still works (should also be caught by the new tests).
Contributor guide
Research direction
Start with LowLevelOutgoingConnectionSpec and the failing expectWireData case, then inspect the fusing commit for buffering changes. Run the low-level client and ConnectionPoolSpec tests, including the listed pipelining and retry cases. Done means pipelined requests behave correctly under backpressure and the PoolSlot changes from #21316 still pass the new tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- backend-api-design, networking, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100