pallets-eco / flask-caching

A caching extension for Flask
https://flask-caching.readthedocs.io
Other
894 stars 194 forks source link

response_hit_indication hit_cache always True once set #570

Open robbiehaynes opened 5 months ago

robbiehaynes commented 5 months ago

When using a Flask route that contains URL parameters with response_hit_indication set to True, the caching functionality works however once the hit_cache header is added for the first time, it persists even if the cache isn't hit on a following request

In this example:

@app.route('/<param1>/<param2>', methods=['GET'])
@cache.cached(timeout=60, response_hit_indication=True)
def cached_route():
   pass

The caching works correctly however if you hit the endpoint three times with the following parameters, this is the outcome:

  1. GET /test/test (no hit_cache header)
  2. GET /test/test (hit_cache header = True)
  3. PROBLEM: GET /test/newtest (hit_cache header = True but cache wasn't actually hit)

The last request shouldn't have the hit_cache header in it's response because nothing is correctly found in the cache for that unique hash. I narrowed down the issue to likely the following code but I'm not an expert on Flask async:

if response_hit_indication:
   ...
   self.app.after_request_funcs[None].append(apply_caching)

The Flask documentation says the correct way to mount to after_request_funcs is to use the @after_request decorator to mount it to application once.

The implemented solution means that when the after_request_funcs are looped over to ensure_sync by Flask, it loops over request number 2 again which sets the hit_cache header to True when the cache wasn't hit for request number 3.

I essentially want to use the hit_cache header for unit testing so I can ensure that the implementation of Flask-Cache is persistent across different versions of my application.

Environment: