akka / akka/akka-http

Client-side HTTP pipelining does not work

Open
#32 7 comments 0 reactions 0 assignees View on GitHub
1 - triaged medium t:client
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.