1

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?

DaJudge
  • 53
  • 1
  • 7

0 Answers0