Commit e6511775 authored by Martin Blix Grydeland's avatar Martin Blix Grydeland

Merge r5170: Introduce req.hash_always_miss (force cache miss) and...

Merge r5170: Introduce req.hash_always_miss (force cache miss) and req.hash_ignore_busy (ignore busy objects) variables available in vcl_fetch.



git-svn-id: http://www.varnish-cache.org/svn/branches/2.1@5171 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 2175fdf6
......@@ -376,6 +376,9 @@ struct sess {
int esis;
int disable_esi;
uint8_t hash_ignore_busy;
uint8_t hash_always_miss;
struct worker *wrk;
socklen_t sockaddrlen;
......
......@@ -269,6 +269,8 @@ cnt_done(struct sess *sp)
memset(&sp->acct_req, 0, sizeof sp->acct_req);
sp->t_req = NAN;
sp->hash_always_miss = 0;
sp->hash_ignore_busy = 0;
if (sp->fd >= 0 && sp->doclose != NULL) {
/*
......
......@@ -403,8 +403,9 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
if (oc == NULL /* We found no live object */
&& grace_oc != NULL /* There is a grace candidate */
&& (busy_oc != NULL /* Somebody else is already busy */
|| !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh))) {
/* Or it is impossible to fetch: */
|| !VBE_Healthy(sp->t_req, sp->director, (uintptr_t)oh))
/* Or it is impossible to fetch */
&& !sp->hash_ignore_busy) { /* And we've not been told to ignore busy */
o = grace_oc->obj;
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
if (o->ttl + HSH_Grace(sp->grace) >= sp->t_req)
......@@ -416,18 +417,27 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
assert(oc->objhead == oh);
/* We found an object we like */
oc->refcnt++;
if (o->hits < INT_MAX)
o->hits++;
assert(oh->refcnt > 1);
Lck_Unlock(&oh->mtx);
assert(hash->deref(oh));
*poh = oh;
return (oc);
if(sp->hash_always_miss) {
if (o->ttl >= sp->t_req) {
o->ttl = sp->t_req - 1;
o->grace = HSH_Grace(sp->grace);
EXP_Rearm(o);
}
o = NULL;
} else {
/* We found an object we like */
oc->refcnt++;
if (o->hits < INT_MAX)
o->hits++;
assert(oh->refcnt > 1);
Lck_Unlock(&oh->mtx);
assert(hash->deref(oh));
*poh = oh;
return (oc);
}
}
if (busy_oc != NULL) {
if (busy_oc != NULL && !sp->hash_ignore_busy) {
/* There are one or more busy objects, wait for them */
if (sp->esis == 0)
VTAILQ_INSERT_TAIL(&oh->waitinglist, sp, list);
......
......@@ -684,6 +684,42 @@ VRT_r_req_xid(struct sess *sp)
return (p);
}
/*--------------------------------------------------------------------
* req.hash_ignore_busy
*/
void
VRT_l_req_hash_ignore_busy(struct sess *sp, unsigned ignore_busy)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
sp->hash_ignore_busy = !!ignore_busy;
}
unsigned
VRT_r_req_hash_ignore_busy(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return sp->hash_ignore_busy;
}
/*--------------------------------------------------------------------
* req.hash_always_miss
*/
void
VRT_l_req_hash_always_miss(struct sess *sp, unsigned always_miss)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
sp->hash_always_miss = !!always_miss;
}
unsigned
VRT_r_req_hash_always_miss(struct sess *sp)
{
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
return sp->hash_always_miss;
}
/*--------------------------------------------------------------------*/
struct sockaddr *
......
# $Id$
test "Test req.hash_always_miss in vcl_recv"
server s1 {
rxreq
txresp -hdr "Inc: 1"
rxreq
txresp -hdr "Inc: 2"
} -start
varnish v1 -vcl+backend {
sub vcl_recv {
if (req.http.x-missit == "1") {
set req.hash_always_miss = true;
}
}
sub vcl_deliver {
if(obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
} -start
client c1 {
txreq -url "/"
rxresp
expect resp.status == 200
expect resp.http.Inc == "1"
txreq -url "/"
rxresp
expect resp.status == 200
expect resp.http.Inc == "1"
txreq -url "/" -hdr "x-missit: 1"
rxresp
expect resp.status == 200
expect resp.http.Inc == "2"
txreq -url "/"
rxresp
expect resp.status == 200
expect resp.http.Inc == "2"
} -run
# $Id$
test "Test req.hash_ignore_busy in vcl_recv"
server s1 {
rxreq
sema r1 sync 2
delay 1
txresp -hdr "Server: 1"
} -start
server s2 {
rxreq
txresp -hdr "Server: 2"
} -start
varnish v1 -vcl+backend {
sub vcl_recv {
if (req.http.x-ignorebusy == "1") {
set req.hash_ignore_busy = true;
}
if (req.http.x-client == "1") {
set req.backend = s1;
}
if (req.http.x-client == "2") {
set req.backend = s2;
}
}
sub vcl_deliver {
if(obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
} -start
client c1 {
txreq -url "/" -hdr "x-client: 1"
rxresp
expect resp.status == 200
expect resp.http.Server == "1"
} -start
client c2 {
sema r1 sync 2
txreq -url "/" -hdr "x-client: 2" -hdr "x-ignorebusy: 1"
txreq -url "/" -hdr "x-client: 2"
rxresp
expect resp.status == 200
expect resp.http.Server == "2"
} -start
client c1 -wait
client c2 -wait
......@@ -27,6 +27,10 @@ const char * VRT_r_req_xid(struct sess *);
unsigned VRT_r_req_esi(struct sess *);
void VRT_l_req_esi(struct sess *, unsigned);
unsigned VRT_r_req_backend_healthy(const struct sess *);
unsigned VRT_r_req_hash_ignore_busy(struct sess *);
void VRT_l_req_hash_ignore_busy(struct sess *, unsigned);
unsigned VRT_r_req_hash_always_miss(struct sess *);
void VRT_l_req_hash_always_miss(struct sess *, unsigned);
const char * VRT_r_bereq_request(const struct sess *);
void VRT_l_bereq_request(const struct sess *, const char *, ...);
const char * VRT_r_bereq_url(const struct sess *);
......
......@@ -339,43 +339,48 @@ vcl_output_lang_h(struct vsb *sb)
vsb_cat(sb, "unsigned VRT_r_req_esi(struct sess *);\n");
vsb_cat(sb, "void VRT_l_req_esi(struct sess *, unsigned);\n");
vsb_cat(sb, "unsigned VRT_r_req_backend_healthy(const struct sess *");
vsb_cat(sb, ");\nconst char * VRT_r_bereq_request(const struct sess");
vsb_cat(sb, " *);\nvoid VRT_l_bereq_request(const struct sess *, co");
vsb_cat(sb, "nst char *, ...);\nconst char * VRT_r_bereq_url(const ");
vsb_cat(sb, "struct sess *);\nvoid VRT_l_bereq_url(const struct ses");
vsb_cat(sb, "s *, const char *, ...);\nconst char * VRT_r_bereq_pro");
vsb_cat(sb, "to(const struct sess *);\nvoid VRT_l_bereq_proto(const");
vsb_cat(sb, " struct sess *, const char *, ...);\n");
vsb_cat(sb, "double VRT_r_bereq_connect_timeout(struct sess *);\n");
vsb_cat(sb, "void VRT_l_bereq_connect_timeout(struct sess *, double");
vsb_cat(sb, ");\ndouble VRT_r_bereq_first_byte_timeout(struct sess ");
vsb_cat(sb, "*);\nvoid VRT_l_bereq_first_byte_timeout(struct sess *");
vsb_cat(sb, ", double);\ndouble VRT_r_bereq_between_bytes_timeout(s");
vsb_cat(sb, "truct sess *);\nvoid VRT_l_bereq_between_bytes_timeout");
vsb_cat(sb, "(struct sess *, double);\nconst char * VRT_r_beresp_pr");
vsb_cat(sb, "oto(const struct sess *);\nvoid VRT_l_beresp_proto(con");
vsb_cat(sb, "st struct sess *, const char *, ...);\n");
vsb_cat(sb, "void VRT_l_beresp_saintmode(const struct sess *, doubl");
vsb_cat(sb, "e);\nint VRT_r_beresp_status(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_beresp_status(const struct sess *, int);\n");
vsb_cat(sb, "const char * VRT_r_beresp_response(const struct sess *");
vsb_cat(sb, ");\nvoid VRT_l_beresp_response(const struct sess *, co");
vsb_cat(sb, "nst char *, ...);\nunsigned VRT_r_beresp_cacheable(con");
vsb_cat(sb, "st struct sess *);\nvoid VRT_l_beresp_cacheable(const ");
vsb_cat(sb, "struct sess *, unsigned);\ndouble VRT_r_beresp_ttl(con");
vsb_cat(sb, "st struct sess *);\nvoid VRT_l_beresp_ttl(const struct");
vsb_cat(sb, " sess *, double);\ndouble VRT_r_beresp_grace(const str");
vsb_cat(sb, "uct sess *);\nvoid VRT_l_beresp_grace(const struct ses");
vsb_cat(sb, "s *, double);\nconst char * VRT_r_obj_proto(const stru");
vsb_cat(sb, "ct sess *);\nvoid VRT_l_obj_proto(const struct sess *,");
vsb_cat(sb, " const char *, ...);\nint VRT_r_obj_status(const struc");
vsb_cat(sb, "t sess *);\nvoid VRT_l_obj_status(const struct sess *,");
vsb_cat(sb, " int);\nconst char * VRT_r_obj_response(const struct s");
vsb_cat(sb, "ess *);\nvoid VRT_l_obj_response(const struct sess *, ");
vsb_cat(sb, "const char *, ...);\nint VRT_r_obj_hits(const struct s");
vsb_cat(sb, "ess *);\nunsigned VRT_r_obj_cacheable(const struct ses");
vsb_cat(sb, "s *);\nvoid VRT_l_obj_cacheable(const struct sess *, u");
vsb_cat(sb, "nsigned);\ndouble VRT_r_obj_ttl(const struct sess *);\n");
vsb_cat(sb, ");\nunsigned VRT_r_req_hash_ignore_busy(struct sess *)");
vsb_cat(sb, ";\nvoid VRT_l_req_hash_ignore_busy(struct sess *, unsi");
vsb_cat(sb, "gned);\nunsigned VRT_r_req_hash_always_miss(struct ses");
vsb_cat(sb, "s *);\nvoid VRT_l_req_hash_always_miss(struct sess *, ");
vsb_cat(sb, "unsigned);\nconst char * VRT_r_bereq_request(const str");
vsb_cat(sb, "uct sess *);\nvoid VRT_l_bereq_request(const struct se");
vsb_cat(sb, "ss *, const char *, ...);\nconst char * VRT_r_bereq_ur");
vsb_cat(sb, "l(const struct sess *);\nvoid VRT_l_bereq_url(const st");
vsb_cat(sb, "ruct sess *, const char *, ...);\n");
vsb_cat(sb, "const char * VRT_r_bereq_proto(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_bereq_proto(const struct sess *, const char");
vsb_cat(sb, " *, ...);\ndouble VRT_r_bereq_connect_timeout(struct s");
vsb_cat(sb, "ess *);\nvoid VRT_l_bereq_connect_timeout(struct sess ");
vsb_cat(sb, "*, double);\ndouble VRT_r_bereq_first_byte_timeout(str");
vsb_cat(sb, "uct sess *);\nvoid VRT_l_bereq_first_byte_timeout(stru");
vsb_cat(sb, "ct sess *, double);\ndouble VRT_r_bereq_between_bytes_");
vsb_cat(sb, "timeout(struct sess *);\nvoid VRT_l_bereq_between_byte");
vsb_cat(sb, "s_timeout(struct sess *, double);\n");
vsb_cat(sb, "const char * VRT_r_beresp_proto(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_beresp_proto(const struct sess *, const cha");
vsb_cat(sb, "r *, ...);\nvoid VRT_l_beresp_saintmode(const struct s");
vsb_cat(sb, "ess *, double);\nint VRT_r_beresp_status(const struct ");
vsb_cat(sb, "sess *);\nvoid VRT_l_beresp_status(const struct sess *");
vsb_cat(sb, ", int);\nconst char * VRT_r_beresp_response(const stru");
vsb_cat(sb, "ct sess *);\nvoid VRT_l_beresp_response(const struct s");
vsb_cat(sb, "ess *, const char *, ...);\nunsigned VRT_r_beresp_cach");
vsb_cat(sb, "eable(const struct sess *);\nvoid VRT_l_beresp_cacheab");
vsb_cat(sb, "le(const struct sess *, unsigned);\n");
vsb_cat(sb, "double VRT_r_beresp_ttl(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_beresp_ttl(const struct sess *, double);\n");
vsb_cat(sb, "double VRT_r_beresp_grace(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_beresp_grace(const struct sess *, double);\n");
vsb_cat(sb, "const char * VRT_r_obj_proto(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_proto(const struct sess *, const char *");
vsb_cat(sb, ", ...);\nint VRT_r_obj_status(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_status(const struct sess *, int);\n");
vsb_cat(sb, "const char * VRT_r_obj_response(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_response(const struct sess *, const cha");
vsb_cat(sb, "r *, ...);\nint VRT_r_obj_hits(const struct sess *);\n");
vsb_cat(sb, "unsigned VRT_r_obj_cacheable(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_cacheable(const struct sess *, unsigned");
vsb_cat(sb, ");\ndouble VRT_r_obj_ttl(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_ttl(const struct sess *, double);\n");
vsb_cat(sb, "double VRT_r_obj_grace(const struct sess *);\n");
vsb_cat(sb, "void VRT_l_obj_grace(const struct sess *, double);\n");
......
......@@ -174,6 +174,18 @@ set spobj {
"const struct sess *"
}
{ req.hash_ignore_busy BOOL
RW
{ recv }
"struct sess *"
}
{ req.hash_always_miss BOOL
RW
{ recv }
"struct sess *"
}
#######################################################################
# Request sent to backend
{ bereq.request STRING
......
......@@ -135,6 +135,18 @@ struct var vcc_vars[] = {
| VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER
| VCL_MET_ERROR
},
{ "req.hash_ignore_busy", BOOL, 20,
"VRT_r_req_hash_ignore_busy(sp)",
"VRT_l_req_hash_ignore_busy(sp, ",
V_RW, 0,
VCL_MET_RECV
},
{ "req.hash_always_miss", BOOL, 20,
"VRT_r_req_hash_always_miss(sp)",
"VRT_l_req_hash_always_miss(sp, ",
V_RW, 0,
VCL_MET_RECV
},
{ "bereq.request", STRING, 13,
"VRT_r_bereq_request(sp)",
"VRT_l_bereq_request(sp, ",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment