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
    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, '', ('', 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, '', ('', 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/

    import time
    import usocket
    import machine
    import _thread
    >>> import dnstest; dnstest.dns_lookup('')
    0 None
    1 (2, 1, 0, '', ('', 443))
    2 (2, 1, 0, '', ('', 443))
    3 (2, 1, 0, '', ('', 443))
    4 (2, 1, 0, '', ('', 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)

    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

Log in to reply

Pycom on Twitter