uasyncio: feature request: multiple event loops
I think this needs to go here and not in the micropython-libs repo...
A project I'm working on has two main contexts code can run in. Previously I had modeled those two contexts as two different event loops, with an explicit hand-off between them.
One loop was the "motion control" event loop. It was a higher priority and there were only specific spots it would be able to stop at safely. I could turn it into a blocking function (with the help of interrupts to handle some edge cases) but there are reasons why it's better for it to be co-operative multi-tasking based. The idea was that it would call motionLoop.stop() at regular intervals to allow the general loop to run.
The other loop was the general purpose loop which would run things like user plugins, a web interface, GC, etc.
Any thoughts?
uasyncio event loop is incompatible with lowlevel scheduler (MICROPY_ENABLE_SCHEDULER)
I am rather baffled by learning that are two disparate event scheduling mechanisms in MicroPython:
- An "invisible" scheduler that "just works" with events posted with mp_sched_schedule(). This includes (in the esp32 port at least) pin interrupts, hires timers, lwip sockets and the main uart. The eventloop for this is driven from the REPL via readline() and the MICROPY_EVENT_POLL_HOOK which ports apparently are required to call regularly. For esp32, this happens in a tight loop inside mp_hal_stdin_rx_chr()
- An explicit event loop in the uasyncio module This is a Python implementation in extmod/uasyncio/core.py where the main handler is run_until_complete() As the name implies, this does not have a "single pass" routine poll hook variant, but will run synchronously in a while loop.
The above makes it (from the outset) impossible to integrate the two mechanisms.
I propose a "single pass poll" entry into the uasyncio logic. Preferably callable from C so that the two can be integrated at low level at each ports discretion. Unfortunately my (current) knowledge of micropython internals does not allow for me to do this.
Is this feasible? Am I missing something?
EDIT: I see now that MICROPY_EVENT_POLL_HOOK is called from poll_poll_internal() so the two are in fact integrated.
I still think it would be nice with a "single pass" inner part of the uasyncio event loop. That would allow for a port (esp32) to arrange for (via MICROPY_EVENT_POLL_HOOK) a return when there is UART input, and thus for integration with the REPL.