Commit 01b70a45 authored by Geoff Simmons's avatar Geoff Simmons

Add maxwait support to pesi.

parent f73d18a8
......@@ -62,6 +62,7 @@ struct pesi {
struct pesi_tree *pesi_tree;
struct worker *wrk;
struct node *node;
double maxwait;
int woken;
struct pecx pecx[1];
......
varnishtest "pESI maxwait no timeout"
# cf e00003.vtc
server s1 {
rxreq
expect req.http.esi0 == "foo"
txresp -body {
<html>
Before include
<esi:include src="/body" maxwait="0"/>
After include
</html>
}
} -start
server s2 {
rxreq
expect req.url == "/body1"
expect req.http.esi0 != "foo"
txresp -body {
Included file
}
} -start
varnish v1 -arg "-p debug=+syncvsl" -vcl+backend {
import ${vmod_pesi};
import ${vmod_pesi_debug};
include "debug.inc.vcl";
sub vcl_recv {
if (req.esi_level > 0) {
set req.url = req.url + req.esi_level;
} else {
set req.http.esi0 = "foo";
}
}
sub vcl_backend_fetch {
if (bereq.url == "/") {
set bereq.backend = s1;
}
else {
set bereq.backend = s2;
}
}
sub vcl_backend_response {
if (bereq.url == "/") {
set beresp.do_esi = true;
}
}
sub vcl_deliver {
pesi.activate();
set resp.http.can_esi = obj.can_esi;
}
} -start
client c1 {
txreq -hdr "Host: foo"
rxresp
expect resp.bodylen == 75
expect resp.status == 200
expect resp.http.can_esi == "true"
expect resp.body == {
<html>
Before include
Included file
After include
</html>
}
delay .1
txreq -hdr "Host: foo"
rxresp
expect resp.bodylen == 75
expect resp.status == 200
expect resp.http.can_esi == "true"
expect resp.body == {
<html>
Before include
Included file
After include
</html>
}
}
client c1 -run
varnish v1 -expect esi_errors == 0
varnish v1 -expect MAIN.s_resp_bodybytes == 150
delay 1
logexpect l1 -v v1 -d 1 -g vxid -q "vxid == 1001" {
expect 0 1001 Begin "^req .* rxreq"
expect * = ReqAcct "^29 0 29 202 75 277$"
expect 0 = End
} -run
logexpect l2 -v v1 -d 1 -g vxid -q "vxid == 1002" {
expect * 1002 Begin "^bereq "
expect * = End
} -run
logexpect l3 -v v1 -d 1 -g vxid -q "vxid == 1003" {
expect * 1003 Begin "^req .* esi"
expect * = ReqAcct "^0 0 0 0 18 18$"
expect 0 = End
} -run
logexpect l4 -v v1 -d 1 -g vxid -q "vxid == 1004" {
expect * 1004 Begin "^bereq "
expect * = End
} -run
logexpect l5 -v v1 -d 1 -g vxid -q "vxid == 1005" {
expect * 1005 Begin "^req .* rxreq"
expect * = ReqAcct "^29 0 29 207 75 282$"
expect 0 = End
} -run
logexpect l6 -v v1 -d 1 -g vxid -q "vxid == 1006" {
expect * 1006 Begin "^req .* esi"
expect * = ReqAcct "^0 0 0 0 18 18$"
expect 0 = End
} -run
## HTTP/2
varnish v1 -cliok "param.set feature +http2"
client c1 {
stream 1 {
txreq -hdr host foo
rxresp
expect resp.status == 200
expect resp.bodylen == 75
expect resp.body == {
<html>
Before include
Included file
After include
</html>
}
} -run
} -run
varnishtest "pESI maxwait with timeout"
server s1 {
rxreq
txresp -body {
<html>
Before include
<esi:include src="/body" maxwait="1"/>
After include
</html>
}
rxreq
delay 1.1
txresp -body {
Included file
}
} -start
server s2 {
rxreq
delay 1.1
txresp -body {
Included file
}
} -start
varnish v1 -arg "-p max_restarts=5 -p max_retries=5"-vcl+backend {
import ${vmod_pesi};
import ${vmod_pesi_debug};
include "debug.inc.vcl";
sub vcl_backend_fetch {
if (bereq.url == "/") {
set bereq.backend = s1;
}
else {
set bereq.backend = s2;
}
}
sub vcl_backend_response {
set beresp.do_esi = true;
}
sub vcl_deliver {
pesi.activate();
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
} -run
logexpect l1 -v v1 -d 1 -q "Timestamp:Timeout" {
expect 0 * Begin bereq
expect * = BereqURL /body
expect * = Timestamp Timeout
expect 0 = FetchError "req_total_timeout elapsed"
expect * = BerespStatus 503
expect * = End
expect 0 * Begin {^req \d+ esi$}
expect * = ReqURL /body
expect * = Timestamp Timeout
expect 0 = Error "req_total_timeout elapsed"
expect * = RespStatus 503
expect * = End
} -run
server s2 -wait
server s2 {
rxreq
expect req.url == "/body"
txresp -body {
Included file
}
} -start
varnish v1 -vcl+backend {
import vtc;
import ${vmod_pesi};
import ${vmod_pesi_debug};
include "debug.inc.vcl";
sub vcl_recv {
if (req.esi_level > 0) {
vtc.sleep(1.1s);
}
}
sub vcl_backend_fetch {
if (bereq.url == "/") {
set bereq.backend = s1;
}
else {
set bereq.backend = s2;
}
}
sub vcl_backend_response {
set beresp.do_esi = true;
}
sub vcl_deliver {
pesi.activate();
}
}
logexpect l1 -v v1 -d 0 -q "Timestamp:Timeout" {
expect 0 * Begin {^req \d+ esi$}
expect * = ReqURL /body
expect * = Timestamp Timeout
expect 0 = Error "req_total_timeout elapsed"
expect * = RespStatus 503
expect * = End
} -start
client c1 -run
logexpect l1 -wait
server s2 -break
server s2 -start
varnish v1 -vcl+backend {
import vtc;
import ${vmod_pesi};
import ${vmod_pesi_debug};
include "debug.inc.vcl";
sub vcl_recv {
if (req.esi_level > 0) {
vtc.sleep(0.3s);
return (restart);
}
}
sub vcl_synth {
set resp.http.Restarts = req.restarts;
}
sub vcl_backend_fetch {
if (bereq.url == "/") {
set bereq.backend = s1;
}
else {
set bereq.backend = s2;
}
}
sub vcl_backend_response {
set beresp.do_esi = true;
}
sub vcl_deliver {
pesi.activate();
}
}
logexpect l1 -v v1 -d 0 -q "Timestamp:Timeout" {
expect 0 * Begin {^req \d+ restart$}
expect * = ReqURL /body
expect * = Timestamp Timeout
expect 0 = Error "req_total_timeout elapsed"
expect * = RespStatus 503
expect * = RespHeader {^Restarts: [34]$}
expect * = End
} -start
client c1 -run
logexpect l1 -wait
server s2 -break
server s2 {
rxreq
expect req.url == "/body"
delay 0.3
txresp -body {
Included file
}
} -start
varnish v1 -vcl+backend {
import ${vmod_pesi};
import ${vmod_pesi_debug};
include "debug.inc.vcl";
sub vcl_backend_fetch {
if (bereq.url == "/") {
set bereq.backend = s1;
}
else {
set bereq.backend = s2;
}
}
sub vcl_backend_response {
set beresp.do_esi = true;
return (retry);
}
sub vcl_backend_error {
set beresp.http.Retries = bereq.retries;
}
sub vcl_deliver {
pesi.activate();
}
}
logexpect l1 -v v1 -d 0 -q "Timestamp:Timeout" -g request {
expect * * Begin {^req \d+ esi$}
expect * = ReqURL /body
expect * = RespStatus 503
expect * = End
expect * * Begin {^bereq \d+ retry}
expect * = BereqURL /body
expect * = FetchError "req_total_timeout elapsed"
expect * = BerespStatus 503
expect * = BerespHeader {^Retries: [1-4]$}
expect * = End
} -start
client c1 -run
logexpect l1 -wait
varnishtest "ESI maxwait syntax"
server s1 {
rxreq
txresp -body {
<html>
Before include
<esi:include src="/body" maxwait="0" maxwait="1"/>
<esi:include src="/body" maxwait=""/>
<esi:include src="/body" maxwait="-1"/>
<esi:include src="/body" maxwait="foo"/>
<esi:include src="/body" maxwait="4711foo"/>
<esi:include src="/body" maxwait="4711 0815"/>
<esi:include src="/body" maxwait="NaN"/>
<esi:include src="/body" maxwait="Inf"/>
<esi:include src="/body" maxwait="-Inf"/>
After include
</html>
}
} -start
server s2 {
rxreq
delay 1.1
txresp -body {
Included file
}
} -start
varnish v1 -vcl+backend {
import ${vmod_pesi};
import ${vmod_pesi_debug};
include "debug.inc.vcl";
sub vcl_backend_fetch {
if (bereq.url == "/") {
set bereq.backend = s1;
}
else {
set bereq.backend = s2;
}
}
sub vcl_backend_response {
set beresp.do_esi = true;
}
sub vcl_deliver {
pesi.activate();
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.body == {
<html>
Before include
After include
</html>
}
} -run
logexpect l1 -v v1 -d 1 -q ESI_xmlerror {
expect 0 * Begin bereq
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has multiple maxwait= attributes"
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has an invalid maxwait= value"
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has an invalid maxwait= value"
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has an invalid maxwait= value"
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has an invalid maxwait= value"
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has an invalid maxwait= value"
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has an invalid maxwait= value"
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has an invalid maxwait= value"
expect * = ESI_xmlerror "ESI 1.0 <esi:include> has an invalid maxwait= value"
expect * = End
} -run
server s1 -break
......@@ -313,6 +313,7 @@ vped_include(struct req *preq, const char *src, const char *host,
struct req *req;
struct bytes_tree *tree;
struct pesi *pesi2;
double deadline;
VSLdbg(preq, "vped_include: enter");
CHECK_OBJ_NOTNULL(preq, REQ_MAGIC);
......@@ -389,6 +390,12 @@ vped_include(struct req *preq, const char *src, const char *host,
req->req_step = R_STP_TRANSPORT;
req->t_req = preq->t_req;
req->t_deadline = preq->t_deadline;
if (pesi->maxwait != 0.) {
deadline = VTIM_mono() + pesi->maxwait;
if (req->t_deadline <= 0. || deadline < req->t_deadline)
req->t_deadline = deadline;
}
#ifdef DEBUG
VSLdbgv(preq, "vped_include: preq->vdc=%p nxt=%p", preq->vdc,
......@@ -1022,6 +1029,12 @@ vdp_pesi_bytes(struct vdp_ctx *vdx, enum vdp_action act, void **priv,
Debug("SKIP1(%d)\n", (int)pecx->l);
pecx->state = 4;
break;
case VEC_WAIT:
pecx->p++;
memcpy(&pesi->maxwait, pecx->p, sizeof(double));
Debug("MAXWAIT [%f]\n", pesi->maxwait);
pecx->p += sizeof(double);
break;
case VEC_INCL:
pecx->p++;
q = (void*)strchr((const char*)pecx->p, '\0');
......
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