1
0
Эх сурвалжийг харах

use background_tasks.create over bare asyncio.create_task (#4551)

Should fix #4500 

TL-DR: As in title. Should avoid GC messing up asyncio tasks since hard
reference is kept.

---

Read specifically
https://github.com/zauberzeug/nicegui/issues/4500#issuecomment-2764759116
for the affected line in NiceGUI 2.13.0

Apparently, from articles in
https://github.com/zauberzeug/nicegui/issues/4500#issuecomment-2748363534,
since asyncio does not itself keep a hard reference to the task created
by `asyncio.create_task`, it can easily by GC-ed and cause `Task was
destroyed but it is pending!`

Sitting in front of us (literally, it's 4 lines before the change in
#4466), we just used `background_tasks.create`, which keeps a hard
reference by putting all tasks into `running_tasks`. It has never caused
trouble, or at least if it would, it should have surfaced a long long
time ago (too lazy to git blame, but I bet this function introduced
several versions before NiceGUI 2.13.0)


https://github.com/zauberzeug/nicegui/blob/6ad424126b4d6d11e5b5b069e545783d262d2fef/nicegui/background_tasks.py#L14-L27

---------

Co-authored-by: Falko Schindler <falko@zauberzeug.com>
Evan Chan 1 сар өмнө
parent
commit
479c97781e
1 өөрчлөгдсөн 4 нэмэгдсэн , 1 устгасан
  1. 4 1
      nicegui/page.py

+ 4 - 1
nicegui/page.py

@@ -123,10 +123,13 @@ class page:
                     with client:
                         return await result
                 task = background_tasks.create(wait_for_result())
+                task_wait_for_connection = background_tasks.create(
+                    client._waiting_for_connection.wait(),  # pylint: disable=protected-access
+                )
                 try:
                     await asyncio.wait([
                         task,
-                        asyncio.create_task(client._waiting_for_connection.wait()),  # pylint: disable=protected-access
+                        task_wait_for_connection,
                     ], timeout=self.response_timeout, return_when=asyncio.FIRST_COMPLETED)
                 except asyncio.TimeoutError as e:
                     raise TimeoutError(f'Response not ready after {self.response_timeout} seconds') from e