[master] e053076 Reintroduce PRIV_REQ as PRIV_TASK. PRIV_TASK is available (as separate priv pointers) both in the client side and the backend side VCL functions.
Dag Haavi Finstad
daghf at varnish-software.com
Thu Nov 27 17:00:39 CET 2014
commit e05307691ecc34b786ac235c4e407597d94f4514
Author: Dag Haavi Finstad <daghf at varnish-software.com>
Date: Tue Nov 25 14:40:13 2014 +0100
Reintroduce PRIV_REQ as PRIV_TASK. PRIV_TASK is available (as separate priv pointers) both in the client side and the backend side VCL functions.
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index d69b4bd..5ad4519 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -525,6 +525,7 @@ struct busyobj {
struct vsb *synth_body;
uint8_t digest[DIGEST_LEN];
+ struct vrt_privs privs[1];
};
diff --git a/bin/varnishd/cache/cache_busyobj.c b/bin/varnishd/cache/cache_busyobj.c
index ad31e11..16c67f2 100644
--- a/bin/varnishd/cache/cache_busyobj.c
+++ b/bin/varnishd/cache/cache_busyobj.c
@@ -154,6 +154,8 @@ VBO_GetBusyObj(struct worker *wrk, const struct req *req)
memcpy(bo->digest, req->digest, sizeof bo->digest);
+ VRTPRIV_init(bo->privs);
+
return (bo);
}
@@ -190,6 +192,9 @@ VBO_DerefBusyObj(struct worker *wrk, struct busyobj **pbo)
AZ(bo->htc);
+ VRTPRIV_dynamic_kill(bo->privs, (uintptr_t)bo);
+ assert(VTAILQ_EMPTY(&bo->privs->privs));
+
VSLb(bo->vsl, SLT_BereqAcct, "%ju %ju %ju %ju %ju %ju",
(uintmax_t)bo->acct.bereq_hdrbytes,
(uintmax_t)bo->acct.bereq_bodybytes,
diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c
index 3e6e9d3..39df537 100644
--- a/bin/varnishd/cache/cache_esi_deliver.c
+++ b/bin/varnishd/cache/cache_esi_deliver.c
@@ -147,6 +147,7 @@ ved_include(struct req *preq, const char *src, const char *host)
(void)usleep(10000);
}
+ VRTPRIV_dynamic_kill(req->sp->privs, (uintptr_t)req);
CNT_AcctLogCharge(wrk->stats, req);
VSL_End(req->vsl);
diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c
index 1819364..a0a5185 100644
--- a/bin/varnishd/cache/cache_vrt_priv.c
+++ b/bin/varnishd/cache/cache_vrt_priv.c
@@ -63,14 +63,20 @@ VRTPRIV_init(struct vrt_privs *privs)
static struct vmod_priv *
VRT_priv_dynamic(VRT_CTX, uintptr_t id, uintptr_t vmod_id)
{
+ struct vrt_privs *vps;
struct vrt_priv *vp;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
- CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
- CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC);
- CHECK_OBJ_NOTNULL(ctx->req->sp->privs, VRT_PRIVS_MAGIC);
+ if (ctx->req) {
+ CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
+ CHECK_OBJ_NOTNULL(ctx->req->sp, SESS_MAGIC);
+ CAST_OBJ_NOTNULL(vps, ctx->req->sp->privs, VRT_PRIVS_MAGIC);
+ } else {
+ CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
+ CAST_OBJ_NOTNULL(vps, ctx->bo->privs, VRT_PRIVS_MAGIC);
+ }
- VTAILQ_FOREACH(vp, &ctx->req->sp->privs->privs, list) {
+ VTAILQ_FOREACH(vp, &vps->privs, list) {
CHECK_OBJ_NOTNULL(vp, VRT_PRIV_MAGIC);
if (vp->vcl == ctx->vcl && vp->id == id
&& vp->vmod_id == vmod_id)
@@ -81,7 +87,7 @@ VRT_priv_dynamic(VRT_CTX, uintptr_t id, uintptr_t vmod_id)
vp->vcl = ctx->vcl;
vp->id = id;
vp->vmod_id = vmod_id;
- VTAILQ_INSERT_TAIL(&ctx->req->sp->privs->privs, vp, list);
+ VTAILQ_INSERT_TAIL(&vps->privs, vp, list);
return (vp->priv);
}
@@ -103,9 +109,19 @@ VRTPRIV_dynamic_kill(struct vrt_privs *privs, uintptr_t id)
}
struct vmod_priv *
-VRT_priv_req(VRT_CTX, void *vmod_id)
+VRT_priv_task(VRT_CTX, void *vmod_id)
{
- return (VRT_priv_dynamic(ctx, (uintptr_t)ctx->req, (uintptr_t)vmod_id));
+ uintptr_t id;
+
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ if (ctx->req) {
+ CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
+ id = (uintptr_t)ctx->req;
+ } else {
+ CHECK_OBJ_NOTNULL(ctx->bo, BUSYOBJ_MAGIC);
+ id = (uintptr_t)ctx->bo;
+ }
+ return (VRT_priv_dynamic(ctx, id, (uintptr_t)vmod_id));
}
/*--------------------------------------------------------------------
diff --git a/bin/varnishtest/tests/r01038.vtc b/bin/varnishtest/tests/r01038.vtc
index bb57072..705e11c 100644
--- a/bin/varnishtest/tests/r01038.vtc
+++ b/bin/varnishtest/tests/r01038.vtc
@@ -45,7 +45,7 @@ server s1 {
txresp -body "foo8"
} -start
-varnish v1 -arg "-p workspace_backend=9k" -vcl+backend {
+varnish v1 -arg "-p workspace_backend=10k" -vcl+backend {
sub vcl_backend_response {
set beresp.do_esi = true;
}
diff --git a/bin/varnishtest/tests/v00041.vtc b/bin/varnishtest/tests/v00041.vtc
index 2be9f8a..9604eb2 100644
--- a/bin/varnishtest/tests/v00041.vtc
+++ b/bin/varnishtest/tests/v00041.vtc
@@ -1,4 +1,4 @@
-varnishtest "Test priv_req"
+varnishtest "Test priv_task"
server s1 {
rxreq
@@ -9,14 +9,26 @@ server s1 {
varnish v1 -vcl+backend {
import ${vmod_debug};
+ import ${vmod_std};
sub vcl_recv {
- set req.http.x0 = debug.test_priv_req(req.url);
+ set req.http.x0 = debug.test_priv_task(req.url);
}
sub vcl_deliver {
set resp.http.x0 = req.http.x0;
- set resp.http.x1 = debug.test_priv_req("");
+ set resp.http.x1 = debug.test_priv_task("");
+ }
+
+ sub vcl_backend_fetch {
+ std.log("foo");
+ set bereq.http.bx0 = debug.test_priv_task(bereq.url);
+ std.log("bar");
+ }
+
+ sub vcl_backend_response {
+ set beresp.http.bx0 = bereq.http.bx0;
+ set beresp.http.bx1 = debug.test_priv_task("");
}
} -start
@@ -26,9 +38,13 @@ client c1 {
rxresp
expect resp.http.x0 == /foobar
expect resp.http.x1 == /foobar
+ expect resp.http.bx0 == /foobar
+ expect resp.http.bx1 == /foobar
txreq -url /snafu
rxresp
expect resp.http.x0 == /snafu
expect resp.http.x1 == /snafu
+ expect resp.http.bx0 == /snafu
+ expect resp.http.bx1 == /snafu
} -run
diff --git a/bin/varnishtest/tests/v00042.vtc b/bin/varnishtest/tests/v00042.vtc
new file mode 100644
index 0000000..1640f56
--- /dev/null
+++ b/bin/varnishtest/tests/v00042.vtc
@@ -0,0 +1,68 @@
+varnishtest "Make sure we also get separate PRIV_TASK contexts in ESI subrequests."
+
+server s1 {
+ rxreq
+ expect req.url == "/a"
+ expect req.http.x0 == "/a0"
+ expect req.http.x1 == "/a0"
+ txresp -body {
+ <html>
+ <esi:include src="/foo"/>
+ }
+
+ rxreq
+ expect req.url == "/foo"
+ expect req.http.x0 == "/foo1"
+ expect req.http.x1 == "/foo1"
+ txresp -body {
+ <html>
+ <esi:include src="/bar"/>
+ }
+
+ rxreq
+ expect req.url == "/bar"
+ expect req.http.x0 == "/bar2"
+ expect req.http.x1 == "/bar2"
+ txresp
+
+ rxreq
+ expect req.url == "/b"
+ expect req.http.x0 == "/b0"
+ expect req.http.x1 == "/b0"
+
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ import ${vmod_debug};
+
+ sub vcl_recv {
+ set req.http.x0 = debug.test_priv_task(req.url + req.esi_level);
+ }
+
+ sub vcl_miss {
+ set req.http.x1 = debug.test_priv_task("");
+ }
+
+ sub vcl_backend_response {
+ set beresp.do_esi = true;
+
+ }
+
+ sub vcl_deliver {
+ set resp.http.x1 = debug.test_priv_task("");
+ }
+} -start
+
+
+client c1 {
+ txreq -url /a
+ rxresp
+ expect resp.http.x1 == "/a0"
+
+ txreq -url /b
+ rxresp
+ expect resp.http.x1 == "/b0"
+} -run
+
+varnish v1 -expect s_req == 2
diff --git a/doc/sphinx/reference/vmod.rst b/doc/sphinx/reference/vmod.rst
index 5ad685f..70f287e 100644
--- a/doc/sphinx/reference/vmod.rst
+++ b/doc/sphinx/reference/vmod.rst
@@ -194,6 +194,9 @@ PRIV_VCL
PRIV_CALL
See below
+PRIV_TASK
+ See below
+
VOID
C-type: ``void``
@@ -231,8 +234,8 @@ It is often useful for library functions to maintain local state,
this can be anything from a precompiled regexp to open file descriptors
and vast data structures.
-The VCL compiler supports two levels of private pointers, "per call"
-and "per VCL"
+The VCL compiler supports three levels of private pointers, "per
+call", "per VCL" and "per task".
"per call" private pointers are useful to cache/store state relative
to the specific call or its arguments, for instance a compiled regular
@@ -243,9 +246,16 @@ last output of some expensive lookup.
applies to all calls in this VCL, for instance flags that determine
if regular expressions are case-sensitive in this vmod or similar.
+"per task" private pointers are useful for state that applies to calls
+for either a specific request or a backend request. For instance this
+can be the result of a parsed cookie specific to a client. Note that
+"per task" contexts are separate for the client side and the backend
+side, so use in ``vcl_backend_*`` will yield a different private pointer
+from the one used on the client side.
+
The way it works in the vmod code, is that a ``struct vmod_priv *`` is
-passed to the functions where argument type PRIV_VCL or PRIV_CALL
-is specified.
+passed to the functions where argument type PRIV_VCL, PRIV_CALL or
+PRIV_TASK is specified.
This structure contains two members::
diff --git a/include/vrt.h b/include/vrt.h
index 78cf479..9331600 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -246,7 +246,7 @@ struct vmod_priv {
typedef int vmod_init_f(struct vmod_priv *, const struct VCL_conf *);
void VRT_priv_fini(const struct vmod_priv *p);
-struct vmod_priv *VRT_priv_req(VRT_CTX, void *vmod_id);
+struct vmod_priv *VRT_priv_task(VRT_CTX, void *vmod_id);
/* Stevedore related functions */
int VRT_Stv(const char *nm);
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 72d8386..91c6a06 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -551,11 +551,11 @@ vcc_priv_arg(struct vcc *tl, const char *p, const char *name)
Fh(tl, 0, "static struct vmod_priv %s;\n", buf);
VSB_printf(ifp->fin, "\tVRT_priv_fini(&%s);", buf);
e2 = vcc_mk_expr(VOID, "&%s", buf);
- } else if (!strcmp(p, "PRIV_REQ")) {
+ } else if (!strcmp(p, "PRIV_TASK")) {
r = strchr(name, '.');
AN(r);
e2 = vcc_mk_expr(VOID,
- "VRT_priv_req(ctx, &VGC_vmod_%.*s)",
+ "VRT_priv_task(ctx, &VGC_vmod_%.*s)",
(int) (r - name), name);
} else {
WRONG("Wrong PRIV_ type");
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index ef6ea2c..1501e31 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -58,7 +58,7 @@ ctypes = {
'IP': "VCL_IP",
'PRIV_CALL': "struct vmod_priv *",
'PRIV_VCL': "struct vmod_priv *",
- 'PRIV_REQ': "struct vmod_priv *",
+ 'PRIV_TASK': "struct vmod_priv *",
'REAL': "VCL_REAL",
'STRING': "VCL_STRING",
'STRING_LIST': "const char *, ...",
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index 09e6c0b..1684230 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -51,9 +51,9 @@ $Function VOID test_priv_vcl(PRIV_VCL)
Test function for VCL private pointers
-$Function STRING test_priv_req(PRIV_REQ, STRING)
+$Function STRING test_priv_task(PRIV_TASK, STRING)
-Test function for REQ private pointers
+Test function for TASK private pointers
$Function BLOB str2blob(STRING src)
diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c
index d8077ce..1701444 100644
--- a/lib/libvmod_debug/vmod_debug.c
+++ b/lib/libvmod_debug/vmod_debug.c
@@ -88,8 +88,8 @@ vmod_test_priv_call(VRT_CTX, struct vmod_priv *priv)
}
}
-VCL_STRING __match_proto__(td_debug_test_priv_req)
-vmod_test_priv_req(VRT_CTX, struct vmod_priv *priv, VCL_STRING s)
+VCL_STRING __match_proto__(td_debug_test_priv_task)
+vmod_test_priv_task(VRT_CTX, struct vmod_priv *priv, VCL_STRING s)
{
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
More information about the varnish-commit
mailing list