When an asynchronous generator is about to be garbage collected,
    it calls its cached finalizer.  The assumption is that the finalizer
    will schedule an ``aclose()`` call with the loop that was active
    when the iteration started.

    For instance, here is how asyncio can be modified to allow
    safe finalization of asynchronous generators::

        # asyncio/base_events.py

        class BaseEventLoop:

            def run_forever(self):
                ...
                old_finalizer = sys.get_asyncgen_finalizer()
                sys.set_asyncgen_finalizer(self._finalize_asyncgen)
                try:
                    ...
                finally:
                    sys.set_asyncgen_finalizer(old_finalizer)
                    ...

            def _finalize_asyncgen(self, gen):
                self.create_task(gen.aclose())

    ``sys.set_asyncgen_finalizer`` is thread-specific, so several event
    loops running in parallel threads can use it safely.

When asynchronous generator is about to be garbage collected event loop starts task to execute aclose, right? Can't such situation happen when this task is not finished at the moment event loop is closed? Something like:

   async def gen():
        try:
            yield 1
            yield 2
            yield 3
        except GeneratorExit as exc:
            await asyncio.sleep(100)
            raise exc


   async def main():
        async for i in gen():
            if i == 1:
                break

        # main() and event loop is about to finish here,
        # while task to aclose will last much longer.


   if __name__ == "__main__":
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())

_______________________________________________
Async-sig mailing list
Async-sig@python.org
https://mail.python.org/mailman/listinfo/async-sig
Code of Conduct: https://www.python.org/psf/codeofconduct/

Reply via email to