diff --git a/app/api/endpoints/subscribe.py b/app/api/endpoints/subscribe.py index 783f31a04..724cbe613 100644 --- a/app/api/endpoints/subscribe.py +++ b/app/api/endpoints/subscribe.py @@ -746,10 +746,10 @@ async def user_subscribes( summary="订阅相关文件信息", response_model=_SchemaSubscrbieInfo, ) -def subscribe_files( +async def subscribe_files( subscribe_id: int, repository: SubscriptionQueryPort = Depends(get_subscription_repository), - current_user: ApiPrincipal = Depends(get_current_active_user), + current_user: ApiPrincipal = Depends(get_current_active_user_async), ) -> Any: """ 订阅相关文件信息 @@ -758,9 +758,12 @@ def subscribe_files( name=current_user.name, is_superuser=current_user.is_superuser, ) - subscribe = repository.get(subscribe_id) + subscribe = await repository.async_get(subscribe_id) if subscribe is not None and SubscriptionMutationService.can_access(subscribe, actor): - return SubscribeChain().subscribe_files_info(subscribe) + return await run_in_threadpool( + SubscribeChain().subscribe_files_info, + subscribe, + ) return _SchemaSubscrbieInfo() diff --git a/tests/test_subscribe_endpoint.py b/tests/test_subscribe_endpoint.py index aecd7e1b0..89e8a1d4b 100644 --- a/tests/test_subscribe_endpoint.py +++ b/tests/test_subscribe_endpoint.py @@ -678,15 +678,48 @@ class TestSubscribeEndpoint: repository = _SubscriptionRepositoryFake(other) with patch("app.api.endpoints.subscribe.SubscribeChain") as subscribe_chain: - result = subscribe_files( - subscribe_id=19, - repository=repository, - current_user=_EndpointUser(name="alice", is_superuser=False), + result = asyncio.run( + subscribe_files( + subscribe_id=19, + repository=repository, + current_user=_EndpointUser(name="alice", is_superuser=False), + ) ) assert result.episodes == {} + repository.async_get.assert_awaited_once_with(19) subscribe_chain.return_value.subscribe_files_info.assert_not_called() + def test_subscribe_files_uses_async_query_and_offloads_file_statistics(self): + """文件统计先异步读取稳定快照,再在线程池执行同步媒体查询。""" + from app.api.endpoints.subscribe import subscribe_files + + own = _EndpointSubscribe(id=21, username="alice", name="自己的订阅") + repository = _SubscriptionRepositoryFake(own) + expected = SimpleNamespace(episodes={1: SimpleNamespace()}) + + with ( + patch("app.api.endpoints.subscribe.SubscribeChain") as subscribe_chain, + patch( + "app.api.endpoints.subscribe.run_in_threadpool", + new=AsyncMock(return_value=expected), + ) as run_worker, + ): + result = asyncio.run( + subscribe_files( + subscribe_id=21, + repository=repository, + current_user=_EndpointUser(name="alice", is_superuser=False), + ) + ) + + assert result is expected + repository.async_get.assert_awaited_once_with(21) + run_worker.assert_awaited_once_with( + subscribe_chain.return_value.subscribe_files_info, + own, + ) + def test_user_subscribes_hides_other_user_list(self): """ 普通用户不能通过 username 参数读取其他用户订阅列表。