diff --git a/services/catalog/src/simcore_service_catalog/api/routes/services.py b/services/catalog/src/simcore_service_catalog/api/routes/services.py index 11439a8dd4cc..2d385347ffc4 100644 --- a/services/catalog/src/simcore_service_catalog/api/routes/services.py +++ b/services/catalog/src/simcore_service_catalog/api/routes/services.py @@ -4,7 +4,6 @@ import logging import urllib.parse from collections import deque -from functools import lru_cache from typing import Any, Deque, Dict, List, Optional, Set, Tuple from aiocache import cached @@ -40,6 +39,7 @@ } DIRECTOR_CACHING_TTL = 5 * MINUTE +LIST_SERVICES_CACHING_TTL = 30 def _prepare_service_details( @@ -70,20 +70,19 @@ def _prepare_service_details( return validated_service -def async_lru_cache(*lru_cache_args, **lru_cache_kwargs): - def async_lru_cache_decorator(async_function): - @lru_cache(*lru_cache_args, **lru_cache_kwargs) - def cached_async_function(*args, **kwargs): - coroutine = async_function(*args, **kwargs) - return asyncio.ensure_future(coroutine) - - return cached_async_function - - return async_lru_cache_decorator +def _build_cache_key(fct, *args, **kwargs): + return f"{fct.__name__}_{kwargs['user_id']}_{kwargs['x_simcore_products_name']}_{kwargs['details']}" +# NOTE: this call is pretty expensive and can be called several times +# (when e2e runs or by the webserver when listing projects) therefore +# a cache is setup here @router.get("", response_model=List[ServiceOut], **RESPONSE_MODEL_POLICY) @cancellable_request +@cached( + ttl=LIST_SERVICES_CACHING_TTL, + key_builder=_build_cache_key, +) async def list_services( request: Request, # pylint:disable=unused-argument user_id: PositiveInt,