From 58b211577f413a51ef0ddaf2f7d59d8bbc20ad01 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Thu, 6 Jun 2019 16:49:49 +0200 Subject: [PATCH] Implement proper caching closing --- retribute_api/cache.py | 8 ++++++++ retribute_api/search/consumers.py | 25 ++++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/retribute_api/cache.py b/retribute_api/cache.py index 1853eac..a8d2a2d 100644 --- a/retribute_api/cache.py +++ b/retribute_api/cache.py @@ -15,6 +15,9 @@ class Backend: async def set(self, key): raise NotImplementedError + async def close(self): + return + class Dummy(Backend): def __init__(self): @@ -59,6 +62,11 @@ class Redis(Backend): r = await self.redis() await r.set(key, json.dumps(value)) + async def close(self): + if not self._redis: + return + await self._redis.close() + def get_default(): return Redis(settings.ASYNC_REDIS_PARAMS) diff --git a/retribute_api/search/consumers.py b/retribute_api/search/consumers.py index c7d05c3..ba996f0 100644 --- a/retribute_api/search/consumers.py +++ b/retribute_api/search/consumers.py @@ -36,6 +36,18 @@ def wrapper_500(callback): return callback +def with_cache(f): + async def inner(*args, **kwargs): + c = kwargs.setdefault("cache", cache.get_default()) + try: + return await f(*args, **kwargs) + except Exception: + await c.close() + raise + + return inner + + def ignore_aiohttp_ssl_eror(loop, aiohttpversion="3.5.4"): """Ignore aiohttp #3535 issue with SSL data after close @@ -84,7 +96,8 @@ def ignore_aiohttp_ssl_eror(loop, aiohttpversion="3.5.4"): class SearchSingleConsumer(AsyncHttpConsumer): @wrapper_500 - async def handle(self, body): + @with_cache + async def handle(self, body, cache): lookup_type = self.scope["url_route"]["kwargs"]["lookup_type"] lookup = self.scope["url_route"]["kwargs"]["lookup"] ignore_aiohttp_ssl_eror(asyncio.get_running_loop()) @@ -94,7 +107,7 @@ class SearchSingleConsumer(AsyncHttpConsumer): await json_response(self, 400, {"detail": "Invalid lookup"}) try: async with aiohttp.client.ClientSession(timeout=aiohttp_timeout) as session: - data = await source.get(lookup, session, cache=cache.get_default()) + data = await source.get(lookup, session, cache=cache) profile = sources.result_to_retribute_profile(lookup_type, lookup, data) except (exceptions.SearchError, aiohttp.ClientError) as e: await json_response(self, 400, {"detail": e.message}) @@ -105,9 +118,9 @@ class SearchSingleConsumer(AsyncHttpConsumer): await json_response(self, 200, profile) -async def do_lookup(lookup, lookup_type, session, source, results): +async def do_lookup(lookup, lookup_type, session, source, results, cache): try: - data = await source.get(lookup, session, cache=cache.get_default()) + data = await source.get(lookup, session, cache=cache) profile = sources.result_to_retribute_profile(lookup_type, lookup, data) except ( exceptions.SearchError, @@ -126,7 +139,8 @@ async def do_lookup(lookup, lookup_type, session, source, results): class SearchMultipleConsumer(AsyncHttpConsumer): @wrapper_500 - async def handle(self, body): + @with_cache + async def handle(self, body, cache): if self.scope["method"] == "OPTIONS": return await self.send_response( 200, @@ -167,6 +181,7 @@ class SearchMultipleConsumer(AsyncHttpConsumer): session=session, source=source, results=results, + cache=cache, ) ) try: -- GitLab