summaryrefslogtreecommitdiff
path: root/requests_cache/session.py
diff options
context:
space:
mode:
authorJordan Cook <jordan.cook@pioneer.com>2022-04-22 20:10:57 -0500
committerJordan Cook <jordan.cook@pioneer.com>2022-05-04 16:17:22 -0500
commitbbd984375d22dedaf33c8d0cad718cc09d072d25 (patch)
tree37eb6cfad188feefcd18dff05de9e591c7dff1aa /requests_cache/session.py
parent3aa84ee6724491858a81ce401487fc85d0ee9c9d (diff)
downloadrequests-cache-bbd984375d22dedaf33c8d0cad718cc09d072d25.tar.gz
Implement Cache-Control: stale-while-revalidate
Diffstat (limited to 'requests_cache/session.py')
-rw-r--r--requests_cache/session.py19
1 files changed, 15 insertions, 4 deletions
diff --git a/requests_cache/session.py b/requests_cache/session.py
index 7be3f94..f6a19dd 100644
--- a/requests_cache/session.py
+++ b/requests_cache/session.py
@@ -1,7 +1,7 @@
"""Main classes to add caching features to :py:class:`requests.Session`"""
from contextlib import contextmanager, nullcontext
from logging import getLogger
-from threading import RLock
+from threading import RLock, Thread
from typing import TYPE_CHECKING, Iterable, MutableMapping, Optional, Union
from requests import PreparedRequest
@@ -197,10 +197,13 @@ class CacheMixin(MIXIN_BASE):
# Handle missing and expired responses based on settings and headers
if actions.error_504:
response: AnyResponse = get_504_response(request)
- elif actions.send_request:
- response = self._send_and_cache(request, actions, cached_response, **kwargs)
+ elif actions.resend_async:
+ self._resend_async(request, actions, cached_response, **kwargs)
+ response = cached_response # type: ignore
elif actions.resend_request:
response = self._resend(request, actions, cached_response, **kwargs) # type: ignore
+ elif actions.send_request:
+ response = self._send_and_cache(request, actions, cached_response, **kwargs)
else:
response = cached_response # type: ignore # Guaranteed to be non-None by this point
@@ -256,6 +259,12 @@ class CacheMixin(MIXIN_BASE):
except Exception:
return self._handle_error(cached_response, actions)
+ def _resend_async(self, *args, **kwargs):
+ """Send a non-blocking request to refresh a cached response"""
+ logger.debug('Using stale response while revalidating')
+ thread = Thread(target=self._send_and_cache, args=args, kwargs=kwargs)
+ thread.start()
+
def _handle_error(self, cached_response: CachedResponse, actions: CacheActions) -> AnyResponse:
"""Handle a request error based on settings:
* Default behavior: re-raise the error
@@ -338,8 +347,10 @@ class CachedSession(CacheMixin, OriginalSession):
a list of specific headers to match
ignored_parameters: Request paramters, headers, and/or JSON body params to exclude from both
request matching and cached request data
- stale_if_error: Return stale cache data if a new request raises an exception. Optionally
+ stale_if_error: Return a stale response if a new request raises an exception. Optionally
accepts a time value representing maximum staleness to accept.
+ stale_while_revalidate: Return a stale response initially, while a non-blocking request is
+ sent to refresh the response for the next time it's requested
filter_fn: Response filtering function that indicates whether or not a given response should
be cached. See :ref:`custom-filtering` for details.
key_fn: Request matching function for generating custom cache keys. See