]> err.no Git - varnish/commitdiff
Add code to VCC to output an identifier for each simple backend which
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 24 Sep 2007 11:25:15 +0000 (11:25 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 24 Sep 2007 11:25:15 +0000 (11:25 +0000)
varnishd can use to decide if a backend state can be shared between
multiple VCL programs.

Originally the idea was to calculate a strong hash over the tokens
which define the backend.

Considering the relatively short lengths of backend declarations
and the infrequency of comparisons, we have opted for an extremely
weak hash instead:  We simply output the space separted tokens as
a string.

The net change in code for simple backends is marginal, but for
complex backends this will be a lot simpler to implement.

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

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

index b7e9c143f00dfa756e85f1a7062527890acf5d5c..282713e411a586be76b08440bc5d61fe133b0717 100644 (file)
@@ -49,6 +49,7 @@ struct bes {
 #define BES_MAGIC              0x015e17ac
        char                    *hostname;
        char                    *portname;
+       char                    *ident;
        struct addrinfo         *addr;
        struct addrinfo         *last_addr;
        double                  dnsttl;
@@ -369,12 +370,8 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
                CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
                if (b->method != &backend_method_simple)
                        continue;
-               if (strcmp(b->vcl_name, t->name))
-                       continue;
                CAST_OBJ_NOTNULL(bes, b->priv, BES_MAGIC);
-               if (strcmp(bes->portname, t->port))
-                       continue;
-               if (strcmp(bes->hostname, t->host))
+               if (strcmp(bes->ident, t->ident))
                        continue;
                b->refcount++;
                *bp = b;
@@ -391,6 +388,9 @@ VRT_init_simple_backend(struct backend **bp, struct vrt_simple_backend *t)
 
        bes->dnsttl = 300;
 
+       AN(t->ident);
+       REPLACE(bes->ident, t->ident);
+
        AN(t->name);
        REPLACE(b->vcl_name, t->name);
 
index dc0059c7586741e4f2f1e65706e163f6f257c5d5..b06cd391ef70158380641c6309215eba037219c5 100644 (file)
@@ -41,6 +41,7 @@ struct VCL_conf;
 struct sockaddr;
 
 struct vrt_simple_backend {
+       const char      *ident;
        const char      *name;
        const char      *port;
        const char      *host;
index b770836d6a90f160ca1a122914bad122fb22c732..fe64cb3cc0a4e5e75043899880cd6e60ec95468b 100644 (file)
@@ -58,6 +58,32 @@ CheckHostPort(const char *host, const char *port)
        return (NULL);
 }
 
+/*--------------------------------------------------------------------
+ * When a new VCL is loaded, it is likely to contain backend declarations
+ * identical to other loaded VCL programs, and we want to reuse the state
+ * of those in order to not have to relearn statistics, DNS etc.
+ *
+ * This function emits a space separated text-string of the tokens which
+ * define a given backend which can be used to determine "identical backend"
+ * in that context.
+ */
+
+static void
+vcc_EmitBeIdent(struct tokenlist *tl, struct token *first, struct token *last)
+{
+
+       Fc(tl, 0, "\t.ident =");
+       while (first != last) {
+               if (first->dec != NULL)
+                       Fc(tl, 0, "\n\t    \"\\\"\" %.*s \"\\\" \"",
+                           PF(first));
+               else
+                       Fc(tl, 0, "\n\t    \"%.*s \"", PF(first));
+               first = TAILQ_NEXT(first, list);
+       }
+       Fc(tl, 0, ",\n");
+}
+
 void
 vcc_ParseSimpleBackend(struct tokenlist *tl)
 {
@@ -65,8 +91,10 @@ vcc_ParseSimpleBackend(struct tokenlist *tl)
        struct token *t_be = NULL;
        struct token *t_host = NULL;
        struct token *t_port = NULL;
+       struct token *t_first;
        const char *ep;
 
+       t_first = tl->t;
        vcc_NextToken(tl);
        ExpectErr(tl, ID);
        t_be = tl->t;
@@ -152,6 +180,7 @@ vcc_ParseSimpleBackend(struct tokenlist *tl)
        else
                Fc(tl, 0, "\t.port = \"http\",\n");
        Fc(tl, 0, "\t.host = %.*s,\n", PF(t_host));
+       vcc_EmitBeIdent(tl, t_first, tl->t);
        Fc(tl, 0, "};\n");
        Fi(tl, 0, "\tVRT_init_simple_backend(&VGC_backend_%.*s , &sbe_%.*s);\n",
            PF(t_be), PF(t_be));
index 7d63b3b27862f5ad2f401d570eb42b1f1cc2fb16..aad2f95cfd3d2fa041c7f225ed048948389ab187 100644 (file)
@@ -419,6 +419,7 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "struct sockaddr;\n");
        vsb_cat(sb, "\n");
        vsb_cat(sb, "struct vrt_simple_backend {\n");
+       vsb_cat(sb, "   const char      *ident;\n");
        vsb_cat(sb, "   const char      *name;\n");
        vsb_cat(sb, "   const char      *port;\n");
        vsb_cat(sb, "   const char      *host;\n");