oscpy
oscpy copied to clipboard
Experimental async support (asyncio/trio/curio)
Supports Curio, Trio and asyncio.
Sorry for hijacking this PR; I was wondering whether there are plans to add support for Trio and asyncio
in the near future, preferably by using anyio
as an abstraction layer on top of them. I am surveying Python implementations of OSC clients as I need to add OSC support to a larger application that is already committed to using Trio as the main event loop. If there are no plans to support Trio in the near future on your own, would you accept a PR for a Trio-based OSC client class?
(Sadly enough, anyio
would have been great to add support for Trio, asyncio
and curio
at the same time until the author of curio
requested removing support for curio
in anyio
at version 3.0 so it looks like Curio needs to be handled separately).
Trio has been added after i opened the PR, (as you can see in the server/trio_server.py and examples/trio_example.py files, about pure asyncio, i started something but it doesn’t work yet.
edit: i had seen about anyio and considered maybe using it indeed (for now wanted to see how hard it was doing without), but if it doesn’t handle curio it’s less interesting.
re-edit: also very interested in your feedback, i don’t have that much experience with asyncio/trio/curio, so if i’m pushing antipatterns, better know it sooner rather than later :).
Oh, great, so there's a working Trio server already. Thanks, I haven't noticed that!
I took a quick look at the code now. I'm not familiar with Curio so I can't comment on that part. As for Trio, the current implementation seems to run all message handlers in a separate task in a nursery, which is probably overkill for small synchronous handlers. I would create a memory channel with open_memory_channel
and spawn two tasks in the nursery: one that reads the socket in a loop and puts whatever it has received into the TX end of the memory channel, and another task that reads the RX end of the memory channel and calls the handler immediately, synchronously. The handler could then receive nursery.start_soon
as an additional argument and it could spawn a new async task into the nursery if it is necessary (i.e. if the handler is expected to take a long time or if it is going to perform blocking I/O).