On 2/13/06, Robert Wittams <[EMAIL PROTECTED]> wrote: > Yes, this is exactly what I intended to convey... sorry if I didn't make > myself clear...
It might take me few attempts to get the point, but as long as we all end up on the same page... :-) > > - q = Article.objects.filter(...).cached(); q.cached() returns a second > > version of the filter query, with a clean cache > > Hm, not really sure if that is obvious. I was assuming cached would be > something like: ... > Ie, it just returns itself if it will "do". Query sets can be passed > around, and the caller is intending to say "make sure this is cached". I was assuming that cached() would _always_ clone. If the source QuerySet is non-cached, you get a clone with caching enabled; if the source is cached, you get a new QuerySet with a clean cache. The use case I can see is: p = Article.objects.filter(...) # Original, uncached query q = p.cached() # Copied, cache version 1 for obj in q: ... # evaluate cache 1 #Add an object that would match q r = q.cached() # Copy of cached query, cache version 2 for obj in r: ... # evaluate cache 2; new object is in list for obj in q: ... # Iterate over cache 1; new object not in list This way, the cache becomes a store of what was in the database when the query was executed, rather than there being a unique cache for any given query. More on this later... > And then the .all() really starts to look meaningless. Yup. Hey, this understanding each other thing is fun! :-) > So without externalising, the choices are: > > a) inconsistency with managers and related objects having different > default caching behaviour. > b) the need to have a lot of .cached() being used on related objects, > when that is likely to be what people want in 95% of situations. I would tend to go with (b), with a chorus of 'fix this in the documentation'. i.e., make the documentation very clear about the fact that a cache is available, and might be a good way to optimize performance in some cases. Also - 95%? Really? The perfomance hit of non-caching only matters if you iterate over any given QuerySet more than once per http request. Maybe I'm being unimaginative, but thinking over my common use cases, multiple iterations over a QuerySet per http request would be the exception, rather than the rule (or at the very least, nowhere near 95% of all use cases). There is also an option (c): make the manager a cached query, and document the need to use non_cached(). If multiple iterations over a query set really is the 95% use case, it would make sense to me to cache across the board. > Externalising caching means that consistent *and* non-ugly behaviour can > be offered for all "query set entry points" - managers and related objects. Well - for your definition of consistent and non-ugly, anyway :-) I think we may have different ideas on the cardinality of the query-cache releationship. Consider: p = Article.objects.filter(headline='xyz').cached() q = Article.objects.filter(headline='xyz').cached() If I am understanding your caching model correctly, you would ideally like to see p and q using the same cache. This model is almost impossible to acheive without externalization; the mapping of this caching model onto the existing framework (where p and q have different caches unless q is a clone of p) is very much ugly. Ergo, pro externalization. My problem with this model is that p.reset_cache() would clear q's cache, too. On top of that, there is the question of when the system automagically flushes the cache (per http request and per transaction being two reasonable suggestions). I would argue that p and q should have independent caches. This way, once you have iterated over p, you know exactly what is there; if you iterate over p again, you will get always get exactly the same result, regardless of what you have done to q. This makes a populated cache a snapshot of the state of the database at a given time. No need to worry if someone/something else has changed the database - my snapshot is always the same. It's a slightly different model of caching, but it is a consistent and easily explainable model, IMHO non-ugly, and doesn't require externalization to achieve - it is entirely covered by the existing framework, plus the modifications we have been discussing. Russ Magee %-)