okhttp: OkHttp HTTP/2 2nd request being blocked

Hello,

I’m not sure how to explain it more clearly than what ian said so I’ll quote from the original issue

I spotted this bit of the OkHttp docs that suggests this might only happen for HTTP/2 connections (emphasis mine):

When an HTTP request is started, OkHttp will attempt to reuse an existing connection from the pool. If there are no existing connections, a new one is created and put into the connection pool. For HTTP/2, the connection can be reused immediately. For HTTP/1, the request must be completed before it can be reused.

Sure enough, I can make the download proceed while playback is paused by forcing OkHttp to use HTTP 1.1:

OkHttpClient okHttpClient =
   new OkHttpClient.Builder()
       .protocols(ImmutableList.of(Protocol.HTTP_1_1))
       .build();
httpDataSourceFactory = new OkHttpDataSource.Factory((Call.Factory) okHttpClient);

I’m not sure what a better solution here is. It seems reasonable to request a resource twice from the same server (or even at the same URI) and leave one request open/pending/consumed while expecting the other to make progress - and I would expect OkHttp to support this, but it doesn’t seem to.

To reproduce the issue you can checkout my branch: https://github.com/yoobi/ExoPlayer/tree/issue/11120 and do the following:

  1. Go to Misc
  2. Click on Big Bunny (MP4 file) (in order to go to PlayerActivity)
  3. Press Download in the top left corner

You’ll see the download is stuck at the beginning while you’re on the PlayerActivity. Once you leave the PlayerActivity, the download is “resumed” and progress smoothly

it looks to be somewhat related to https://github.com/square/okhttp/issues/7764 but I’m not entirely sure

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 18

Most upvoted comments

Released

Any forecast when this will land in a 5.0-alpha or (even better) in a 4.12? I tested the 5.0-SNAPSHOT and the fix works 💯

HTTP/2 is over a multiplexed socket, so if one request has data, but is not being read, it can block other requests.

OkHttp doesn’t handle this at all, but it’s possible there are some improvements in either Media3/ExoPlayer or OkHttp that could make this less likely.

As an extra bit of info, if you switch @yoobi’s demo to use Media3’s CronetDataSource it still uses HTTP/2 (confirmed via JSON netlog) but the download isn’t blocked by playback being paused - so it seems there is something the HTTP stack can change to avoid the blocking of seemingly ‘independent’ reads (from an API consumer perspective) that is being reported here.

@yschimke do you plan to release 4.12?

Fix coming in 5, hopefully to land in a 4.12 at some point.

This is no longer reproducible on the exoplayer demo using a 5.0.0-SNAPSHOT, the download completes quickly and successfully.

I’d like to wait for a 5.0.0-alpha release gets some real use, before looking to backport to a 4.12. So it’s probably a small number of weeks for a 5 alpha, and couple of months for a 4.12? But that’s a guess.

to test, change to version 5.0.0-SNAPSHOT and add this repository

        maven {
            url = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
        }

I’ve reproduced with your repo and an emulator, and tried reproducing in a standalone JVM project without success. So trying to get the right logging in place to understand what’s going on in the emulator.