-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
request()
retries fetch twice, which can cause timeouts that are twice as long as requested
#191
Comments
When I pulled out code for ConnectionManager, I tried to find a way to make this happen for real, but couldn't. Do you have a way to make it happen? |
Here's a rather rough program I used (I originally used some personal domains that I knew succeeded or failed, but I tried again with the ones listed): import os
import time
import wifi
import adafruit_connection_manager
import adafruit_requests
class Timer:
def __init__(self, title):
self.title = title
def __enter__(self):
self.start = time.monotonic()
return self
def __exit__(self, type, value, traceback):
print(self.title+":", time.monotonic() - self.start)
# Get WiFi details, ensure these are setup in settings.toml
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
SUCCEED_URL = "https://example.org"
FAIL_URL = "https://192.168.1.253"
pool = adafruit_connection_manager.get_radio_socketpool(wifi.radio)
ssl_context = adafruit_connection_manager.get_radio_ssl_context(wifi.radio)
requests = adafruit_requests.Session(pool, ssl_context)
wifi.radio.connect(ssid, password)
with Timer("default success"):
response = requests.get(SUCCEED_URL)
try:
with Timer("default fail"):
response = requests.get(FAIL_URL)
except Exception as e:
print(e)
with Timer("timeout success"):
response = requests.get(SUCCEED_URL, timeout=2)
try:
with Timer("timeout fail"):
response = requests.get(FAIL_URL, timeout=3)
except Exception as e:
print(e) with output:
Note that the last |
What MCU are you using? On a
On an
|
I was using a Metro ESP32-S3 |
My testing was with adafruit/circuitpython#9210, not yet merged as of this writing. I shjould test that on an S2, then. |
What was odd was that the UM FeatherS3 seemed to ignore the timeouts. I remember some other boards did that in 8.x |
@dhalbert tomorrow I'll try again on both my S2 and UMS3 with that build |
@dhalbert, added some logging. The double timeout in this case is in ConnectionManager. The flow from CM is that it tries once, and then if it fails and has any sockets it can release to try again after closing them:
If I just do: try:
with Timer("timeout fail"):
response = requests.get(FAIL_URL, timeout=3)
except Exception as e:
print(f"error: {e}") I get:
What we could do is in CM, look at specific errors like:
And stop trying. Thoughts? If you help me come up with which ones to not try again on, I can open up a PR in CM |
Ah, OK, so it is not the retry loop in requests at all, you're saying? So I was mistaken. Does it not make sense to close a socket before trying, because we'd like to reuse a socket that has an existing open connection to a particular host? I think it would be worth looking at the logic in CPython requests and lower down, if necessary, because they don't have double timeouts. I am not more experienced with socket programming than you. |
I totally want to make this better. I trimmed what I could from the previous request code. It used to try up to 5 times... I think making both I'll try some other things and see if I can get it to try the second time |
request()
tries twice to get a socket, connect, and fetch twice:Adafruit_CircuitPython_Requests/adafruit_requests.py
Lines 513 to 518 in 12e6b47
This is confusing because if it tries a second time, it can make the default or user specified timeout (see #9210) appear to take twice as long as requested.
I am not sure about the circumstances the comment is talking about:
Adafruit_CircuitPython_Requests/adafruit_requests.py
Line 513 in 12e6b47
and whether it's true for non-ESP32-SPI, etc. I wonder if some checking or resetting of the socket can be done in advance.
The text was updated successfully, but these errors were encountered: