Skip to content

Conversation

@devkral
Copy link

@devkral devkral commented Sep 18, 2025

Changes:

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

Changes:
- add lifespan support via monkay.asgi
- Bump minimum python version (near EOL, needs discussion)
@devkral devkral force-pushed the devkral/feature/lifespan_support branch from 07ab334 to fa811a6 Compare September 18, 2025 13:56
@devkral
Copy link
Author

devkral commented Sep 18, 2025

if needed, I can readd python 3.9 support in monkay

@carltongibson
Copy link
Member

No problem with Python 3.10 as a minimum version.

@mjvankampen
Copy link

mjvankampen commented Nov 7, 2025

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.

@devkral
Copy link
Author

devkral commented Nov 7, 2025

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

@devkral
Copy link
Author

devkral commented Nov 7, 2025

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

devkral commented Nov 7, 2025

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

devkral commented Nov 8, 2025

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

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.

3 participants