<div dir="ltr">So in light of the hit-for-pass vs. hit-for-miss change in 5.0 (which I think is great), I have been researching 0s TTL objects coming into cache (and generating the hit-for-XXX marker). In particular, even with grace disabled, I have still seen valid objects from one Varnish come in as a stale 0s TTL object in another Varnish. As in, an object comes into Varnish with a max-age of X and an equal Age of X. Example:<div><br></div><div>Cache-Control: max-age=14</div><div>Age: 14</div><div><br></div><div>The effective TTL here is 0s, triggering the hit-for-XXX. Looking at the code:</div><div><br></div><div><div>http_PrintfHeader(req->resp, "Age: %.0f",</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>    fmax(0., req->t_prev - req->objcore->t_origin));</div><div><br></div><div><a href="https://github.com/varnishcache/varnish-cache/blob/f4400e0c682c69ba63fc7c00abe7246ea570fbd8/bin/varnishd/cache/cache_req_fsm.c#L95-L96">https://github.com/varnishcache/varnish-cache/blob/f4400e0c682c69ba63fc7c00abe7246ea570fbd8/bin/varnishd/cache/cache_req_fsm.c#L95-L96</a><br></div><div><br></div><div>The issue here is that %.0f will do a standard IEEE floating point numerical rounding to satisfy the precision. I am not sure if this is a C standard, but in my tests, this holds true. In the context of our Age calculation, this means that objects in their last 0.5s of TTL life will get their Age rounded up to the max-age and then anything reading this response will see a stale object.</div><div><br></div><div>Given that we are losing precision and accepting a 1s rounding error, floor() is the best choice here as it doesn't have the side effect of this premature Age == max-age scenario. So something as simple as:</div><div><br></div><div><div>http_PrintfHeader(req->resp, "Age: %.0f",</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>    floor(fmax(0., req->t_prev - req->objcore->t_origin)));</div></div><div><br></div><div>Will make sure we *always* get an Age < max-age, up until the actual Age >= max-age and the object is infact stale.</div><div><br></div><div>Thoughts? I am not sure of the history here and if this has been previously considered and there are valid reasons for this logic. If so, I apologize in advance!</div><div><br></div><div><div><div class="gmail_signature"><div dir="ltr">--<br>Reza Naghibi<br>Varnish Software</div></div></div>
</div></div></div>