Commit 54154417 authored by Nils Goroll's avatar Nils Goroll

add .cluster_selected method

parent 5c0551b8
...@@ -27,13 +27,14 @@ AM_VTC_LOG_FLAGS = \ ...@@ -27,13 +27,14 @@ AM_VTC_LOG_FLAGS = \
-p vmod_path="$(abs_builddir)/.libs:$(vmoddir)" -p vmod_path="$(abs_builddir)/.libs:$(vmoddir)"
TESTS = \ TESTS = \
vtc/cfg.vtc \ vtc/cfg.vtc \
vtc/cld.vtc \ vtc/cld.vtc \
vtc/deep.vtc \ vtc/cluster_selected.vtc \
vtc/deep_stk.vtc \ vtc/deep.vtc \
vtc/direct.vtc \ vtc/deep_stk.vtc \
vtc/shallow.vtc \ vtc/direct.vtc \
vtc/lazy.vtc \ vtc/shallow.vtc \
vtc/lazy.vtc \
vtc/lazy_shard.vtc vtc/lazy_shard.vtc
# Documentation # Documentation
......
...@@ -507,8 +507,8 @@ vmod_cluster_resolve(VRT_CTX, VCL_BACKEND dir) ...@@ -507,8 +507,8 @@ vmod_cluster_resolve(VRT_CTX, VCL_BACKEND dir)
static VCL_BACKEND static VCL_BACKEND
cluster_choose(VRT_CTX, cluster_choose(VRT_CTX,
struct vmod_cluster_cluster *vc, struct vmod_cluster_cluster *vc,
enum resolve_e resolve, enum resolve_e resolve, enum decision_e *decision,
struct VARGS(cluster_backend) *arg) struct VARGS(cluster_cluster_selected) *arg)
{ {
int modify = arg->valid_deny || arg->valid_real || int modify = arg->valid_deny || arg->valid_real ||
arg->valid_uncacheable_direct; arg->valid_uncacheable_direct;
...@@ -517,11 +517,14 @@ cluster_choose(VRT_CTX, ...@@ -517,11 +517,14 @@ cluster_choose(VRT_CTX,
void *spc = NULL; void *spc = NULL;
int nblack; int nblack;
if (decision != NULL)
*decision = D_NULL;
if (! modify) { if (! modify) {
if (resolve == LAZY) if (resolve == LAZY)
return (vc->dir); return (vc->dir);
pr = cluster_task_param_r(ctx, vc); pr = cluster_task_param_r(ctx, vc);
return (decide(ctx, pr, resolve, NULL)); return (decide(ctx, pr, resolve, decision));
} }
AN(modify); AN(modify);
...@@ -565,7 +568,7 @@ cluster_choose(VRT_CTX, ...@@ -565,7 +568,7 @@ cluster_choose(VRT_CTX,
if (resolve == LAZY) if (resolve == LAZY)
return (vc->dir); return (vc->dir);
return (decide(ctx, pr, resolve, NULL)); return (decide(ctx, pr, resolve, decision));
} }
VCL_BACKEND VCL_BACKEND
...@@ -573,9 +576,42 @@ vmod_cluster_backend(VRT_CTX, ...@@ -573,9 +576,42 @@ vmod_cluster_backend(VRT_CTX,
struct vmod_cluster_cluster *vc, struct vmod_cluster_cluster *vc,
struct VARGS(cluster_backend) *arg) struct VARGS(cluster_backend) *arg)
{ {
return (cluster_choose(ctx, vc, parse_resolve_e(arg->resolve), arg)); struct VARGS(cluster_cluster_selected)
carg[1] = {{
.valid_deny = arg->valid_deny,
.valid_real = arg->valid_real,
.valid_uncacheable_direct = arg->valid_uncacheable_direct,
.deny = arg->deny,
.real = arg->real,
.uncacheable_direct = arg->uncacheable_direct
}};
return (cluster_choose(ctx, vc, parse_resolve_e(arg->resolve), NULL, carg));
} }
VCL_BOOL
vmod_cluster_cluster_selected(VRT_CTX,
struct VPFX(cluster_cluster) *vc,
struct VARGS(cluster_cluster_selected) *arg)
{
enum decision_e decision;
VCL_BACKEND b;
if (ctx->method != VCL_MET_BACKEND_FETCH) {
VRT_fail(ctx,
"cluster.cluster_selected can not be called here");
return (0);
}
b = cluster_choose(ctx, vc, CLD, &decision, arg);
if (decision == D_NULL || b == NULL)
return (0);
assert(b != vc->dir);
VRT_l_bereq_backend(ctx, b);
return (decision == D_CLUSTER);
}
/* /*
* layered directors may not be prepared to resolve outside a VCL task, so when * layered directors may not be prepared to resolve outside a VCL task, so when
* called from the cli (no method, no vcl), just return healthy if either the * called from the cli (no method, no vcl), just return healthy if either the
......
...@@ -225,6 +225,31 @@ differently depending on context: ...@@ -225,6 +225,31 @@ differently depending on context:
Also, they cannot be used together with ``resolve=LAZY``. Also, they cannot be used together with ``resolve=LAZY``.
$Method BOOL .cluster_selected(
[ BACKEND deny ], [ BACKEND real ],
[ BOOL uncacheable_direct ])
The indended use case is::
if (xcluster.cluster_selected(...) {
# prep the cluster request
return (fetch);
}
which is almost identical to::
set bereq.backend = xcluster.backend(resolve=CLD, ...);
if (bereq.backend != xcluster.get_real()) {
# prep the cluster request
return (fetch);
}
Behaviour differs for the case that the ``NULL`` backend would be set,
in which case ``bereq.backend`` is not modified;
This method may only be called from ``vcl_backend_fetch {}`` and fail
the vcl otherwise.
SEE ALSO SEE ALSO
======== ========
vcl\(7),varnishd\(1) vcl\(7),varnishd\(1)
varnishtest "test .cluster_selected"
varnish v1 -vcl {
import cluster;
import directors;
backend s1 { .host = "${bad_backend}";}
backend s2 { .host = "${bad_backend}";}
backend s3 { .host = "${bad_backend}";}
sub vcl_init {
new rr = directors.round_robin();
rr.add_backend(s1);
rr.add_backend(s2);
new real = directors.round_robin();
real.add_backend(s3);
new cl = cluster.cluster(rr.backend(), deny=s2, real=real.backend());
}
sub vcl_backend_fetch {
set bereq.http.c1 = cl.cluster_selected();
set bereq.http.b1 = bereq.backend;
set bereq.http.c2 = cl.cluster_selected();
set bereq.http.b2 = bereq.backend;
}
sub vcl_backend_error {
set beresp.status = 200;
set beresp.http.c1 = bereq.http.c1;
set beresp.http.b1 = bereq.http.b1;
set beresp.http.c2 = bereq.http.c2;
set beresp.http.b2 = bereq.http.b2;
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.c1 == true
expect resp.http.b1 == s1
expect resp.http.c2 == false
expect resp.http.b2 == real
} -run
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