Commit 54154417 authored by Nils Goroll's avatar Nils Goroll

add .cluster_selected method

parent 5c0551b8
......@@ -27,13 +27,14 @@ AM_VTC_LOG_FLAGS = \
-p vmod_path="$(abs_builddir)/.libs:$(vmoddir)"
TESTS = \
vtc/cfg.vtc \
vtc/cld.vtc \
vtc/deep.vtc \
vtc/deep_stk.vtc \
vtc/direct.vtc \
vtc/shallow.vtc \
vtc/lazy.vtc \
vtc/cfg.vtc \
vtc/cld.vtc \
vtc/cluster_selected.vtc \
vtc/deep.vtc \
vtc/deep_stk.vtc \
vtc/direct.vtc \
vtc/shallow.vtc \
vtc/lazy.vtc \
vtc/lazy_shard.vtc
# Documentation
......
......@@ -507,8 +507,8 @@ vmod_cluster_resolve(VRT_CTX, VCL_BACKEND dir)
static VCL_BACKEND
cluster_choose(VRT_CTX,
struct vmod_cluster_cluster *vc,
enum resolve_e resolve,
struct VARGS(cluster_backend) *arg)
enum resolve_e resolve, enum decision_e *decision,
struct VARGS(cluster_cluster_selected) *arg)
{
int modify = arg->valid_deny || arg->valid_real ||
arg->valid_uncacheable_direct;
......@@ -517,11 +517,14 @@ cluster_choose(VRT_CTX,
void *spc = NULL;
int nblack;
if (decision != NULL)
*decision = D_NULL;
if (! modify) {
if (resolve == LAZY)
return (vc->dir);
pr = cluster_task_param_r(ctx, vc);
return (decide(ctx, pr, resolve, NULL));
return (decide(ctx, pr, resolve, decision));
}
AN(modify);
......@@ -565,7 +568,7 @@ cluster_choose(VRT_CTX,
if (resolve == LAZY)
return (vc->dir);
return (decide(ctx, pr, resolve, NULL));
return (decide(ctx, pr, resolve, decision));
}
VCL_BACKEND
......@@ -573,9 +576,42 @@ vmod_cluster_backend(VRT_CTX,
struct vmod_cluster_cluster *vc,
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
* called from the cli (no method, no vcl), just return healthy if either the
......
......@@ -225,6 +225,31 @@ differently depending on context:
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
========
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