oscpy icon indicating copy to clipboard operation
oscpy copied to clipboard

Experimental async support (asyncio/trio/curio)

Open tshirtman opened this issue 3 years ago • 3 comments

Supports Curio, Trio and asyncio.

tshirtman avatar Jun 26 '21 00:06 tshirtman

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).

ntamas avatar Jun 30 '21 09:06 ntamas

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 :).

tshirtman avatar Jun 30 '21 10:06 tshirtman

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).

ntamas avatar Jun 30 '21 13:06 ntamas