]> err.no Git - varnish/commitdiff
Fix an architectural mistake:
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 10 Aug 2007 09:51:16 +0000 (09:51 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Fri, 10 Aug 2007 09:51:16 +0000 (09:51 +0000)
What the compiled VCL code contains is not "a backend" but more
like a specification of or a template of a backend.

This matters because it controls the ownership of the backend
structure, and to a lesser degree because it complicates the VRT
api with a lot of pointless functions.

When vcl.use switches to a different VCL program, the backends of
the old VCL program may still be in use, and, provided the backend
declarations of the two VCL programs are identical, should continue
be carried over to the new VCL code.

This requires the memory and state to be owned by the central backend
code, and the VCL programs to just hold references and becomes even
more important when we keep complex state for load balancing on
individual backends.

This commit changes the ownership of the backends to the central code,
and moves the specification used in the compiled VCL program to a
communication structure for just that.

This also paves the way for introducing directors/policies for backend
selection and for good measure, I have named the default (ie: current)
backend policy "simple" for now.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1829 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache_vrt.c
varnish-cache/include/vrt.h
varnish-cache/lib/libvcl/vcc_backend.c
varnish-cache/lib/libvcl/vcc_compile.c
varnish-cache/lib/libvcl/vcc_fixed_token.c

index d8b2d86661198994c16fe60d60d8b918ddfc161f..f3bdaed33939abddc5fa6b913d0771f3498c605c 100644 (file)
@@ -267,63 +267,6 @@ VRT_handling(struct sess *sp, unsigned hand)
        sp->handling = hand;
 }
 
-/*--------------------------------------------------------------------*/
-
-void
-VRT_set_backend_name(struct backend *be, const char *p)
-{
-       CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);
-       be->vcl_name = p;
-}
-
-void
-VRT_alloc_backends(struct VCL_conf *cp)
-{
-       int i;
-
-       cp->backend = calloc(sizeof *cp->backend, cp->nbackend);
-       XXXAN(cp->backend);
-       for (i = 0; i < cp->nbackend; i++) {
-               cp->backend[i] = calloc(sizeof *cp->backend[i], 1);
-               XXXAN(cp->backend[i]);
-               cp->backend[i]->magic = BACKEND_MAGIC;
-               cp->backend[i]->dnsttl = 30;
-               TAILQ_INIT(&cp->backend[i]->connlist);
-               cp->backend[i]->health = 0;
-               cp->backend[i]->last_check = TIM_mono();
-               cp->backend[i]->minute_limit = 1;
-       }
-}
-
-void
-VRT_free_backends(struct VCL_conf *cp)
-{
-
-       (void)cp;       /* XXX */
-}
-
-void
-VRT_fini_backend(struct backend *be)
-{
-
-       (void)be;       /* XXX */
-}
-
-/*--------------------------------------------------------------------*/
-
-#define VBACKEND(type,onm,field)                       \
-void                                                   \
-VRT_l_backend_##onm(struct backend *be, type a)                \
-{                                                      \
-       CHECK_OBJ_NOTNULL(be, BACKEND_MAGIC);           \
-       be->field = a;                                  \
-}                                                      \
-
-VBACKEND(const char *, host,   hostname)
-VBACKEND(const char *, port,   portname)
-VBACKEND(double,       dnsttl, dnsttl)
-
-
 /*--------------------------------------------------------------------
  * XXX: Working relative to t_req is maybe not the right thing, we could
  * XXX: have spent a long time talking to the backend since then.
@@ -557,3 +500,40 @@ VRT_purge(const char *regexp, int hash)
        
        AddBan(regexp, hash);
 }
+
+/*--------------------------------------------------------------------
+ * Backend stuff, should probably move to its own file eventually
+ */
+void
+VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
+{
+       struct backend *b;
+       
+       b = calloc(sizeof *b, 1);
+       XXXAN(b);
+       b->magic = BACKEND_MAGIC;
+       b->dnsttl = 300;
+       TAILQ_INIT(&b->connlist);
+       b->last_check = TIM_mono();
+       b->minute_limit = 1;
+
+       AN(t->name);
+       b->vcl_name = strdup(t->name);
+       XXXAN(b->vcl_name);
+
+       AN(t->port);
+       b->portname = strdup(t->port);
+       XXXAN(b->portname);
+
+       AN(t->host);
+       b->hostname = strdup(t->host);
+       XXXAN(b->hostname);
+
+       *bp = b;
+}
+
+void
+VRT_fini_backend(struct backend *b)
+{
+       (void)b;
+}
index 840aaf04bd1d6af839a45a108075bd4d30887347..d0049a4313a23d0eac55f00b3336aed571e7e524 100644 (file)
@@ -40,6 +40,12 @@ struct backend;
 struct VCL_conf;
 struct sockaddr;
 
