[master] db5fd14 Add the management process logic for handling VCL state.
Poul-Henning Kamp
phk at FreeBSD.org
Mon Mar 9 10:29:33 CET 2015
commit db5fd145c1fab360929cf5dec6133e5aed52af80
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Mar 9 08:42:58 2015 +0000
Add the management process logic for handling VCL state.
diff --git a/bin/varnishd/mgt/mgt_vcl.c b/bin/varnishd/mgt/mgt_vcl.c
index 8de6583..0c8dc08 100644
--- a/bin/varnishd/mgt/mgt_vcl.c
+++ b/bin/varnishd/mgt/mgt_vcl.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * VCL compiler stuff
+ * VCL management stuff
*/
#include "config.h"
@@ -39,11 +39,14 @@
#include <sys/stat.h>
#include "mgt/mgt.h"
+#include "common/params.h"
#include "vcl.h"
#include "vcli.h"
#include "vcli_priv.h"
+#include "vev.h"
#include "vfil.h"
+#include "vtim.h"
#include "mgt_cli.h"
@@ -52,7 +55,9 @@ struct vclprog {
char *name;
char *fname;
int active;
+ int warm;
char state[8];
+ double go_cold;
};
static VTAILQ_HEAD(, vclprog) vclhead = VTAILQ_HEAD_INITIALIZER(vclhead);
@@ -60,8 +65,8 @@ static VTAILQ_HEAD(, vclprog) vclhead = VTAILQ_HEAD_INITIALIZER(vclhead);
/*--------------------------------------------------------------------*/
-static void
-mgt_vcc_add(const char *name, const char *libfile, const char *state)
+static struct vclprog *
+mgt_vcl_add(const char *name, const char *libfile, const char *state)
{
struct vclprog *vp;
@@ -69,14 +74,21 @@ mgt_vcc_add(const char *name, const char *libfile, const char *state)
XXXAN(vp);
REPLACE(vp->name, name);
REPLACE(vp->fname, libfile);
+ if (strcmp(state, "cold"))
+ vp->warm = 1;
+ else
+ state = "auto";
+
bprintf(vp->state, "%s", state);
+
if (VTAILQ_EMPTY(&vclhead))
vp->active = 1;
VTAILQ_INSERT_TAIL(&vclhead, vp, list);
+ return (vp);
}
static void
-mgt_vcc_del(struct vclprog *vp)
+mgt_vcl_del(struct vclprog *vp)
{
VTAILQ_REMOVE(&vclhead, vp, list);
printf("unlink %s\n", vp->fname);
@@ -87,7 +99,7 @@ mgt_vcc_del(struct vclprog *vp)
}
static struct vclprog *
-mgt_vcc_byname(const char *name)
+mgt_vcl_byname(const char *name)
{
struct vclprog *vp;
@@ -99,13 +111,13 @@ mgt_vcc_byname(const char *name)
static int
-mgt_vcc_delbyname(const char *name)
+mgt_vcl_delbyname(const char *name)
{
struct vclprog *vp;
- vp = mgt_vcc_byname(name);
+ vp = mgt_vcl_byname(name);
if (vp != NULL) {
- mgt_vcc_del(vp);
+ mgt_vcl_del(vp);
return (0);
}
return (1);
@@ -118,6 +130,29 @@ mgt_has_vcl(void)
return (!VTAILQ_EMPTY(&vclhead));
}
+static void
+mgt_vcl_setstate(struct vclprog *vp, int warm)
+{
+ unsigned status;
+ char *p;
+
+ if (vp->warm == warm)
+ return;
+
+ vp->warm = warm;
+
+ if (vp->warm == 0)
+ vp->go_cold = 0;
+
+ if (child_pid < 0)
+ return;
+
+ AZ(mgt_cli_askchild(&status, &p, "vcl.state %s %d%s\n",
+ vp->name, vp->warm, vp->state));
+
+ free(p);
+}
+
/*--------------------------------------------------------------------*/
static void
@@ -126,6 +161,7 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc,
{
unsigned status;
char *lib, *p;
+ struct vclprog *vp;
AN(cli);
@@ -143,27 +179,22 @@ mgt_new_vcl(struct cli *cli, const char *vclname, const char *vclsrc,
if (lib == NULL)
return;
- VCLI_Out(cli, "VCL compiled.\n");
+ vp = mgt_vcl_add(vclname, lib, state);
+ free(lib);
- if (child_pid < 0) {
- mgt_vcc_add(vclname, lib, state);
- free(lib);
+ if (child_pid < 0)
return;
- }
- if (!mgt_cli_askchild(&status, &p,
- "vcl.load %s %s %s\n", vclname, lib, state)) {
- mgt_vcc_add(vclname, lib, state);
- free(lib);
+ if (!mgt_cli_askchild(&status, &p, "vcl.load %s %s %d%s\n",
+ vp->name, vp->fname, vp->warm, vp->state)) {
free(p);
return;
}
+ mgt_vcl_del(vp);
VCLI_Out(cli, "%s", p);
free(p);
VCLI_SetResult(cli, CLIS_PARAM);
- (void)unlink(lib);
- free(lib);
}
/*--------------------------------------------------------------------*/
@@ -198,7 +229,8 @@ mgt_push_vcls_and_start(unsigned *status, char **p)
VTAILQ_FOREACH(vp, &vclhead, list) {
if (mgt_cli_askchild(status, p,
- "vcl.load \"%s\" %s %s\n", vp->name, vp->fname, vp->state))
+ "vcl.load \"%s\" %s %d%s\n",
+ vp->name, vp->fname, vp->warm, vp->state))
return (1);
free(*p);
if (!vp->active)
@@ -217,31 +249,6 @@ mgt_push_vcls_and_start(unsigned *status, char **p)
/*--------------------------------------------------------------------*/
-static void
-mgt_vcl_atexit(void)
-{
- struct vclprog *vp;
-
- if (getpid() != mgt_pid)
- return;
- while (1) {
- vp = VTAILQ_FIRST(&vclhead);
- if (vp == NULL)
- break;
- (void)unlink(vp->fname);
- VTAILQ_REMOVE(&vclhead, vp, list);
- }
-}
-
-void
-mgt_vcl_init(void)
-{
-
- AZ(atexit(mgt_vcl_atexit));
-}
-
-/*--------------------------------------------------------------------*/
-
void
mcf_vcl_inline(struct cli *cli, const char * const *av, void *priv)
{
@@ -249,7 +256,7 @@ mcf_vcl_inline(struct cli *cli, const char * const *av, void *priv)
(void)priv;
- vp = mgt_vcc_byname(av[2]);
+ vp = mgt_vcl_byname(av[2]);
if (vp != NULL) {
VCLI_Out(cli, "Already a VCL program named %s", av[2]);
VCLI_SetResult(cli, CLIS_PARAM);
@@ -266,7 +273,7 @@ mcf_vcl_load(struct cli *cli, const char * const *av, void *priv)
struct vclprog *vp;
(void)priv;
- vp = mgt_vcc_byname(av[2]);
+ vp = mgt_vcl_byname(av[2]);
if (vp != NULL) {
VCLI_Out(cli, "Already a VCL program named %s", av[2]);
VCLI_SetResult(cli, CLIS_PARAM);
@@ -289,7 +296,7 @@ mcf_find_vcl(struct cli *cli, const char *name)
{
struct vclprog *vp;
- vp = mgt_vcc_byname(name);
+ vp = mgt_vcl_byname(name);
if (vp != NULL)
return (vp);
VCLI_SetResult(cli, CLIS_PARAM);
@@ -319,8 +326,10 @@ mcf_vcl_state(struct cli *cli, const char * const *av, void *priv)
return;
}
bprintf(vp->state, "%s", "auto");
+ mgt_vcl_setstate(vp, 0);
} else if (!strcmp(av[3], "warm")) {
bprintf(vp->state, "%s", av[3]);
+ mgt_vcl_setstate(vp, 1);
} else {
VCLI_Out(cli, "State must be one of auto, cold or warm.");
VCLI_SetResult(cli, CLIS_PARAM);
@@ -332,7 +341,7 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv)
{
unsigned status;
char *p = NULL;
- struct vclprog *vp;
+ struct vclprog *vp, *vp2;
(void)priv;
vp = mcf_find_vcl(cli, av[2]);
@@ -340,19 +349,21 @@ mcf_vcl_use(struct cli *cli, const char * const *av, void *priv)
return;
if (vp->active != 0)
return;
+ mgt_vcl_setstate(vp, 1);
if (child_pid >= 0 &&
mgt_cli_askchild(&status, &p, "vcl.use %s\n", av[2])) {
VCLI_SetResult(cli, status);
VCLI_Out(cli, "%s", p);
} else {
VCLI_Out(cli, "VCL '%s' now active", av[2]);
- vp->active = 2;
- VTAILQ_FOREACH(vp, &vclhead, list) {
- if (vp->active == 1)
- vp->active = 0;
- else if (vp->active == 2)
- vp->active = 1;
+ VTAILQ_FOREACH(vp2, &vclhead, list) {
+ if (vp2->active) {
+ vp2->active = 0;
+ vp2->go_cold = VTIM_mono();
+ break;
+ }
}
+ vp->active = 1;
}
free(p);
}
@@ -376,7 +387,7 @@ mcf_vcl_discard(struct cli *cli, const char * const *av, void *priv)
VCLI_SetResult(cli, status);
VCLI_Out(cli, "%s", p);
} else {
- AZ(mgt_vcc_delbyname(av[2]));
+ AZ(mgt_vcl_delbyname(av[2]));
}
}
free(p);
@@ -404,8 +415,62 @@ mcf_vcl_list(struct cli *cli, const char * const *av, void *priv)
flg = "active";
} else
flg = "available";
- VCLI_Out(cli, "%-10s %4s/? %6s %s\n",
- flg, vp->state, "N/A", vp->name);
+ VCLI_Out(cli, "%-10s %4s/%s %s\n", flg, vp->state,
+ vp->warm ? "warm" : "cold", vp->name);
}
}
}
+
+/*--------------------------------------------------------------------*/
+
+static int __match_proto__(vev_cb_f)
+mgt_vcl_poker(const struct vev *e, int what)
+{
+ struct vclprog *vp;
+ double now = VTIM_mono();
+
+ (void)e;
+ (void)what;
+ VTAILQ_FOREACH(vp, &vclhead, list) {
+ if (vp->go_cold == 0)
+ continue;
+ if (strcmp(vp->state, "auto"))
+ continue;
+ if (vp->go_cold + mgt_param.vcl_cooldown < now)
+ mgt_vcl_setstate(vp, 0);
+ }
+ return (0);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+mgt_vcl_atexit(void)
+{
+ struct vclprog *vp;
+
+ if (getpid() != mgt_pid)
+ return;
+ while (1) {
+ vp = VTAILQ_FIRST(&vclhead);
+ if (vp == NULL)
+ break;
+ (void)unlink(vp->fname);
+ VTAILQ_REMOVE(&vclhead, vp, list);
+ }
+}
+
+void
+mgt_vcl_init(void)
+{
+ struct vev *e;
+
+ e = vev_new();
+ AN(e);
+ e->timeout = 23; // random, prime
+ e->callback = mgt_vcl_poker;
+ e->name = "vcl poker";
+ AZ(vev_add(mgt_evb, e));
+
+ AZ(atexit(mgt_vcl_atexit));
+}
More information about the varnish-commit
mailing list