One strategy we are using for caching the Python calls is to provide both a
max-age
and stale-while-revalidate
value.
Setting a max-age
informs the consumer to not come back at all during the
period as the content is known 'good'. Setting a stale-while-revalidate
as well
tells the consumer that they can safely use the content in their cache while they check for updates.
This should result in the following sort of behavior:
- User requests a resource for the first time
- Result: Cache is populated
- User requests the same resource very quickly
- Result: User does not even make a second request due to
max-age
- Result: User does not even make a second request due to
- User requests the same resource after the
max-age
has expired but before thestale-while-revalidate
has expired- Result:
- User is immediately served the old cached content
- Then asynchronously the content is checked for validity
- The cache updated as necessary
- Result:
- User requests the same resource very quickly after receiving the previous copy is found 'stale'
- Result: User is returned the updated content retrieved asynchronously last time
This means the user may see a stale version on the second try if the content has changed, but can quickly fix this simply checking again.
In a very crude overview the proxy works by:
- A Python call to determine the type (PDF or not) - Slowish
- A call through NGINX to serve the content - Fastish
If this call is made repeatedly the flow is:
- Python call #1
- NGINX call #1 (user journey 1 complete)
- Python call #2
- NGINX call #2 (user journey 2 complete)
- Python call #3
- NGINX call #3 (user journey 3 complete)
Using the stale-while-revalidate
the sequence from the users point of view becomes
- Python call #1
- NGINX call #1 (user journey 1 complete)
- NGINX call #2 (user journey 2 complete with contents of Python call #1)
- Python call #2 (async)
- NGINX call #3 (user journey 3 complete with contents of Python call #2)
- Python call #3 (async)
With the caveat that the content is always one call out of date, this effectively means the Python call is made after the NGINX call.
The different calls have different time-outs as we can rely on some checks to effectively invalidate others.
- When served under
/
the timeout is 60s - When served under
/static/<salt>
marked as immutable - This means whatever serves links to immutable assets:
- Must use
request.static_url()
to generate URLs for them - Must change for new assets to be picked up
- Must use
max-age
: PDF: 5m, HTML 60s- PDFs should be relatively static, and take a while to update and change
- HTML could be served from a wiki or other volatile source
max-age
: 0- This is the jumping off point from where we link to static assets
- As these assets are marked immutable, this must change to pick them up