Improve cached_endpoint behavior with sentinel.
This commit is contained in:
parent
56ab6636cc
commit
975408227b
3 changed files with 19 additions and 4 deletions
|
@ -4,11 +4,14 @@ import time
|
||||||
|
|
||||||
from voussoirkit import dotdict
|
from voussoirkit import dotdict
|
||||||
from voussoirkit import passwordy
|
from voussoirkit import passwordy
|
||||||
|
from voussoirkit import sentinel
|
||||||
|
|
||||||
import etiquette
|
import etiquette
|
||||||
|
|
||||||
from . import jsonify
|
from . import jsonify
|
||||||
|
|
||||||
|
NOT_CACHED = sentinel.Sentinel('not cached', truthyness=False)
|
||||||
|
|
||||||
def cached_endpoint(max_age):
|
def cached_endpoint(max_age):
|
||||||
'''
|
'''
|
||||||
The cached_endpoint decorator can be used on slow endpoints that don't need
|
The cached_endpoint decorator can be used on slow endpoints that don't need
|
||||||
|
@ -29,12 +32,19 @@ def cached_endpoint(max_age):
|
||||||
the previous return value (still using 200 or 304 as appropriate for the
|
the previous return value (still using 200 or 304 as appropriate for the
|
||||||
client's provided etag).
|
client's provided etag).
|
||||||
|
|
||||||
|
With max_age=0, the function will be run every time to check if the value
|
||||||
|
has changed, but if it hasn't changed then we can still send a 304 response,
|
||||||
|
saving bandwidth.
|
||||||
|
|
||||||
An example use case would be large-sized data dumps that don't need to be
|
An example use case would be large-sized data dumps that don't need to be
|
||||||
precisely up to date every time.
|
precisely up to date every time.
|
||||||
'''
|
'''
|
||||||
|
if max_age < 0:
|
||||||
|
raise ValueError(f'max_age should be positive, not {max_age}.')
|
||||||
|
|
||||||
state = dotdict.DotDict({
|
state = dotdict.DotDict({
|
||||||
'max_age': max_age,
|
'max_age': max_age,
|
||||||
'stored_value': None,
|
'stored_value': NOT_CACHED,
|
||||||
'stored_etag': None,
|
'stored_etag': None,
|
||||||
'headers': {'ETag': None, 'Cache-Control': f'max-age={max_age}'},
|
'headers': {'ETag': None, 'Cache-Control': f'max-age={max_age}'},
|
||||||
'last_run': 0,
|
'last_run': 0,
|
||||||
|
@ -42,7 +52,12 @@ def cached_endpoint(max_age):
|
||||||
|
|
||||||
def wrapper(function):
|
def wrapper(function):
|
||||||
def get_value(*args, **kwargs):
|
def get_value(*args, **kwargs):
|
||||||
if state.max_age and (time.time() - state.last_run) > state.max_age:
|
can_bail = (
|
||||||
|
state.stored_value is not NOT_CACHED and
|
||||||
|
state.max_age != 0 and
|
||||||
|
(time.time() - state.last_run) < state.max_age
|
||||||
|
)
|
||||||
|
if can_bail:
|
||||||
return state.stored_value
|
return state.stored_value
|
||||||
|
|
||||||
value = function(*args, **kwargs)
|
value = function(*args, **kwargs)
|
||||||
|
|
|
@ -195,7 +195,7 @@ def post_album_show_in_folder(album_id):
|
||||||
# Album listings ###################################################################################
|
# Album listings ###################################################################################
|
||||||
|
|
||||||
@site.route('/all_albums.json')
|
@site.route('/all_albums.json')
|
||||||
@decorators.cached_endpoint(max_age=0)
|
@decorators.cached_endpoint(max_age=15)
|
||||||
def get_all_album_names():
|
def get_all_album_names():
|
||||||
all_albums = {album.display_name: album.id for album in common.P.get_albums()}
|
all_albums = {album.display_name: album.id for album in common.P.get_albums()}
|
||||||
response = {'albums': all_albums}
|
response = {'albums': all_albums}
|
||||||
|
|
|
@ -99,7 +99,7 @@ def post_tag_remove_synonym(tagname):
|
||||||
# Tag listings #####################################################################################
|
# Tag listings #####################################################################################
|
||||||
|
|
||||||
@site.route('/all_tags.json')
|
@site.route('/all_tags.json')
|
||||||
@decorators.cached_endpoint(max_age=0)
|
@decorators.cached_endpoint(max_age=15)
|
||||||
def get_all_tag_names():
|
def get_all_tag_names():
|
||||||
all_tags = list(common.P.get_all_tag_names())
|
all_tags = list(common.P.get_all_tag_names())
|
||||||
all_synonyms = common.P.get_all_synonyms()
|
all_synonyms = common.P.get_all_synonyms()
|
||||||
|
|
Loading…
Reference in a new issue