question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to make a connection never timeout

See original GitHub issue

Problem

I use httpx to request a kubernetes watch api. The api is based on HTTP chunked transfer encoding. When the server generates a new pod message, it will send to client.

Simplified code is as follows

import httpx

resp = httpx.get('http://127.0.0.1:18081/api/v1/watch/pods', stream=True)
for chunk in resp.stream():
    pass

After 5 second, I get a ReadTimeout error

Traceback (most recent call last):
  File "t.py", line 4, in <module>
    for line in resp.stream():
  File "/usr/local/lib/python3.6/site-packages/httpx/models.py", line 1077, in stream
    for chunk in self.raw():
  File "/usr/local/lib/python3.6/site-packages/httpx/models.py", line 1105, in raw
    for part in self._raw_stream:
  File "/usr/local/lib/python3.6/site-packages/httpx/concurrency/base.py", line 163, in iterate
    yield self.run(async_iterator.__anext__)
  File "/usr/local/lib/python3.6/site-packages/httpx/concurrency/asyncio.py", line 261, in run
    return self.loop.run_until_complete(coroutine(*args, **kwargs))
  File "/usr/lib64/python3.6/asyncio/base_events.py", line 484, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.6/site-packages/httpx/dispatch/http11.py", line 152, in _receive_response_data
    event = await self._receive_event(timeout)
  File "/usr/local/lib/python3.6/site-packages/httpx/dispatch/http11.py", line 174, in _receive_event
    self.READ_NUM_BYTES, timeout, flag=self.timeout_flag
  File "/usr/local/lib/python3.6/site-packages/httpx/concurrency/asyncio.py", line 83, in read
    raise ReadTimeout() from None
httpx.exceptions.ReadTimeout

I change the timeout to 60 sec, and I will get RemoteProtocolError

Traceback (most recent call last):
  File "t.py", line 4, in <module>
    for chunk in resp.stream():
  File "/usr/local/lib/python3.6/site-packages/httpx/models.py", line 1077, in stream
    for chunk in self.raw():
  File "/usr/local/lib/python3.6/site-packages/httpx/models.py", line 1105, in raw
    for part in self._raw_stream:
  File "/usr/local/lib/python3.6/site-packages/httpx/concurrency/base.py", line 163, in iterate
    yield self.run(async_iterator.__anext__)
  File "/usr/local/lib/python3.6/site-packages/httpx/concurrency/asyncio.py", line 261, in run
    return self.loop.run_until_complete(coroutine(*args, **kwargs))
  File "/usr/lib64/python3.6/asyncio/base_events.py", line 484, in run_until_complete
    return future.result()
  File "/usr/local/lib/python3.6/site-packages/httpx/dispatch/http11.py", line 152, in _receive_response_data
    event = await self._receive_event(timeout)
  File "/usr/local/lib/python3.6/site-packages/httpx/dispatch/http11.py", line 164, in _receive_event
    event = self.h11_state.next_event()
  File "/usr/local/lib/python3.6/site-packages/h11/_connection.py", line 420, in next_event
    event = self._extract_next_receive_event()
  File "/usr/local/lib/python3.6/site-packages/h11/_connection.py", line 369, in _extract_next_receive_event
    event = self._reader.read_eof()
  File "/usr/local/lib/python3.6/site-packages/h11/_readers.py", line 170, in read_eof
    "peer closed connection without sending complete message body "
h11._util.RemoteProtocolError: peer closed connection without sending complete message body (incomplete chunked read)

Environment

  • Python 3.6.3
  • httpx 0.7.4

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:19 (17 by maintainers)

github_iconTop GitHub Comments

9reactions
florimondmancacommented, Sep 29, 2019

There are actually three kinds of timeouts you can control in HTTPX: connect, read, and write. Unfortunately, the documentation doesn’t show this ability to fine-tune timeouts yet (TimeoutConfig isn’t even documented), and I agree it’s something we need to address.

For your use case, it seems what you want is to modify the read timeout. (That way, you’ll still timeout when connecting or when sending data, which is good because those are unexpected situations.)

The following should work:

import httpx

timeout = httpx.TimeoutConfig(connect_timeout=5, read_timeout=None, write_timeout=5)

resp = httpx.get('http://127.0.0.1:18081/api/v1/watch/pods', stream=True, timeout=timeout)
for chunk in resp.stream():
    pass

Unfortunately there’s no way to override only one of the timeouts while keeping default values for the others, so you need to explicitly set the connect and write timeouts. I reckon what we’d need is something like:

timeout = httpx.DEFAULT_TIMEOUT_CONFIG.replace(read_timeout=None)

but that doesn’t exist yet.

Also — according to this SO thread you should expect the connection to drop anyway, so a long timeout along with an infinite loop that reconnects when losing the connection to the watch endpoint might be preferable:

def get_pod_events():
    timeout = httpx.TimeoutConfig(connect_timeout=5, read_timeout=5 * 60 write_timeout=5)
    while True:
        resp = httpx.get('http://127.0.0.1:18081/api/v1/watch/pods', stream=True, timeout=timeout)
        for event in resp.stream():
            yield event
7reactions
luckydonaldcommented, Oct 7, 2020

Note, TimeoutConfig is now simply called Timeout.

Read more comments on GitHub >

github_iconTop Results From Across the Web

how to make putty ssh connection never to timeout when user ...
If you go to your putty settings -> Connection and set the value of "Seconds between keepalives" to 30 seconds this should solve...
Read more >
How to disable SSH timeout - Simplified Guide
You can increase SSH connection timeout by configuring TCPKeepAlive and related settings both from the SSH server and the client. Methods to prevent...
Read more >
The Connection Has Timed Out How To Fix It Tutorial - YouTube
... Out -- How To Fix It [Tutorial].A server connection timeout means that a server is taking too long to reply to a...
Read more >
Artificially create a connection timeout error - Stack Overflow
To test a connection timeout at the socket level, freeze the nc process with a kill -STOP <pid> (or just CTRL-Z it without...
Read more >
SqlConnection.ConnectionTimeout Property - Microsoft Learn
You can set the amount of time a connection waits to time out by using the Connect Timeout or Connection Timeout keywords in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found