Skip to content

Add an async manager #129

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add an async manager #129

wants to merge 1 commit into from

Conversation

liujordan
Copy link

@liujordan liujordan commented Feb 15, 2025

Description of the Change

This is a full copy of the JSONRPCResponseManager but with an async handle method for async dispatchers

full sample usage of this with a Tornado server that has a die action that kills the process after a short delay

async def delay(coro, seconds):
    await asyncio.sleep(seconds)
    await coro

class MainHandler(tornado.web.RequestHandler):
    dispatcher = None

    def initialize(self, dispatcher):
        self.dispatcher = dispatcher

    async def post(self):
        response = await JSONRPCResponseManagerAsync.handle(self.request.body, self.dispatcher)
        self.write(response.result)


class Server:
    def __init__(self, dispatcher: Dispatcher = None):
        if dispatcher is None:
            dispatcher = Dispatcher()
        self.dispatcher = dispatcher
        self.dispatcher.add_method(self.die)

    async def die(self, **kwargs):
        async def coro():
            sys.exit(0)
        asyncio.create_task(delay(coro(), 10))
        return {"response": "success"}

    def make_app(self):
        return tornado.web.Application([
            (r"/jsonrpc", MainHandler, dict(dispatcher=self.dispatcher)),
        ])

    async def start_server_task(self, **kwargs):
        app = self.make_app()
        app.listen(8888)
        await asyncio.Event().wait()

async def async_main():
    thing_server = Server()
    threads = [
        asyncio.create_task(thing_server.start_server_task()),
    ]
    await asyncio.gather(*threads)


def main(*args, **kwargs):
    try:
        loop = asyncio.get_running_loop()
    except RuntimeError:
        loop = asyncio.new_event_loop()

    try:
        loop.run_until_complete(async_main())
    except KeyboardInterrupt:
        pass

    loop.close()


if __name__ == "__main__":
    main()

Alternate Designs

Benefits

ability to dispatch with async handlers

Possible Drawbacks

This is a copy & paste of the existing manager.py and test_manager.py, any change needs to the manger will need to be made in both places. Some refactoring is recommended in the next PR

#116 mentions theres an ajson-rpc fork and this is meant to support older versions but i do not see the reason why this package can't just bump the major version and cut support for older python versions

Applicable Issues

#116

@liujordan liujordan changed the title ADD: async manager Add an async manager Feb 15, 2025
@liujordan liujordan marked this pull request as ready for review February 15, 2025 23:47
@pavlov99
Copy link
Owner

Hi @liujordan thank you for the PR! Would https://github.com/pavlov99/ajsonrpc work for your case?

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

Successfully merging this pull request may close these issues.

2 participants