+struct vrt_simple_backend {
+       const char      *name;
+       const char      *port;
+       const char      *host;
+};
+
 struct vrt_ref {
        unsigned        source;
        unsigned        offset;
@@ -83,10 +89,8 @@ void VRT_SetHdr(struct sess *, enum gethdr_e where, const char *, const char *,
 void VRT_handling(struct sess *sp, unsigned hand);
 
 /* Backend related */
-void VRT_set_backend_name(struct backend *, const char *);
-void VRT_alloc_backends(struct VCL_conf *cp);
-void VRT_free_backends(struct VCL_conf *cp);
-void VRT_fini_backend(struct backend *be);
+void VRT_init_simple_backend(struct backend **, struct vrt_simple_backend *);
+void VRT_fini_backend(struct backend *);
 
 char *VRT_IP_string(struct sess *sp, struct sockaddr *sa);
 char *VRT_int_string(struct sess *sp, int);
index 35f7ff093db76f31360bcdb7247ab1d8076d93bf..3e47024d9876bdd577d2db04c6e0ba16854bce47 100644 (file)
@@ -61,7 +61,6 @@ CheckHostPort(const char *host, const char *port)
 void
 vcc_ParseBackend(struct tokenlist *tl)
 {
-       unsigned a;
        struct var *vp;
        struct token *t_be = NULL;
        struct token *t_host = NULL;
@@ -72,17 +71,17 @@ vcc_ParseBackend(struct tokenlist *tl)
        ExpectErr(tl, ID);
        t_be = tl->t;
        vcc_AddDef(tl, tl->t, R_BACKEND);
+       /*
+        * The first backend is always referenced because that is the default
+        * at the beginning of vcl_recv
+        */
        if (tl->nbackend == 0)
                vcc_AddRef(tl, tl->t, R_BACKEND);
+
+       /* In the compiled vcl we use these macros to refer to backends */
        Fh(tl, 1, "#define VGC_backend_%.*s (VCL_conf.backend[%d])\n",
            PF(tl->t), tl->nbackend);
-       Fc(tl, 0, "\n");
-       Fc(tl, 0, "static void\n");
-       Fc(tl, 1, "VGC_init_backend_%.*s (void)\n", PF(tl->t));
-       Fc(tl, 1, "{\n");
-       Fc(tl, 1, "\tstruct backend *backend = VGC_backend_%.*s;\n", PF(tl->t));
-       Fc(tl, 1, "\n");
-       Fc(tl, 1, "\tVRT_set_backend_name(backend, \"%.*s\");\n", PF(tl->t));
+
        vcc_NextToken(tl);
        ExpectErr(tl, '{');
        vcc_NextToken(tl);
@@ -110,40 +109,13 @@ vcc_ParseBackend(struct tokenlist *tl)
                case HOSTNAME:
                        ExpectErr(tl, CSTR);
                        t_host = tl->t;
-                       Fc(tl, 1, "\t%s ", vp->lname);
-                       EncToken(tl->fc, t_host);
-                       Fc(tl, 0, ");\n");
                        vcc_NextToken(tl);
                        break;
                case PORTNAME:
                        ExpectErr(tl, CSTR);
                        t_port = tl->t;
-                       Fc(tl, 1, "\t%s ", vp->lname);
-                       EncToken(tl->fc, t_port);
-                       Fc(tl, 0, ");\n");
                        vcc_NextToken(tl);
                        break;
-#if 0
-               case INT:
-               case SIZE:
-               case RATE:
-               case FLOAT:
-#endif
-               case TIME:
-                       Fc(tl, 1, "\t%s ", vp->lname);
-                       a = tl->t->tok;
-                       if (a == T_MUL || a == T_DIV)
-                               Fc(tl, 0, "%g", vcc_DoubleVal(tl));
-                       else if (vp->fmt == TIME)
-                               vcc_TimeVal(tl);
-                       else if (vp->fmt == SIZE)
-                               vcc_SizeVal(tl);
-                       else if (vp->fmt == RATE)
-                               vcc_RateVal(tl);
-                       else
-                               Fc(tl, 0, "%g", vcc_DoubleVal(tl));
-                       Fc(tl, 0, ");\n");
-                       break;
                default:
                        vsb_printf(tl->sb,
                            "Assignments not possible for '%s'\n", vp->name);
@@ -177,9 +149,14 @@ vcc_ParseBackend(struct tokenlist *tl)
        }
 
        vcc_NextToken(tl);
-       Fc(tl, 1, "}\n");
-       Fc(tl, 0, "\n");
-       Fi(tl, 0, "\tVGC_init_backend_%.*s();\n", PF(t_be));
+       Fc(tl, 0, "\nstatic struct vrt_simple_backend sbe_%.*s = {\n",
+           PF(t_be));
+       Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(t_be));
+       Fc(tl, 0, "\t.port = %.*s,\n", PF(t_port));
+       Fc(tl, 0, "\t.host = %.*s,\n", PF(t_host));
+       Fc(tl, 0, "};\n");
+       Fi(tl, 0, "\tVRT_init_simple_backend(&VGC_backend_%.*s , &sbe_%.*s);\n",
+           PF(t_be), PF(t_be));
        Ff(tl, 0, "\tVRT_fini_backend(VGC_backend_%.*s);\n", PF(t_be));
        tl->nbackend++;
 }
