Skip to content

Commit b43604e

Browse files
committed
Add tasks to set to prevent garbage collection
1 parent bbe906b commit b43604e

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

src/reactpy_django/hooks.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def use_query(
126126
loading, set_loading = use_state(True)
127127
error, set_error = use_state(cast(Union[Exception, None], None))
128128
query_ref = use_ref(query)
129+
async_task_refs = use_ref(set())
129130
kwargs = kwargs or {}
130131
postprocessor_kwargs = postprocessor_kwargs or {}
131132

@@ -174,7 +175,11 @@ def schedule_query() -> None:
174175
set_should_execute(False)
175176

176177
# Execute the query in the background
177-
asyncio.create_task(execute_query())
178+
task = asyncio.create_task(execute_query())
179+
180+
# Add the task to a set to prevent it from being garbage collected
181+
async_task_refs.current.add(task)
182+
task.add_done_callback(async_task_refs.current.remove)
178183

179184
@use_callback
180185
def refetch() -> None:
@@ -229,6 +234,7 @@ def use_mutation(
229234

230235
loading, set_loading = use_state(False)
231236
error, set_error = use_state(cast(Union[Exception, None], None))
237+
async_task_refs = use_ref(set())
232238

233239
# The main "running" function for `use_mutation`
234240
async def execute_mutation(exec_args, exec_kwargs) -> None:
@@ -268,7 +274,11 @@ def schedule_mutation(*exec_args: FuncParams.args, **exec_kwargs: FuncParams.kwa
268274
set_loading(True)
269275

270276
# Execute the mutation in the background
271-
asyncio.ensure_future(execute_mutation(exec_args=exec_args, exec_kwargs=exec_kwargs))
277+
task = asyncio.ensure_future(execute_mutation(exec_args=exec_args, exec_kwargs=exec_kwargs))
278+
279+
# Add the task to a set to prevent it from being garbage collected
280+
async_task_refs.current.add(task)
281+
task.add_done_callback(async_task_refs.current.remove)
272282

273283
# Used when the user has told us to reset this mutation
274284
@use_callback

src/reactpy_django/pyscript/layout_handler.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class ReactPyLayoutHandler:
2020

2121
def __init__(self, uuid):
2222
self.uuid = uuid
23+
self.running_tasks = set()
2324

2425
@staticmethod
2526
def update_model(update, root_model):
@@ -74,14 +75,17 @@ def build_element_tree(self, layout, parent, model):
7475
msg = f"Unknown model type: {type(model)}"
7576
raise TypeError(msg)
7677

77-
@staticmethod
78-
def create_event_handler(layout, element, event_name, event_handler_model):
78+
def create_event_handler(self, layout, element, event_name, event_handler_model):
7979
"""Create an event handler for an element. This function is used as an
8080
adapter between ReactPy and browser events."""
8181
target = event_handler_model["target"]
8282

8383
def event_handler(*args):
84-
asyncio.create_task(layout.deliver({"type": "layout-event", "target": target, "data": args}))
84+
task = asyncio.create_task(layout.deliver({"type": "layout-event", "target": target, "data": args}))
85+
86+
# Add the task to a set to prevent it from being garbage collected
87+
self.running_tasks.add(task)
88+
task.add_done_callback(self.running_tasks.remove)
8589

8690
event_name = event_name.lstrip("on_").lower().replace("_", "")
8791
add_event_listener(element, event_name, event_handler)

0 commit comments

Comments
 (0)