Skip to content
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

asyncio bugfixes, select bugfixes & selectable socket #7173

Merged
merged 3 commits into from
Nov 7, 2022

Conversation

jepler
Copy link
Member

@jepler jepler commented Nov 5, 2022

  1. The internal definition of ticks in moduasyncio was still wrong, in a way that deceptively seemed to work sometimes
  2. select() was not interruptable with ctrl-c
  3. socket objects are now selectable -- implementation tested on rp2040 only at this point -- needs further changes in asyncio module itself

Here's my test program, which connects to a netcat -l 5153 already running on my laptop bert. When I type something into netcat and hit enter, it's received and echoed back, with extra running commentary in the repl. also, the led toggles with each print.

@furbrain pinging in case you are interested in this

import os
import asyncio

import board
import digitalio
import socketpool
import wifi

if wifi.radio.ipv4_address is None:
    ssid = os.getenv('CIRCUITPY_WIFI_SSID')
    print("Connecting to", ssid)
    wifi.radio.connect(ssid, os.getenv('CIRCUITPY_WIFI_PASSWORD'))
    print("Connected to", ssid)
else:
    print("already connected")
print("Local address", wifi.radio.ipv4_address)

pool = socketpool.SocketPool(wifi.radio)


class Socket:
    def __init__(self, s):
        self.s = s
        s.setblocking(False)

    async def recv_into(self, buf):
        await asyncio.core._io_queue.queue_read(self.s)
        return self.s.recv_into(buf)

    async def send(self, buf):
        await asyncio.core._io_queue.queue_write(self.s)
        return self.s.send(buf)

async def sock_task(sock):
    print("in sock task")
    with digitalio.DigitalInOut(board.LED) as led:
        led.switch_to_output(False)
        s = Socket(sock)
        buf = bytearray(16)
        while True:
            led.value = not led.value
            print("going to await recv")
            sz = await s.recv_into(buf)
            print(sz, bytes(buf[:sz]))
            print("going to await send")
            sz = await(s.send(buf[:sz]))
            print("sent", sz)

with pool.socket(pool.AF_INET, pool.SOCK_STREAM) as sock:
    print("connecting")
    sock.connect(("bert.u", 5123))
    print("running task")
    asyncio.run(sock_task(sock))

supervisor_ticks_ms is ALREADY a small int, so passing it to
MP_OBJ_SMALL_INT again messes things up. I don't know why this passed
muster with the C type system, but oh well.
.. which will lead to them being usable in async contexts, pending
relevant changes in asyncio
Copy link
Collaborator

@dhalbert dhalbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not tested. This looks good and I checked the ticks() stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants