Bug 14556 - mod_cache with mod_mem_cache enabled doesnt cash modified documents
Summary: mod_cache with mod_mem_cache enabled doesnt cash modified documents
Status: RESOLVED WORKSFORME
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_cache (show other bugs)
Version: 2.0.44
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-11-14 16:04 UTC by Sergey
Modified: 2007-06-08 12:02 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sergey 2002-11-14 16:04:03 UTC
When document is cashed, mod_cache.c stores time of cash in date variable 
(info->date), when it happenes debug says "Added date header". Then every 
other request will use this cash and date variable will always be the same 
with the date when cash stored. All works fine yet, but that happens if cashed 
document was changed: mod_cache stores new last modified date of the document 
in the lastmod variable, and then compares if lastmod > date then 
lastmod=date, debug says "lastmod is in the future replacing with now"(but 
date its not now, its date of last cash?). The problem is how mod_cache 
calculates cash expire. 

expiry date = now + min((date - lastmod) * factor, maxexpire)

If document doesnt have Expire in the headers, then expire time will be: now + 
0 * factor = now, and mod_cache will never cash document anymore, before 
apache restart when cashed headers with old date will be deleted. 

I dont know is it supposed to work this way, or maybe some removal algorithms 
of old cashed dates doesnt work? For now i deleted "if lastmod>date then 
lastmod=date" piece of code and all works fine. 

Also i added:
expiry date = now + min(((date - lastmod) * factor) + conf->defex, maxexpire)

so if i set "CacheLastModifiedFactor 0" and "CacheDefaultExpire time" in 
httpd.conf, i can manually add expire time in seconds if i dont want to use 
Expires headers, so should be the way to manually enter expire time besides 
Expire headers.
Comment 1 Paul J. Reder 2002-11-21 22:07:33 UTC
Thanks for the diagnosis and input. I have committed a fix for this PR which
will be shipped in a future release of Apache.

The fix simply changes the checking code in mod_cache (around line 853) from

if (lastmod != APR_DATE_BAD)

to

if ((lastmod != APR_DATE_BAD) && (lastmod < date))

This forces the code into the else clause when lastmod == date.

You should not remove the "if lastmod>date then lastmod=date" code
since this has other negative consequences in checking for freshness.
Also, adding the conf->defex value into the expiry date calculation, as you
did, will either result in a longer than expected expiry date, or an expiry
date of maxexpire.

Please let me know if the above fix (adding "&& (lastmod < date))") fails to
solve the problem for you.

Thanks for using Apache and helping to make it better.
Comment 2 Sergey 2002-12-12 22:15:04 UTC
Hi,

i just checked your response.

Look, that if you change

if (lastmod != APR_DATE_BAD)

to

if ((lastmod != APR_DATE_BAD) && (lastmod < date))

that will work, but it will break advantage of conf->factor future, and 
modified documents always will be based on conf->defex variable. So what will 
be the difference between document that is modified every 10 sec and another 
that is modified every 5 hours? 
As i got, the problem is that mod_cache doesnt refresh "Date" value in cached 
headers untill apache restart, so, instead of that fix above, line 809 should 
be changed from

if (info->date == APR_DATE_BAD) {

to

if ((info->date == APR_DATE_BAD) || (lastmod >= info->date)) {

this will update date header in cache after document was modified, and after 
that all will work fine, with conf->factor etc. as like apache was restarted.
Comment 3 Sergey 2003-01-25 16:29:21 UTC
The problem still in 2.0.44. With the fix above modified documents will never use 
this formula: expiry date = now + min((date - lastmod) * factor, maxexpire), 
because the "Date" header doesnt refresh never, lastmod always will be greater 
than date, isnt that a bug? So, the string around line 704 (in 2.0.44 mod_cache.c) 
should be changed from

    if (info->date == APR_DATE_BAD){  /* No, or bad date */
to
    if ((info->date == APR_DATE_BAD) || (lastmod > date)){  /* No, or bad date */

that will make "Date" header updated with *now* if document was modified and 
lastmod wont be greater than date. So the formula with conf->factor will work.

Also that string around line 752 that is now 
   if ((lastmod != APR_DATE_BAD) && (lastmod < date)) {
should be changed to
   if ((lastmod != APR_DATE_BAD) && (lastmod <= date)) {

Because in some cases, then the document was modified in the same time(same 
second) as requested by server, it should really expired by now and not be 
cached for default time. 

With these fixes above, it will be possible to configure the server to cache the 
documents for some time, BUT the documents that is modified for example every 
1 second, automatically will be almost not cached.
Comment 4 Sergey 2003-01-26 00:18:43 UTC
One mistake above, line 752

    if ((lastmod != APR_DATE_BAD) && (lastmod < date)) {

should be changed back to simple

    if (lastmod != APR_DATE_BAD) {

not to

if ((lastmod != APR_DATE_BAD) && (lastmod <= date)) {

because there will be no difference, lastmod always <= date
Comment 5 Paul Querna 2005-06-03 02:38:57 UTC
Can you please try this with 2.0.54, and try using mod_disk_cache instead of
mod_mem_cache?

Thanks
Comment 6 Davi Arnaut 2007-06-08 12:02:07 UTC
No response from user. If more information appears later, please re-open
the bug, for now, file it.