http4s / blaze

Blazing fast NIO microframework and Http Parser

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"IllegalStateException: Cannot have multiple pending reads" when using blaze

yanns opened this issue · comments

When using http4s as HTTP client, we often have this issue:

java.lang.IllegalStateException: Cannot have multiple pending reads
  at org.http4s.client.blaze.ReadBufferStage.readRequest(ReadBufferStage.scala:43)
  at org.http4s.blaze.pipeline.Tail.channelRead(Stages.scala:93)
  at org.http4s.blaze.pipeline.Tail.channelRead$(Stages.scala:91)
  at org.http4s.client.blaze.Http1Connection.channelRead(Http1Connection.scala:41)
  at org.http4s.client.blaze.Http1Connection.readAndParsePrelude(Http1Connection.scala:205)
  at org.http4s.client.blaze.Http1Connection.$anonfun$receiveResponse$1(Http1Connection.scala:196)
  at org.http4s.client.blaze.Http1Connection.$anonfun$receiveResponse$1$adapted(Http1Connection.scala:195)
  at async @ org.http4s.client.blaze.Http1Connection.receiveResponse(Http1Connection.scala:195)
  at >>$extension @ org.http4s.client.blaze.Http1Connection.$anonfun$executeRequest$2(Http1Connection.scala:178)
  at flatMap @ org.http4s.client.blaze.Http1Connection.$anonfun$executeRequest$2(Http1Connection.scala:180)
  at flatMap @ org.http4s.client.blaze.Http1Connection.$anonfun$executeRequest$1(Http1Connection.scala:162)
  at map @ org.http4s.client.blaze.BlazeClient$.$anonfun$makeClient$9(BlazeClient.scala:109)
  at runSyncUnsafe @ com.github.agourlay.cornichon.http.client.Http4sClient.<init>(Http4sClient.scala:68)
  at makeCase @ org.http4s.client.blaze.BlazeClient$.borrow$1(BlazeClient.scala:79)
  at use @ org.http4s.client.blaze.BlazeClient$.org$http4s$client$blaze$BlazeClient$$loop$1(BlazeClient.scala:101)
  at runSyncUnsafe @ com.github.agourlay.cornichon.http.client.Http4sClient.<init>(Http4sClient.scala:68)
  at asyncF @ org.http4s.client.PoolManager.borrow(PoolManager.scala:168)
  at makeCase @ org.http4s.client.blaze.BlazeClient$.borrow$1(BlazeClient.scala:79)
  at use @ org.http4s.client.blaze.BlazeClient$.org$http4s$client$blaze$BlazeClient$$loop$1(BlazeClient.scala:101)
  at use @ com.github.agourlay.cornichon.http.client.Http4sClient.$anonfun$runRequest$2(Http4sClient.scala:104)
  at delayExecution @ com.github.agourlay.cornichon.http.client.Http4sClient.$anonfun$runRequest$2(Http4sClient.scala:118)
  at map @ com.github.agourlay.cornichon.http.client.Http4sClient.$anonfun$runRequest$2(Http4sClient.scala:121)
  at flatMap @ com.github.agourlay.cornichon.http.HttpService.runRequest(HttpService.scala:67)

This issue happens when using cornichon: agourlay/cornichon#391

This looks in the neighborhood of http4s/http4s#4143, but that was WritePending, not ReadPending.

I don't see any obvious misuse in the cornichon source. This smells like a bug.

Thanks for the pointer.
If you have an idea on a test that could reproduce this issue, I could spend some time on it.

@RaasAhsan found the write side of this, but I think through reasoning about the (unreasonable in this area) code rather than iterating on a failing test. Perhaps he has a pointer?

sorry i missed this - seems like the exception is being thrown here https://github.com/http4s/http4s/blob/series/0.21/blaze-client/src/main/scala/org/http4s/client/blaze/ReadBufferStage.scala#L43

understanding how this state machine works will probably be the key to understanding why this bug is happening, so i'll try to spend some time on that tomorrow