getaddrinfo in a thread
-
DNS lookups via 4G on a GPY can take up to 20s if things don't go well
import time, usocket, _thread def _dns(host, port): ai = usocket.getaddrinfo(host, port); ai=ai[0]; return ai start=time.time() ai=_dns('some url', 443) stop=time.time(); wait=stop-start; print('wait =', wait, ' dns =', ai)
for example, returns
wait = 14 dns = (2, 1, 0, '', ('0.0.0.0', 443))
Since we can't wait that long in a battery powered GPY we tried a thread
import time, usocket, _thread def _dns(host, port): global ai; ai=usocket.getaddrinfo(host, port); ai=ai[0] start=time.time(); ai=0 _thread.start_new_thread(_dns, ('some url', 443)) for i in range(5): print(i, ai), time.sleep(1) if ai: break stop=time.time(); wait=stop-start; print('wait =', wait, ' dns =', ai)
more or less the same result
0 0 wait = 13 dns = (2, 1, 0, '', ('0.0.0.0', 443))
We don't get it. Why doesn't the main program timeout after 5s? Why does it pause after the first iteration of the loop & wait for the thread? Isn't the idea of a thread that it allows the main program to continue regardless of what the thread is doing?
-
Just retyped this for the sake of improved readability. You might want to save it as
/flash/lib/dnstest.py
.import time import usocket import machine import _thread """ >>> import dnstest; dnstest.dns_lookup('google.com') 0 None 1 (2, 1, 0, '', ('172.217.18.14', 443)) 2 (2, 1, 0, '', ('172.217.18.14', 443)) 3 (2, 1, 0, '', ('172.217.18.14', 443)) 4 (2, 1, 0, '', ('172.217.18.14', 443)) """ response = None def run_getaddrinfo(host, port): global response response = usocket.getaddrinfo(host, port)[0] def dns_lookup(hostname, timeout=5): _thread.start_new_thread(run_getaddrinfo, (hostname, 443)) for i in range(timeout): print(i, response) machine.idle() time.sleep(1) print('Ready.')
It works flawlessly over a WiFi connection, but LTE might well have its delicacies.
-
What should
print(i, ai), time.sleep(1)
actually do? I believe your thread might crash without notice.@andreas said in urequests timeouts:
I can't decipher your code
However, you might want to add
machine.idle()
while you are waiting for the thread outcome in order to feed the OS scheduler.
-
getaddrinfo
does not only have issues on MicroPython when used in a thread [1]. These things are tricky.
-
This post is deleted!
-
Is this guy for real?!
-
@kjm GPY works with the 5G LTE CAT M1 and NB-Iot. You need to buy a 5G sim card from a service provider and follow the examples found on our website: CAT M1 and NB-Iot