const char *doclose;
struct http *http;
- time_t t_req;
- time_t t_resp;
+ struct timespec t_req;
+ struct timespec t_idle;
enum step step;
unsigned handling;
vca_tick(int a, short b, void *c)
{
struct sess *sp, *sp2;
- time_t t;
+ struct timespec t;
(void)a;
(void)b;
(void)c;
AZ(evtimer_add(&tick_e, &tick_rate));
- (void)time(&t);
+ clock_gettime(CLOCK_MONOTONIC, &t);
TAILQ_FOREACH_SAFE(sp, &sesshead, list, sp2) {
- if (sp->t_resp + 30 < t) {
+ if (sp->t_idle.tv_sec + 30 < t.tv_sec) {
TAILQ_REMOVE(&sesshead, sp, list);
vca_close_session(sp, "timeout");
vca_return_session(sp);
(void)arg;
i = read(fd, &sp, sizeof sp);
assert(i == sizeof sp);
- sp->t_resp = time(NULL);
+ clock_gettime(CLOCK_MONOTONIC, &sp->t_idle);
TAILQ_INSERT_TAIL(&sesshead, sp, list);
http_RecvHead(sp->http, sp->fd, evb, vca_callback, sp);
}
TCP_name(addr, l, sp->addr, sizeof sp->addr, sp->port, sizeof sp->port);
VSL(SLT_SessionOpen, sp->fd, "%s %s", sp->addr, sp->port);
- (void)time(&sp->t_resp);
+ clock_gettime(CLOCK_MONOTONIC, &sp->t_idle);
TAILQ_INSERT_TAIL(&sesshead, sp, list);
http_RecvHead(sp->http, sp->fd, evb, vca_callback, sp);
}
sp->backend->hostname);
}
- sp->t_req = time(NULL);
WRK_Reset(w, &vc->fd);
http_Write(w, vc->http, 0);
i = WRK_Flush(w);
*/
http_RecvHead(vc->http, vc->fd, w->eb, NULL, NULL);
(void)event_base_loop(w->eb, 0);
- sp->t_resp = time(NULL);
assert(http_DissectResponse(vc->http, vc->fd) == 0);
sp->vbc = vc;
+
+ sp->obj->entered = time(NULL);
+
return (0);
}
/* ignore */
} else if (o->ttl == 0) {
/* Object banned but not reaped yet */
- } else if (o->ttl < sp->t_req) {
+ } else if (o->ttl < sp->t_req.tv_sec) {
/* Object expired */
} else if (BAN_CheckObject(o, url)) {
o->ttl = 0;
struct worker *w;
pthread_t tp;
- sp->t_req = time(NULL);
+ clock_gettime(CLOCK_REALTIME, &sp->t_req);
sp->workreq.sess = sp;
sbuf_clear(sb);
sbuf_printf(sb, "HTTP/1.1 %03d %s\r\n", error, msg);
- TIM_format(sp->t_req, buf);
+ TIM_format(sp->t_req.tv_sec, buf);
sbuf_printf(sb, "Date: %s\r\n", buf);
sbuf_cat(sb,
"Server: Varnish\r\n"
if (sp->obj->last_modified > 0 &&
http_GetHdr(sp->http, H_If_Modified_Since, &p)) {
ims = TIM_parse(p);
- if (ims > sp->t_req) /* [RFC2616 14.25] */
+ if (ims > sp->t_req.tv_sec) /* [RFC2616 14.25] */
return (0);
if (ims > sp->obj->last_modified) {
VSL(SLT_Debug, sp->fd,
{
struct storage *st;
unsigned u = 0;
+ double dt;
+ struct timespec t_resp;
+ clock_gettime(CLOCK_REALTIME, &t_resp);
+ dt = (t_resp.tv_sec - sp->t_req.tv_sec);
+ dt += (t_resp.tv_nsec - sp->t_req.tv_nsec) * 1e-9;
+ VSL(SLT_ReqServTime, sp->fd, "%ld.%09ld %.9f",
+ (long)sp->t_req.tv_sec, (long)sp->t_req.tv_nsec, dt);
+
if (sp->obj->response == 200 && sp->http->conds && res_do_conds(sp))
return;
else
http_PrintfHeader(sp->fd, sp->http, "X-Varnish: %u", sp->xid);
http_PrintfHeader(sp->fd, sp->http, "Age: %u",
- sp->obj->age + sp->t_req - sp->obj->entered);
+ sp->obj->age + sp->t_req.tv_sec - sp->obj->entered);
http_SetHeader(sp->fd, sp->http, "Via: 1.1 varnish");
if (sp->doclose != NULL)
http_SetHeader(sp->fd, sp->http, "Connection: close");
VBACKEND(const char *, host, hostname)
VBACKEND(const char *, port, portname)
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * XXX: Working relative to t_req is maybe not the right thing, we could
+ * XXX: have spent a long time talking to the backend since then.
+ * XXX: It might make sense to cache a timestamp as "current time"
+ * XXX: before vcl_recv (== t_req) and vcl_fetch.
+ * XXX: On the other hand, that might lead to inconsistent behaviour
+ * XXX: where an object expires while we are running VCL code, and
+ * XXX: and that may not be a good idea either.
+ * XXX: See also related t_req use in cache_hash.c
+ */
void
VRT_l_obj_ttl(struct sess *sp, double a)
VSL(SLT_TTL, sp->fd, "%u VCL %.0f %u", sp->obj->xid, a, sp->t_req);
if (a < 0)
a = 0;
- sp->obj->ttl = sp->t_req + (int)a;
+ sp->obj->ttl = sp->t_req.tv_sec + (int)a;
if (sp->obj->heap_idx != 0)
EXP_TTLchange(sp->obj);
}
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); /* XXX */
- return (sp->obj->ttl - sp->t_req);
+ return (sp->obj->ttl - sp->t_req.tv_sec);
}
/*--------------------------------------------------------------------*/
#endif
static time_t
-RFC2616_Ttl(struct sess *sp, struct http *hp, time_t t_req, time_t t_resp, struct object *obj)
+RFC2616_Ttl(struct sess *sp, struct http *hp, struct object *obj)
{
int retirement_age;
unsigned u1, u2;
time_t h_date, h_expires, ttd;
char *p;
- (void)t_resp; /* XXX */
-
retirement_age = INT_MAX;
u1 = u2 = 0;
if (http_GetHdr(hp, H_Expires, &p))
h_expires = TIM_parse(p);
- if (h_date < t_req && h_expires > t_req) {
+ if (h_date < obj->entered && h_expires > obj->entered) {
ttd = h_expires;
- if (retirement_age != INT_MAX && t_req + retirement_age < ttd)
- ttd = t_req + retirement_age;
+ if (retirement_age != INT_MAX &&
+ obj->entered + retirement_age < ttd)
+ ttd = obj->entered + retirement_age;
} else {
if (h_date != 0 && h_expires != 0) {
if (h_date < h_expires &&
if (retirement_age == INT_MAX)
retirement_age = heritage.default_ttl;
- ttd = t_req + retirement_age;
+ ttd = obj->entered + retirement_age;
}
/* calculated TTL, Our time, Date, Expires, max-age, age */
VSL(SLT_TTL, sp->fd, "%u RFC %d %d %d %d %d %d", sp->xid,
- (int)(ttd - t_req), (int)t_req, (int)h_date, (int)h_expires,
- (int)u1, (int)u2);
+ (int)(ttd - obj->entered), (int)obj->entered, (int)h_date,
+ (int)h_expires, (int)u1, (int)u2);
return (ttd);
}
break;
}
- sp->obj->ttl = RFC2616_Ttl(sp, hp, sp->t_req, sp->t_resp, sp->obj);
- sp->obj->entered = sp->t_req;
+ sp->obj->ttl = RFC2616_Ttl(sp, hp, sp->obj);
if (sp->obj->ttl == 0) {
sp->obj->cacheable = 0;
}
SLTM(CLI)
SLTM(StatAddr)
SLTM(StatSess)
+SLTM(ReqServTime)
SLTM(SessionOpen)
SLTM(SessionReuse)
SLTM(SessionClose)