Using redis in combination with Flask_caching. When data changes the app uses cache.clear()
to clear redis keys, which works. However, when a user request a page for a record that is not in the database redis fills up with keys. I would like to keep my TTL for at least a week or longer. So the app needs to remove the invalid keys since they will fill-up redis over time. I looked at cache.delete()
, redis.expire()
and cache.set()
but none of them work during the request. It seems the redis entry is only created after the request, so I can not change the TTL or delete it.
I decide on this solution.
@home.route('/product/<int:product_id>')
@cache.cached()
def view_product(product_id):
data = Product.query.filter_by(id=product_id).filter_by(active=True).first()
if data is None:
message = 'Invalid Product'
prefix = current_app.config['CACHE_KEY_PREFIX']
deleteBadCacheList = f"{prefix}INVALID"
key = f"{prefix}view/{request.path}"
redis.lpush(deleteBadCacheList, key)
for key in redis.lrange(deleteBadCacheList, 0, -1):
key = key.decode("utf-8")
if redis.exists(key):
redis.expire(key, 1)
redis.lrem(deleteBadCacheList, 0, key)
....
return render_template('product.html', flash=message, product=data.serialized)
With this approach requests for invalid products are stored in a redis range key <prefix>INVALID
. And every-time another request is made, for an invalid product, the app removes items from previous failed request. I have a feeling there is a better way. Seems to me most applications will have this problem. Any suggestions?