asyncio: hold our own strong refs for tasks and futures
see https://docs.python.org/3.13/library/asyncio-task.html#asyncio.create_task : > Important > > Save a reference to the result of this function, to avoid a task > disappearing mid-execution. The event loop only keeps weak references > to tasks. A task that isn’t referenced elsewhere may get garbage > collected at any time, even before it’s done. For reliable > “fire-and-forget” background tasks, gather them in a collection ref https://github.com/python/cpython/issues/91887 ref https://github.com/beeware/toga/pull/2814
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
|
||||
@@ -472,3 +473,30 @@ class TestUtil(ElectrumTestCase):
|
||||
self.assertTrue(ShortID.from_components(3, 30, 300) > ShortID.from_components(3, 1, 999))
|
||||
self.assertTrue(ShortID.from_components(3, 30, 300) < ShortID.from_components(3, 999, 1))
|
||||
|
||||
async def test_custom_task_factory(self):
|
||||
loop = util.get_running_loop()
|
||||
# set our factory. note: this does not leak into other unit tests
|
||||
util._set_custom_task_factory(loop)
|
||||
|
||||
evt = asyncio.Event()
|
||||
async def foo():
|
||||
await evt.wait()
|
||||
|
||||
fut = asyncio.ensure_future(foo())
|
||||
self.assertTrue(fut in util._running_asyncio_tasks)
|
||||
fut = asyncio.create_task(foo())
|
||||
self.assertTrue(fut in util._running_asyncio_tasks)
|
||||
fut = loop.create_task(foo())
|
||||
self.assertTrue(fut in util._running_asyncio_tasks)
|
||||
#fut = asyncio.run_coroutine_threadsafe(foobar(), loop=loop)
|
||||
#self.assertTrue(fut in util._running_asyncio_tasks)
|
||||
|
||||
# we should have stored one ref for each above.
|
||||
# (though what if test framework is doing stuff ~concurrently?)
|
||||
self.assertEqual(3, len(util._running_asyncio_tasks))
|
||||
evt.set()
|
||||
for _ in range(10): # wait a few event loop iterations
|
||||
await asyncio.sleep(0)
|
||||
# refs should be cleaned up by now:
|
||||
self.assertEqual(0, len(util._running_asyncio_tasks))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user