[4.1] e275141 Introduce a new "busy" VCL temperature
Lasse Karstensen
lkarsten at varnish-software.com
Thu Jan 14 15:15:08 CET 2016
commit e275141bd5dd360912a4407a7b94994ebe3ce453
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date: Fri Dec 4 22:07:14 2015 +0100
Introduce a new "busy" VCL temperature
Now that VCLs can be referenced, there are two different situations
stalling the cooldown. The "cooling" one is kept for VCLs that have
received a COLD event, and the "busy" one is introduced to wait for
ongoing transactions.
Basically, if there are transactions, the VCL is still active even
though it's not *the* active VCL and should therefore be considered
warm. This guarantees that WARM and COLD events are balanced, and
also that a "busy" VCL doesn't need to warm up if it is set to warm
again.
The new VCL temperature engine looks like this:
.----------W>---------------.
| .--W>---. v
init ---> cold --| |-- warm --.
^ ^ '---<C--' | |
| | | |
| '--- cooling <C--' |
| ^ |
| C |
| | .---<---. |
'--<C-- busy --| |--'
'--->---'
The transitions marked with a 'W' or a 'C' are the one dispatching
WARM and COLD events respectively.
Since the "busy" state is considered warm, VMODs should operate as
such and backend creation remains possible.
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index a6d0c26..664c2c1 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -50,6 +50,7 @@
static const char * const vcl_temp_init = "init";
static const char * const vcl_temp_cold = "cold";
static const char * const vcl_temp_warm = "warm";
+static const char * const vcl_temp_busy = "busy";
static const char * const vcl_temp_cooling = "cooling";
struct vcl {
@@ -164,7 +165,7 @@ VCL_Ref(struct vcl *vcl)
{
CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
- assert(vcl->temp == vcl_temp_warm || vcl->temp == vcl_temp_cooling);
+ assert(vcl->temp != vcl_temp_init && vcl->temp != vcl_temp_cold);
Lck_Lock(&vcl_mtx);
assert(vcl->busy > 0);
vcl->busy++;
@@ -207,10 +208,10 @@ VCL_AddBackend(struct vcl *vcl, struct backend *be)
VTAILQ_INSERT_TAIL(&vcl->backend_list, be, vcl_list);
Lck_Unlock(&vcl_mtx);
- if (vcl->temp == vcl_temp_warm) {
+ if (vcl->temp == vcl_temp_warm || vcl->temp == vcl_temp_busy)
/* Only when adding backend to already warm VCL */
VBE_Event(be, VCL_EVENT_WARM);
- } else if (vcl->temp != vcl_temp_init)
+ else if (vcl->temp != vcl_temp_init)
WRONG("Dynamic Backends can only be added to warm VCLs");
return (0);
@@ -400,7 +401,8 @@ VRT_rel_vcl(VRT_CTX)
vcl = ctx->vcl;
CHECK_OBJ_NOTNULL(vcl, VCL_MAGIC);
- assert(vcl->temp == vcl_temp_warm || vcl->temp == vcl_temp_cooling);
+ assert(vcl->temp == vcl_temp_warm || vcl->temp == vcl_temp_busy ||
+ vcl->temp == vcl_temp_cooling);
Lck_Lock(&vcl_mtx);
assert(vcl->refcount > 0);
@@ -430,6 +432,7 @@ static void
vcl_set_state(struct vcl *vcl, const char *state)
{
struct vrt_ctx ctx;
+ const char *target;
unsigned hand = 0;
ASSERT_CLI();
@@ -441,22 +444,29 @@ vcl_set_state(struct vcl *vcl, const char *state)
switch(state[0]) {
case '0':
- if (vcl->temp == vcl_temp_init)
- vcl->temp = vcl_temp_cold;
- if (vcl->temp == vcl_temp_cold)
- break;
- if (vcl->busy == 0 && vcl->refcount == 0) {
- vcl->temp = vcl_temp_cold;
+ assert(vcl->temp != vcl_temp_cold);
+ target = vcl->busy ? vcl_temp_busy : vcl_temp_cold;
+ if (target == vcl_temp_cold && (vcl->temp == vcl_temp_warm ||
+ vcl->temp == vcl_temp_busy)) {
+
+ vcl->temp = vcl->refcount ? vcl_temp_cooling :
+ vcl_temp_cold;
AZ(vcl->conf->event_vcl(&ctx, VCL_EVENT_COLD));
vcl_BackendEvent(vcl, VCL_EVENT_COLD);
- } else {
- vcl->temp = vcl_temp_cooling;
}
+ else if (vcl->busy)
+ vcl->temp = vcl_temp_busy;
+ else
+ vcl->temp = vcl->refcount ? vcl_temp_cooling :
+ vcl_temp_cold;
break;
case '1':
- if (vcl->temp == vcl_temp_cooling)
+ assert(vcl->temp != vcl_temp_warm);
+ /* The warm VCL hasn't seen a cold event yet */
+ if (vcl->temp == vcl_temp_busy)
vcl->temp = vcl_temp_warm;
- else {
+ /* The VCL must first reach a stable cold state */
+ else if (vcl->temp != vcl_temp_cooling) {
vcl->temp = vcl_temp_warm;
(void)vcl->conf->event_vcl(&ctx, VCL_EVENT_WARM);
vcl_BackendEvent(vcl, VCL_EVENT_WARM);
@@ -573,9 +583,10 @@ VCL_Poll(void)
ASSERT_CLI();
VTAILQ_FOREACH_SAFE(vcl, &vcl_head, list, vcl2) {
- if (vcl->temp == vcl_temp_cooling)
+ if (vcl->temp == vcl_temp_busy ||
+ vcl->temp == vcl_temp_cooling)
vcl_set_state(vcl, "0");
- if (vcl->discard && vcl->busy == 0 && vcl->refcount == 0)
+ if (vcl->discard && vcl->temp == vcl_temp_cold)
VCL_Nuke(vcl);
}
}
More information about the varnish-commit
mailing list