From ae95d4b1ff25c30e7235248a26c84b267dc8f1ea Mon Sep 17 00:00:00 2001 From: phk Date: Mon, 24 Sep 2007 11:25:15 +0000 Subject: [PATCH] Add code to VCC to output an identifier for each simple backend which 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 --- .../bin/varnishd/cache_backend_simple.c | 10 +++---- varnish-cache/include/vrt.h | 1 + varnish-cache/lib/libvcl/vcc_backend.c | 29 +++++++++++++++++++ varnish-cache/lib/libvcl/vcc_fixed_token.c | 1 + 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_backend_simple.c b/varnish-cache/bin/varnishd/cache_backend_simple.c index b7e9c143..282713e4 100644 --- a/varnish-cache/bin/varnishd/cache_backend_simple.c +++ b/varnish-cache/bin/varnishd/cache_backend_simple.c @@ -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); diff --git a/varnish-cache/include/vrt.h b/varnish-cache/include/vrt.h index dc0059c7..b06cd391 100644 --- a/varnish-cache/include/vrt.h +++ b/varnish-cache/include/vrt.h @@ -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; diff --git a/varnish-cache/lib/libvcl/vcc_backend.c b/varnish-cache/lib/libvcl/vcc_backend.c index b770836d..fe64cb3c 100644 --- a/varnish-cache/lib/libvcl/vcc_backend.c +++ b/varnish-cache/lib/libvcl/vcc_backend.c @@ -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)); diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index 7d63b3b2..aad2f95c 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -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"); -- 2.39.5