Skip to content

Instantly share code, notes, and snippets.

@bagder
Last active February 17, 2020 13:31
Show Gist options
  • Select an option

  • Save bagder/63b7e4fd90669e0b901c2e22a950110c to your computer and use it in GitHub Desktop.

Select an option

Save bagder/63b7e4fd90669e0b901c2e22a950110c to your computer and use it in GitHub Desktop.
An h2 pausing and window size quirk

Test app

We use nghttp2's auto handling of window sizes.

Start out with window size set to 500K and we do two h2 streams (multiple megabytes) over a single connection from a local server.

  1. The first stream (1) is paused as soon as data arrives.
  2. The second stream (3) goes through and when it is done, unpauses the stream 1 transfer.

Pause

When pause is returned from the callback (on first invoke for stream 1), libcurl sets the local window size for the stream to 0 (with nghttp2_session_set_local_window_size()). This then makes us receive 500K of data to buffer in memory since we already promised the 500K - but no more.

Unpause

When unpaused, libcurl first deliver the 500K buffered data to the callback, then sets the local window size for stream 1 to 500K again and continues. (Using nghttp2_session_set_local_window_size() again.)

Problem!!

Setting the local window size to 500K and then reading back the local size again says the window size is zero and indeed no data will flow. It is stuck.

Workaround

Instead if we set the local window size for stream 1 to 500K * 2 in the unpause, we get the flow going again and the rest of the data arrives. But now with a window size of 1000K which if we pause again will require twice the memory! Not a good situation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment