pallets / quart

An async Python micro framework for building web applications.
https://quart.palletsprojects.com
MIT License
3.01k stars 164 forks source link

Background tasks can disappear mid-execution #339

Closed jakubsvehla closed 6 months ago

jakubsvehla commented 6 months ago

According to the asyncio documentation, it is necessary to keep a strong reference to a task to avoid it disappearing mid-execution because the event loop only keeps weak references to tasks. However, Quart uses a WeakSet to store the tasks which means that they can potentially be garbage collected before they finish. And users cannot keep their own strong references because the task is not returned.

The solution would be to use normal set instead of the WeakSet to keep the tasks in the background_tasks app instance variable and add task.add_done_callback(self.background_tasks.discard) to the add_background_task method after the task is created.

I tried to reproduce the bug but wasn't able to. I found several discussions where others are also not able to reproduce this behavior but nevertheless it's still recommended (both in the official docs and in the discussions) to keep the strong references (and use a callback to remove it) because it can happen in some cases that the task disappears before finishing.

Here are some discussions related to that:

I can also create a merge request for it but I won't be able to create a failing test for it since I wasn't able to reproduce it.

Environment:

pgjones commented 6 months ago

Thanks, fixed in 425f685d213f8c3d464d1ce4e347ccf36e609330 and released in 0.19.6