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

Dispatcher for async coroutines #118

Open
pogojotz opened this issue Jun 10, 2020 · 5 comments
Open

Dispatcher for async coroutines #118

pogojotz opened this issue Jun 10, 2020 · 5 comments

Comments

@pogojotz
Copy link

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:

async def asyncExample(param):
    print(param)

def exampleWrapper(address, *args):
    evloop.create_task(asyncExample(args[0]))

dispatcher = Dispatcher()
dispatcher.map("/osc/exampleWrapper", exampleWrapper)

async def loop():
    while True:
        print("loop")
        await asyncio.sleep(1)

async def async_main():
    server = AsyncIOOSCUDPServer(("0.0.0.0", 1234), dispatcher, asyncio.get_event_loop())
    transport, protocol = await server.create_serve_endpoint()  # Create datagram endpoint and start serving

    await loop()  # Enter main loop of program
    transport.close()  # Clean up serve endpoint

if __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?

Thank you.

@attwad
Copy link
Owner

attwad commented Jun 12, 2020

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

@bobh66
Copy link
Contributor

bobh66 commented 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
Copy link
Author

pogojotz commented Sep 5, 2024

But what about UDP handlers? The change affects only TCP as far as I can see.

@bobh66
Copy link
Contributor

bobh66 commented 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 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.

@pogojotz
Copy link
Author

pogojotz commented 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.

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

No branches or pull requests

3 participants