Hey Jeremy,

On Thu, 2007-03-08 at 12:37 -0500, Jeremy Bowers wrote:
> Malcolm Tredinnick wrote:
> 
> For concreteness, I've added a ticket and there is a code-only patch at 
> http://code.djangoproject.com/attachment/ticket/3680/cache.control.on.syndication.code.only.diff
>  
> . The patch is exceedingly lightly tested (I've only smoke tested it on 
> a local dev box, and I haven't tested cache_control_from_bits at all), 
> it's just for discussion.

Cool. I'll have a look at it in detail. From a first read, though, it
looks like a reasonable approach: building in cache management to the
view. Why can't this be done using the normal CacheMiddleware, though?
Requests for the same URL will check the cache first using that. You can
also invalidate cached entries manually, if you like, as part of adding
new objects or updating an object that might be in a feed.

I'm not completely in love with all portions of the patch, but I'll have
a read through it more carefully, test some things and get back to you.

The rest of my response is on a more theoretical level...

> > Could you make some timings to show the difference between retrieving
> > all the objects for a feed (which you need to do to establish whether
> > it's changed) and retrieving all the objects and constructing the feed?
> > The extra overhead of turning objects into a sequence of bytes isn't
> > that huge as a proportion of the overall time -- I measured it for my
> > own feed examples when working on some syndication problems last year
> > and the generation was very short when compared to the database
> > interaction and pushing out the data via the network, except when I had
> > quite tiny datasets or very complex transformations in templates. The
> > former is ignorable, since the total time is so small, whilst the latter
> > is atypical for feeds. It would be interesting to see if that (the
> > timing ratios) has changed much.
> >   
> I understand what you're getting at, but the value of benchmarking 
> something where there can be arbitrary client code is dubious.

Disagree. Benchmarking is required as part of examining performance
problems. Otherwise you cannot tell what has changed and whether it's an
improvement. It obviously cannot cover every case, but we are trying to
strike a balance between common usage, maintainable and correct code,
and edge cases. 

[...]
> However, you've raised a good point w.r.t. database access, so I did go 
> ahead and add the hook to determine ETag and Last-Modified before even 
> hitting the DB. Perhaps you pull this from a cache. In that case, a 
> no-change RSS hit is no database hits at all.

So you've worked out a way to test for "no changes" without retrieving
all the objects that make up the feed? OK, I see you're just using the
cache stuff. Makes sense.

> > There is some consistent logic supporting things like the
> > ConditionalGetMiddleware: content generation is typically small
> > (timewise) compared to content shipping and database retrieval.
> I find this logic questionable. It's the non-typical cases where it is 
> expensive where it is disproportionately important.

[...]
> > I think a bunch of the things you're talking about can be done by
> > modifying contrib.syndication.views.feed() so that more return options
> > are handled. Views can already jump out early with their own HTTP
> > response codes and/or tweak their HTTP headers.
> I don't know what you mean by this; return values from what? 
> contrib.syndication.views.feed (at least prior to my patch) never calls 
> any user code.

I used lazy language here. Apologies. Your Feed-derived class's methods
are called as part of a view function. That view function is, in the
standard setup, contrib.syndication.views.feed(). Don't look at the Feed
class and sub-classes as special, in this respect: they are just one
part of a view. So you can bail out of feed processing by raising
exceptions, for example, and catching them in the view to return the
right HTTP code. At the moment, the standard view doesn't catch any
special exceptions (except for Http404), but writing a slightly
different view that did would be easy.

Your code seems to be taking a similar, but slightly different approach,
by putting cache support into the view. That may work, too.

Finally, let me just make something clear...

The work you seem to be doing may well be of real benefit, so don't
think I'm dismissing it out of hand. Even just talking through the
design is going to help somebody someday.

It's impossible to really judge the impact on the usefulness vs.
maintainable/good design scale without seeing the code and you're
clearly writing something that scratches your own itch. I'm genuinely
not intending to pre-judge your code at all here, since I haven't looked
at it until just now. I am, however, quite willing to keep questioning
your assumptions and start from my default position of "prove it" when
it comes to adding extra code to support fringe cases.

You may be unlucky here in who chose to respond. There's evidence to
suggest that I'm more of a hard-ass on this front than the other core
developers, but only by a little bit.

Regards,
Malcolm


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to