sanic-org / sanic

Accelerate your web app development | Build fast. Run fast.

Home Page:https://sanic.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow the signal router to finalize without a running event loop

eelkevdbos opened this issue · comments

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe.

I am running some tasks by awaiting the Sanic.run_delayed_task interface. All is well, except for the fact that I cannot dispatch signals.

The error raised when dispatching a signal is TypeError: 'NoneType' object is not callable and originates from a non-finalized signal router.

The signal router cannot be finalized without a running event loop.

Describe the solution you'd like

Add a loop keyword argument to the signal router's finalize method.

def finalize(self, do_compile: bool = True, do_optimize: bool = False, loop: asyncio.AbstractEventLoop = None):
    self.add(_blank, "sanic.__signal__.__init__")

    try:
        self.ctx.loop = loop or asyncio.get_running_loop()
    except RuntimeError:
        raise RuntimeError("Cannot finalize signals outside of event loop")

    for signal in self.routes:
        signal.ctx.event = asyncio.Event()

    return super().finalize(do_compile=do_compile, do_optimize=do_optimize)

This will allow me to inject a loop instance into the finalize method, circumventing the runtime error caused by asyncio.get_running_loop() in the absence of a running loop.

Additional context

No response