From 4c5f14d3d95387d7e90de8f6ec097194b0a042a4 Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Sep 25 2017 16:54:37 +0000 Subject: Fix caching to be testable. The old way didn't work because our ``cache`` object was global. It would get configured by the first test and then never be reconfigurable for other tests. This gets fixed here by hanging the cache region on `flask.current_app` so that it gets reinstantiated and reconfigured for each test run (and each WSGI process). --- diff --git a/greenwave/app_factory.py b/greenwave/app_factory.py index cb86e47..44b53a4 100644 --- a/greenwave/app_factory.py +++ b/greenwave/app_factory.py @@ -4,9 +4,9 @@ from flask import Flask from greenwave.logger import init_logging from greenwave.api_v1 import api -from greenwave.cache import cache from greenwave.utils import json_error, load_config +from dogpile.cache import make_region from requests import ConnectionError, Timeout from werkzeug.exceptions import default_exceptions @@ -32,8 +32,8 @@ def create_app(config_obj=None): app.add_url_rule('/healthcheck', view_func=healthcheck) # Initialize the cache. - if not cache.is_configured: - cache.configure(**app.config['CACHE']) + app.cache = make_region() + app.cache.configure(**app.config['CACHE']) return app diff --git a/greenwave/cache.py b/greenwave/cache.py index 27fb3b6..00bcf50 100644 --- a/greenwave/cache.py +++ b/greenwave/cache.py @@ -1,9 +1,19 @@ # SPDX-License-Identifier: GPL-2.0+ import dogpile.cache - -# Our globally available cache region. Gets initialized in app_factory. -cache = dogpile.cache.make_region() +import flask # Provide a convenient alias for the key generator we want to use key_generator = dogpile.cache.util.function_key_generator + + +def cached(fn): + """ Cache arguments with a region hung on the flask app. """ + def wrapper(*args): + decoration = flask.current_app.cache.cache_on_arguments + decorator = decoration(function_key_generator=key_generator) + return decorator(fn)(*args) + wrapper.__name__ = fn.__name__ + wrapper.__module__ = fn.__module__ + wrapper.__doc__ = fn.__doc__ + return wrapper diff --git a/greenwave/resources.py b/greenwave/resources.py index 2a95f2f..11335f0 100644 --- a/greenwave/resources.py +++ b/greenwave/resources.py @@ -9,12 +9,12 @@ waiverdb, etc..). import requests from flask import current_app -from greenwave.cache import cache, key_generator +from greenwave.cache import cached requests_session = requests.Session() -@cache.cache_on_arguments(function_key_generator=key_generator) +@cached def retrieve_results(item): """ Retrieve cached results from resultsdb for a given item. """ # XXX make this more efficient than just fetching everything