Poll class not working - urequest

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
User avatar
MorseIot
Posts: 38
Joined: Fri Jun 29, 2018 12:32 am

Poll class not working - urequest

Post by MorseIot » Tue Aug 07, 2018 12:18 pm

Example code: Urequest has no timeout parameter, I implemented the code below to use poll class

Code: Select all

  response = urequests.get(url=API_ENDPOINT,headers=headers)
  sock = response.raw
  sock.setblocking(True)
  poller = uselect.poll()
  poller.register(sock,uselect.POLLIN)
  events = poller.poll(1000)  # time in milliseconds
  print(events)
  if events:
     if uselect.POLLIN:
        text = sock.read()
        parsed = ujson.loads(text)
        print(parsed)
        response.close()
     else:
        print('POLLIN False'')
  else:            
     print('TIMEOUT  - events False')
          
 poller.unregister(sock)
Problem: Variable events always returns true, poll does not work.

I'm using ESP8266. Would anyone have an example, using poll with urequest that works ??

Thanks

SpotlightKid
Posts: 463
Joined: Wed Apr 08, 2015 5:19 am

Re: Poll class not working - urequest

Post by SpotlightKid » Tue Aug 07, 2018 2:05 pm

Firstly, when you use urequests.get, it calls urequests.request, which already opens a connection, writes to it and reads the response headers. Setting the poll timeout afterwards is too late, if the server is slow in responding, the socket already blocks while reading the headers in urequests.request. You'll need to implement your own HTTP request function if you want to use select/polling all the way.

Secondly, you're using the return value of poller.poll() wrongly, it is a sequence of tuples (stream, event_type). You need to iterate over this list and check for the event type like this:

Code: Select all

    for event in events:
        # 'event[0] is sock' does not work on CPython!
        if event[1] == uselect.POLLIN and event[0] is sock:
            data = event[0].read()
            ...
        elif event[1] in (uselect.POLLHUP, uselect.POLLERR):
            print("Poll error")
            # cleanup...

And should you want to do HTTP requests in an asyncio context, you should probably use uaiohttpclient.

User avatar
MorseIot
Posts: 38
Joined: Fri Jun 29, 2018 12:32 am

Re: Poll class not working - urequest

Post by MorseIot » Tue Aug 07, 2018 7:12 pm

SpotlightKid wrote:
Tue Aug 07, 2018 2:05 pm
Firstly, when you use urequests.get, it calls urequests.request, which already opens a connection, writes to it and reads the response headers. Setting the poll timeout afterwards is too late, if the server is slow in responding, the socket already blocks while reading the headers in urequests.request. You'll need to implement your own HTTP request function if you want to use select/polling all the way.

Secondly, you're using the return value of poller.poll() wrongly, it is a sequence of tuples (stream, event_type). You need to iterate over this list and check for the event type like this:

Code: Select all

    for event in events:
        # 'event[0] is sock' does not work on CPython!
        if event[1] == uselect.POLLIN and event[0] is sock:
            data = event[0].read()
            ...
        elif event[1] in (uselect.POLLHUP, uselect.POLLERR):
            print("Poll error")
            # cleanup...

And should you want to do HTTP requests in an asyncio context, you should probably use uaiohttpclient.
Ok,

There is a commit for adding timeout to the lib urequests, I will modify and test the implementation.

Thanks

Post Reply