Python requests sometimes freezes
Asked Answered
S

2

9

I have a Python program which sends several (about 5-6) long poll requests in parallel using different threads for each poll via requests package. And I realized that some of my threads sometimes just freeze. When this happens, the server I am sending the request does not receive the request. Also I set a timeout on the request and it does not work.

try:
    print("This line prints")
    response = requests.head(poll_request_url, timeout=180)
    print("This line does not print when freeze occurs")
except ReadTimeout:
    print("Request exception.")
except RequestException as e:
    print("Request exception.")
except Exception:
    print("Unknown exception.")
print("This line does not print either when freeze occurs.")

I am doing this on Raspberry Pi 2 hardware with Raspbian OS.

I used this same program without a problem when I was using Python 2.7. Recently I switched to Python 3.5. I tested using both requests versions with 2.8.1 and 2.9.1.

This problem does not occur very frequently but happens 2-3 times per day on different threads.

What might be the problem? How can I debug this?

Edit: The problem is solved by updating the Linux kernel.

Spies answered 9/2, 2016 at 12:27 Comment(0)
T
7

According to the docs:

http://docs.python-requests.org/en/master/user/quickstart/#timeouts

It should be throwing a Timeout exception, when the timeout happens. That would mean that the line:

print("This line does not print when freeze occurs")

Would never be called it a timeout actually happens.

Are you catching the exception? Or any other exception? It might be that it's timing out fine, but you just aren't seeing this. Maybe try something like this:

try:
    response = requests.head(poll_request_url, timeout=180)
except requests.exceptions.Timeout:
    print("Timeout occurred")

So you can see if that's what is going on.

EDIT: possibly it's the "connect" step that's not timing out correctly. It may be the large timeout value for the "connect" step is messing it up somehow. Perhaps trying having a shorter timeout for that (as mentioned here):

http://docs.python-requests.org/en/master/user/advanced/#timeouts

e.g.

response = requests.head(poll_request_url, timeout=(3, 180))

Failing that it might be some sort of DNS lookup issue? Maybe see if hardcoding the IPs presents the same problem?

Toper answered 9/2, 2016 at 13:8 Comment(10)
I am catching all the exceptions including Timeout, and when timeout happens it catches the exception successfully. It is when the timeout does not happen and freeze happens, that line is never executed and no exception is thrown.Nowt
I added some more context to the code to reflect the exception handling.Nowt
This must be failing to timeout during the "connect" step - as you say you never receive a request on the server.Toper
Edit with suggestions for connect timeoutToper
Thanks, I'll try and post the results.Nowt
@CanolGökel Is there any update? Did it solve your problem?Inapprehensive
No, unfortunately not. And I haven't got much further on finding out the problem, it is still occurring.Nowt
One last thing to try would be to add a general "except" that would catch everything else. It might be that the error isn't even throwing an "Exception", but something that extends from "BaseException" instead.Toper
@CanolGökel I have the same problem. Which kernel do you mean, Linux kernel?Dorsad
@Dorsad yes the Linux kernel. If I remember correctly, I used rpi-update to update the kernel and it fixed the problem. But before doing that, make absolutely sure that the problem is not because of some other reason like a race condition in your code, for example. We eliminated every possibility before we could conclude that it was a kernel issue and it took us weeks.Nowt
S
3

Solved my problem using timers (from threading import Timer). If no result next 10 seconds - repeat, if no result next 10 seconds - print 'Error' and go on. You can't monitor timer status with if statement if request freezes, but you can do it through while loop, adding time if result is ok (Python: Run code every n seconds and restart timer on condition).

Sorrento answered 17/8, 2017 at 14:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.