File tree Expand file tree Collapse file tree 2 files changed +31
-2
lines changed
Expand file tree Collapse file tree 2 files changed +31
-2
lines changed Original file line number Diff line number Diff line change 3636RedisClient = Annotated [Redis , Depends (get_redis )]
3737TaskFilters = Annotated [TaskListFilters , Depends ()]
3838logger = getLogger (__name__ )
39+ _BACKGROUND_CACHE_INVALIDATION_TASKS : set [asyncio .Task [None ]] = set ()
3940
4041_DUE_DATE_ERROR = HTTPException (
4142 status_code = status .HTTP_400_BAD_REQUEST ,
4243 detail = "Дедлайн не может быть в прошлом" ,
4344)
4445
4546
47+ def _track_background_task (task : asyncio .Task [None ]) -> None :
48+ """Сохраняет strong reference на фоновую задачу до её завершения."""
49+ _BACKGROUND_CACHE_INVALIDATION_TASKS .add (task )
50+ task .add_done_callback (_BACKGROUND_CACHE_INVALIDATION_TASKS .discard )
51+
52+
4653def _schedule_invalidate_user_tasks_cache (redis : Redis , user_id : UUID ) -> None :
4754 """Запускает инвалидацию кэша списка задач в фоне (fire-and-forget).
4855 Исключения в фоновой задаче логируются и не пробрасываются в вызывающий код.
@@ -58,7 +65,7 @@ async def _run() -> None:
5865 exc_info = True ,
5966 )
6067
61- asyncio .create_task (_run ())
68+ _track_background_task ( asyncio .create_task (_run () ))
6269
6370
6471@router .post (
Original file line number Diff line number Diff line change 88
99import pytest
1010
11- from app .routes .tasks import _schedule_invalidate_user_tasks_cache
11+ from app .routes .tasks import (
12+ _BACKGROUND_CACHE_INVALIDATION_TASKS ,
13+ _schedule_invalidate_user_tasks_cache ,
14+ )
1215
1316pytestmark = pytest .mark .asyncio
1417
@@ -28,3 +31,22 @@ async def test_schedule_invalidate_runs_in_background_and_does_not_propagate_exc
2831 await asyncio .sleep (0.05 )
2932
3033 assert "Не удалось инвалидировать кэш задач пользователя" in caplog .text
34+
35+
36+ async def test_schedule_invalidate_keeps_task_reference_until_completion () -> None :
37+ """Фоновая задача хранится в реестре до завершения и затем автоматически удаляется."""
38+ redis = AsyncMock ()
39+ user_id = uuid4 ()
40+
41+ with patch (
42+ "app.routes.tasks.delete_cached_tasks_list_for_user" ,
43+ new_callable = AsyncMock ,
44+ ) as delete_cached_tasks :
45+ _schedule_invalidate_user_tasks_cache (redis , user_id )
46+
47+ assert len (_BACKGROUND_CACHE_INVALIDATION_TASKS ) == 1
48+
49+ await asyncio .sleep (0.05 )
50+
51+ delete_cached_tasks .assert_awaited_once_with (redis , user_id )
52+ assert not _BACKGROUND_CACHE_INVALIDATION_TASKS
You can’t perform that action at this time.
0 commit comments