index c38e2c62dbcbeb05d45706987f5356b8edf694bc..6bcbc2ed17a98f375a25fbaa293a3f9681432974 100644 (file)
@@ -338,11 +338,14 @@ EmitStruct(const struct tokenlist *tl)
        }
        Fc(tl, 0, "};\n");
 
+       Fc(tl, 0, "\nstatic struct backend\t*backends[%d];\n", tl->nbackend);
+
        Fc(tl, 0, "\nstruct VCL_conf VCL_conf = {\n");
        Fc(tl, 0, "\t.magic = VCL_CONF_MAGIC,\n");
        Fc(tl, 0, "\t.init_func = VGC_Init,\n");
        Fc(tl, 0, "\t.fini_func = VGC_Fini,\n");
        Fc(tl, 0, "\t.nbackend = %d,\n", tl->nbackend);
+       Fc(tl, 0, "\t.backend = backends,\n");
        Fc(tl, 0, "\t.ref = VGC_ref,\n");
        Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
        Fc(tl, 0, "\t.nsrc = %u,\n", tl->nsources);
@@ -559,8 +562,6 @@ vcc_CompileSource(struct vsb *sb, struct source *sp)
        Fh(tl, 0, "\n/* ---===### VCC generated below here ###===---*/\n");
        Fh(tl, 0, "\nextern struct VCL_conf VCL_conf;\n");
 
-       Fi(tl, 0, "\tVRT_alloc_backends(&VCL_conf);\n");
-
        /* Register and lex the main source */
        TAILQ_INSERT_TAIL(&tl->sources, sp, list);
        sp->idx = tl->nsources++;
@@ -615,8 +616,6 @@ vcc_CompileSource(struct vsb *sb, struct source *sp)
        if (tl->err)
                return (vcc_DestroyTokenList(tl, NULL));
 
-       Ff(tl, 0, "\tVRT_free_backends(&VCL_conf);\n");
-
        /* Emit method functions */
        for (i = 0; i < N_METHODS; i++) {
                Fc(tl, 1, "\nstatic int\n");
index 60af001753179908a4cbacb29caac79673e150b0..bbf44f2db5e77e0731be6c17d43f297868514736 100644 (file)
@@ -398,6 +398,12 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "struct VCL_conf;\n");
        vsb_cat(sb, "struct sockaddr;\n");
        vsb_cat(sb, "\n");
+       vsb_cat(sb, "struct vrt_simple_backend {\n");
+       vsb_cat(sb, "   const char      *name;\n");
+       vsb_cat(sb, "   const char      *port;\n");
+       vsb_cat(sb, "   const char      *host;\n");
+       vsb_cat(sb, "};\n");
+       vsb_cat(sb, "\n");
        vsb_cat(sb, "struct vrt_ref {\n");
        vsb_cat(sb, "   unsigned        source;\n");
        vsb_cat(sb, "   unsigned        offset;\n");
@@ -441,10 +447,8 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "void VRT_handling(struct sess *sp, unsigned hand);\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "/* Backend related */\n");
-       vsb_cat(sb, "void VRT_set_backend_name(struct backend *, const char *);\n");
-       vsb_cat(sb, "void VRT_alloc_backends(struct VCL_conf *cp);\n");
-       vsb_cat(sb, "void VRT_free_backends(struct VCL_conf *cp);\n");
-       vsb_cat(sb, "void VRT_fini_backend(struct backend *be);\n");
+       vsb_cat(sb, "void VRT_init_simple_backend(struct backend **, struct vrt_simple_backend *);\n");
+       vsb_cat(sb, "void VRT_fini_backend(struct backend *);\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "char *VRT_IP_string(struct sess *sp, struct sockaddr *sa);\n");
        vsb_cat(sb, "char *VRT_int_string(struct sess *sp, int);\n");