Closed cheburakshu closed 6 years ago
It's highly likely that the responses contain enough data that if you aren't reading them the streams don't complete. In general you need to be reading responses to ensure that the flow control window moves appropriately.
It is because of h2 expecting the global no. of streams to be less than 100.
https://github.com/Lukasa/hyper/blob/development/hyper/http20/response.py#L143
The stream is closed after reading a response for the current request. Is there a reason for doing so? So, this ensures the no. of active streams never exceed the specified global 100, but incurs heavy overhead when additonal requests create streams instead of re-using the existing ones.
# We're at the end, close the connection.
if response_complete:
self.close()
New streams are created for each request and it is behind a lock and adds overhead for request:
https://github.com/Lukasa/hyper/blob/development/hyper/http20/connection.py#L600
def _new_stream(self, stream_id=None, local_closed=False):
"""
Returns a new stream object for this connection.
"""
# Concurrency
#
# Hold _lock: ensure that threads accessing the connection see
# self.next_stream_id in a consistent state
#
# No I/O occurs, the delay in waiting threads depends on their number.
with self._lock:
s = Stream(
stream_id or self.next_stream_id,
self.__wm_class(DEFAULT_WINDOW_SIZE),
self._conn,
self._send_outstanding_data,
self._recv_cb,
self._stream_close_cb,
)
s.local_closed = local_closed
self.streams[s.stream_id] = s
self.next_stream_id += 2
return s
ENV:
If I create a connection, create 101 requests without reading a response, it aborts with TooManyStreamsError. But, if I redo it by reading the response also, the error does not occur.
Questions:
Standalone client: client.py
If the above code is executed, the below error results:
Error:
But, if the same is done with responses read, it works, even if the no. of requests is raised to 1000!