You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was wondering if it is possible to map async coroutines in the dispatcher. I run the AsyncIOOSCUDPServer to integrate python-osc in my asyncio driven service, but if I map an async coroutine in the dispatcher I get something like "coroutine was never awaited" during runtime.
As a workaround I use wrappers like:
asyncdefasyncExample(param):
print(param)
defexampleWrapper(address, *args):
evloop.create_task(asyncExample(args[0]))
dispatcher=Dispatcher()
dispatcher.map("/osc/exampleWrapper", exampleWrapper)
asyncdefloop():
whileTrue:
print("loop")
awaitasyncio.sleep(1)
asyncdefasync_main():
server=AsyncIOOSCUDPServer(("0.0.0.0", 1234), dispatcher, asyncio.get_event_loop())
transport, protocol=awaitserver.create_serve_endpoint() # Create datagram endpoint and start servingawaitloop() # Enter main loop of programtransport.close() # Clean up serve endpointif__name__=="__main__":
evloop=asyncio.get_event_loop();
evloop.run_until_complete(async_main())
Is this the way to go or a horrible example of bad code? Is async support planned for the dispatcher?
Hi, ideally with proper async support you shouldn't have to call asyncio.sleep ever so I'd not recommend this code in production.
Having some kind of AsyncDispatcher would be nice, I haven't used the async lib enough myself to know if one can recognize whether an async function was passed to the dispatcher (in which case we could bundle the wait call in it).
PRs are welcome if you find a cleaner version that doesn't involve hardcoded sleep calls :)
You're right - I couldn't find a straightforward way to call Dispatcher.async_call_handlers_for_packet() because it needs to be awaited and the protocol handler only defines a synchronous method for datagram_received. It may be possible to call the async handler using loop.call_soon() and then send the responses. I'll try to find some time to take a look at it.
I guess the appropriate course would be to change or even rewrite a lot of the current UDP handling code, to have an async pathway there too. But on a quick glance this looks like quite a chunk of work.
Activity
attwad commentedon Jun 12, 2020
Hi, ideally with proper async support you shouldn't have to call
asyncio.sleepever so I'd not recommend this code in production.Having some kind of
AsyncDispatcherwould be nice, I haven't used the async lib enough myself to know if one can recognize whether an async function was passed to the dispatcher (in which case we could bundle thewaitcall in it).PRs are welcome if you find a cleaner version that doesn't involve hardcoded sleep calls :)
bobh66 commentedon Aug 17, 2024
@pogojotz the changes merged in #173 released in 1.9.0 support async handlers that can return responses over the same socket.
pogojotz commentedon Sep 5, 2024
But what about UDP handlers? The change affects only TCP as far as I can see.
bobh66 commentedon Sep 5, 2024
You're right - I couldn't find a straightforward way to call
Dispatcher.async_call_handlers_for_packet()because it needs to be awaited and the protocol handler only defines a synchronous method fordatagram_received. It may be possible to call the async handler usingloop.call_soon()and then send the responses. I'll try to find some time to take a look at it.pogojotz commentedon Sep 5, 2024
I guess the appropriate course would be to change or even rewrite a lot of the current UDP handling code, to have an async pathway there too. But on a quick glance this looks like quite a chunk of work.