daphne icon indicating copy to clipboard operation
daphne copied to clipboard

WIP: add lifespan support (monkay based)

Open devkral opened this issue 5 months ago • 7 comments

Changes:

  • add lifespan support via monkay.asgi
  • Bump minimum python version (near EOL, needs discussion)

devkral avatar Sep 18 '25 13:09 devkral

if needed, I can readd python 3.9 support in monkay

devkral avatar Sep 18 '25 13:09 devkral

No problem with Python 3.10 as a minimum version.

carltongibson avatar Nov 07 '25 13:11 carltongibson

I'm not sure if the lifespan cleanup is going right :(. When using --noreload I do see kill_all_applications being run. But not the actual lifespan code.

mjvankampen avatar Nov 07 '25 13:11 mjvankampen

not sure where the bug results from. I think twisted ignores the return value despite documented

devkral avatar Nov 07 '25 16:11 devkral

I rewrote the code for test purposes:


    def kill_all_applications(self):
        """
        Kills all application coroutines before reactor exit.
        """

        # Make Twisted wait until they're all dead and cleanup lifespan
        async def cleanup():
            # Send cancel to all coroutines
            wait_for = []
            for details in self.connections.values():
                application_instance = details["application_instance"]
                if not application_instance.done():
                    application_instance.cancel()
                    wait_for.append(application_instance)
            logger.info("Killed %i pending application instances", len(wait_for))
            try:
                await asyncio.gather(*wait_for)
            finally:
                if self.lifespan_context:
                    await self.lifespan_context.__aexit__()

        return defer.Deferred.fromFuture(cleanup())

Effect: silence (no info output). Seemingly they ignore the return value

devkral avatar Nov 07 '25 17:11 devkral


    def kill_all_applications(self):
        """
        Kills all application coroutines before reactor exit.
        """

        # Make Twisted wait until they're all dead and cleanup lifespan
        async def cleanup():
            # Send cancel to all coroutines
            wait_for = []
            for details in self.connections.values():
                application_instance = details["application_instance"]
                if not application_instance.done():
                    application_instance.cancel()
                    wait_for.append(application_instance)
            logger.info("Killed %i pending application instances", len(wait_for))
            try:
                await asyncio.gather(*wait_for)
            finally:
                if self.lifespan_context:
                    await self.lifespan_context.__aexit__()

        reactor._asyncioEventloop.run_until_complete(cleanup())

Gives me a resource warning

devkral avatar Nov 07 '25 17:11 devkral

Found a solution. But I doubt that the kill_app code is working.

devkral avatar Nov 08 '25 17:11 devkral