Closed roccomuso closed 7 years ago
This library could have a lot of potential, the invalidation of an object is definitely a big need.
I really like the idea, but there are complications of that, which I haven't quite figured out how to handle elegantly. Example: let's say you have a "User" record, and you cache that particular record. If we plugged into sequelize, we could easily invalidate that record on save/update. But what if you then cache a collection of users based on a SQL query? For example, all users in a specific timezone. How would we invalidate that collection? Currently we use an md5 hash of the query as the redis key, so we can't practically inspect every single cache item in redis. Those are the issue I wrestle with, in considering expanding the functionality beyond a simple caching layer.
I've added a link to Amazon's caching strategies / recommendations to the README.md. I'm going to close this issue, but I'm still open to any ideas on making this more robust, in terms of cache management.
I +1 this addition. @rfink, when you're talking about users and timezones, are you referring to a situation like this?:
I'm using this library with GraphQL, where I need cache invalidation for mutations(create/update/delete), i.e. user presses like button on an article, API records that like by the user, then the API needs to return the article data with the updated like count after invalidating the cached data for that article.
@Naoto-Ida - yes that is a great example of the situation that is difficult to handle programmatically. Especially now with the new raw query capabilities.
@rfink its a really good library. However, without cache invalidation methods, we can't use it
Thank you for enjoying it. I'm open to suggestions on how to implement cache invalidation on a larger scale, but we haven't been able to come up with anything quite yet.
@rfink there are lifecycle hooks for create and update right? Why can't we clear the cache on these hooks? Next time a find* is done, insert it back to cache.
So that's an idea that's been thrown around, and definitely possible, but that wouldn't include ranged or complex queries that include those records, such as .findAll({ where: { date: { $gt: 2017-01-01T00:00:00Z' } } });
So the behavior would be inconsistent. What are your thoughts on that?
did you mean update instead of find? like model.update(args, { where: { date: { $gt: 2017-01-01T00:00:00Z' } } });
oh, when findAll({ where: { date: { $gt: 2017-01-01T00:00:00Z' } } });
is executed a cache is built with its hash right?
Right - which we wouldn't be able to determine all possible objects that were affected. That's been my biggest concern with the cache busting.
Maybe the behavior is opt in, with good documentation on what wouldn't be invalidated properly. I know this is a large issue for some, and I'd love to find a way to tackle it.
hmmm. Let me do a research about in detail. I'll get back to you in a few days
Great, thanks! I'm looking forward to what you find.
@rfink How's the data of cached queries currently stored in Redis? A hash of the query and its result?
Right, the key is an MD5 hash of the JSON query object passed in the findX call, and the value is the raw JSON string of the results.
ok
I would reccommend to edit the README.md to insert some hints on how to choose the best TTL value according to the application type :)
Moreover, we should think about a cache invalidation mechanism :) any hints?