]> err.no Git - varnish/commitdiff
Parse a random director into an appropriate data structure,
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 22 Jan 2008 10:48:49 +0000 (10:48 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 22 Jan 2008 10:48:49 +0000 (10:48 +0000)
still bits missing.

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

varnish-cache/include/vrt.h
varnish-cache/lib/libvcl/vcc_backend.c
varnish-cache/lib/libvcl/vcc_compile.h
varnish-cache/lib/libvcl/vcc_fixed_token.c
varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl
varnish-cache/lib/libvcl/vcc_parse.c
varnish-cache/lib/libvcl/vcc_token_defs.h

index 25abbc1dbf34af20c7a246a8cce9d6feb93b2b7c..d9e4a43749728bba6073c9749d43a03db57a94dd 100644 (file)
@@ -65,6 +65,17 @@ struct vrt_round_robin_backend {
        struct vrt_backend_entry *bentry;
 };
 
+struct vrt_dir_random_entry {
+       const struct vrt_backend_host   *host;
+       double                          weight;
+};
+
+struct vrt_dir_random {
+       unsigned                        nmember;
+       struct vrt_dir_random_entry     *members;
+       const char                      *ident;
+};
+
 struct vrt_random_backend {
        const char      *name;
        unsigned        weighted;
index fd41543d40fc6f5fb996556bafe12081ec3bc98d..3a69a8144028b217b2f23a3fb3bddc0aeef220a1 100644 (file)
@@ -85,7 +85,7 @@ vcc_EmitBeIdent(struct vsb *v, const struct token *first, const struct token *la
 }
 
 /*--------------------------------------------------------------------
- * Parse and emit a backend specification.
+ * Parse and emit a backend host specification.
  *
  * The syntax is the following:
  *
@@ -245,8 +245,12 @@ vcc_ParseBackendHost(struct tokenlist *tl, int *nbh)
        vcc_NextToken(tl);
 }
 
+/*--------------------------------------------------------------------
+ * Parse a plain backend
+ */
+
 void
-vcc_ParseSimpleBackend(struct tokenlist *tl)
+vcc_ParseBackend(struct tokenlist *tl)
 {
        struct token *t_first;
        struct host *h;
@@ -287,171 +291,102 @@ vcc_ParseSimpleBackend(struct tokenlist *tl)
        tl->nbackend++;
 }
 
-void
-vcc_ParseBalancedBackend(struct tokenlist *tl)
+/*--------------------------------------------------------------------
+ * Parse directors
+ */
+
+static void
+vcc_ParseRandomDirector(struct tokenlist *tl, struct token *t_first, struct token *t_dir)
 {
-       struct var *vp;
-       struct token *t_be = NULL;
-       struct token *t_host = NULL;
-       struct token *t_port = NULL;
-       double t_weight = 0;
-       const char *ep;
-       int cnt = 0;
-       int weighted = 0;
-       double weight = 0;
-       unsigned backend_type = tl->t->tok;
+       struct token *t_field, *tb, *tw;
+       int nbh, nelem;
 
-       vcc_NextToken(tl);
-       ExpectErr(tl, ID);
-       t_be = tl->t;
-       vcc_AddDef(tl, tl->t, R_BACKEND);
+       (void)t_first;
+       (void)t_dir;
 
-       /* 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);
+       vcc_NextToken(tl);              /* ID: policy (= random) */
 
-       vcc_NextToken(tl);
        ExpectErr(tl, '{');
        vcc_NextToken(tl);
-       
-       while (1) {
-               if (tl->t->tok == '}')
-                       break;
-               ExpectErr(tl, ID);
-               if (!vcc_IdIs(tl->t, "set")) {
-                       vsb_printf(tl->sb,
-                           "Expected 'set', found ");
-                       vcc_ErrToken(tl, tl->t);
-                       vsb_printf(tl->sb, " at\n");
-                       vcc_ErrWhere(tl, tl->t);
-                       return;
-               }
-               vcc_NextToken(tl);
-               ExpectErr(tl, VAR);
-               vp = vcc_FindVar(tl, tl->t, vcc_be_vars);
-               ERRCHK(tl);
-               assert(vp != NULL);
-               vcc_NextToken(tl);
-               ExpectErr(tl, '=');
-               vcc_NextToken(tl);
-               if (vp->fmt != SET) {
-                       vsb_printf(tl->sb,
-                           "Assignments not possible for '%s'\n", vp->name);
-                       vcc_ErrWhere(tl, tl->t);
-                       return;
-               }
-               
+
+       Fc(tl, 0,
+           "\nstatic const struct vrt_dir_random_entry vdre_%.*s[] = {\n",
+           PF(t_dir));
+
+       for (nelem = 0; tl->t->tok != '}'; nelem++) {   /* List of members */
+               tb = NULL;
+               tw = NULL;
+               nbh = -1;
+
                ExpectErr(tl, '{');
                vcc_NextToken(tl);
-               
-               while (1) {
-                       if (tl->t->tok == '}')
-                               break;
-                               
-                       ExpectErr(tl, '{');
+       
+               while (tl->t->tok != '}') {     /* Member fields */
+                       ExpectErr(tl, '.');
                        vcc_NextToken(tl);
-                       
-                       // Host
-                       ExpectErr(tl, CSTR);
-                       t_host = tl->t;
+                       ExpectErr(tl, ID);
+                       t_field = tl->t;
                        vcc_NextToken(tl);
-               
-                       ep = CheckHostPort(t_host->dec, "80");
-                       if (ep != NULL) {
-                               vsb_printf(tl->sb, "Backend '%.*s': %s\n", PF(t_be), ep);
-                               vcc_ErrWhere(tl, t_host);
-                               return;
-                       }
-                       
-                       if (tl->t->tok == ',') {
+                       ExpectErr(tl, '=');
+                       vcc_NextToken(tl);
+                       if (vcc_IdIs(t_field, "backend")) {
+                               assert(tb == NULL);
+                               tb = t_field;
+                               vcc_ParseBackendHost(tl, &nbh);
+                       } else if (vcc_IdIs(t_field, "weight")) {
+                               assert(tw == NULL);
+                               ExpectErr(tl, CNUM);
+                               tw = tl->t;
                                vcc_NextToken(tl);
-                               
-                               // Port
-                               
-                               ExpectErr(tl, CSTR);
-                               t_port = tl->t;
+                               ExpectErr(tl, ';');
                                vcc_NextToken(tl);
-                               
-                               ep = CheckHostPort(t_host->dec, t_port->dec);
-                               if (ep != NULL) {
-                                       vsb_printf(tl->sb,
-                                           "Backend '%.*s': %s\n", PF(t_be), ep);
-                                       vcc_ErrWhere(tl, t_port);
-                                       return;
-                               }
-                               
-                               if (tl->t->tok == ',') {
-                               
-                                       vcc_NextToken(tl);
-                                       
-                                       // Weight
-                                       t_weight = vcc_DoubleVal(tl);
-                                       weighted = 1;
-                                       weight += t_weight;
-                               }
+                       } else {
+                               ExpectErr(tl, '?');
                        }
-                                               
-                       ExpectErr(tl, '}');
-                       vcc_NextToken(tl);
-               
-                       Fc(tl, 0, "\nstatic struct vrt_backend_entry bentry_%.*s_%d = {\n",
-                               PF(t_be), cnt);
-                       Fc(tl, 0, "\t.port = %.*s,\n", PF(t_port));
-                       Fc(tl, 0, "\t.host = %.*s,\n", PF(t_host));
-                       Fc(tl, 0, "\t.weight = %f,\n", t_weight);
-                       if (cnt > 0) {
-                               Fc(tl, 0, "\t.next = &bentry_%.*s_%d\n", PF(t_be), cnt-1);
-                       } /*else {
-                               Fc(tl, 0, "\t.next = NULL\n");
-                       }*/
-                       Fc(tl, 0, "};\n");
-                       t_weight = 0;
-                       cnt++;
                }
-               ExpectErr(tl, '}');
+               assert(tb != NULL);
+               Fc(tl, 0, "\t{");
+               Fc(tl, 0, ".host = &bh_%d", nbh);
+               if (tw != NULL)
+                       Fc(tl, 0, ", .weight = %.*s", PF(tw));
+               Fc(tl, 0, "},\n");
                vcc_NextToken(tl);
-               ExpectErr(tl, ';');
-               vcc_NextToken(tl);
-               
-               if (t_host == NULL) {
-                       vsb_printf(tl->sb, "Backend '%.*s' has no hostname\n",
-                       PF(t_be));
-                       vcc_ErrWhere(tl, tl->t);
-                       return;
-               }
-               
-               if (weighted && (int)weight != 1) {
-                       vsb_printf(tl->sb, "Total weight must be 1\n");
-                       vcc_ErrWhere(tl, tl->t);
-                       return;
-               }
-               
-               if (backend_type == T_BACKEND_ROUND_ROBIN) {
-                       Fc(tl, 0, "\nstatic struct vrt_round_robin_backend sbe_%.*s = {\n",
-                           PF(t_be));
-                       Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(t_be));
-                       Fc(tl, 0, "\t.count = %d,\n", cnt);
-                       Fc(tl, 0, "\t.bentry = &bentry_%.*s_%d\n", PF(t_be), cnt-1);
-                       Fc(tl, 0, "};\n");
-                       Fi(tl, 0, "\tVRT_init_round_robin_backend(&VGC_backend_%.*s , &sbe_%.*s);\n",
-                           PF(t_be), PF(t_be));
-               } else if (backend_type == T_BACKEND_RANDOM) {
-                       Fc(tl, 0, "\nstatic struct vrt_random_backend sbe_%.*s = {\n",
-                           PF(t_be));
-                       Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(t_be));
-                       Fc(tl, 0, "\t.weighted = %d,\n", weighted);
-                       Fc(tl, 0, "\t.count = %d,\n", cnt);
-                       Fc(tl, 0, "\t.bentry = &bentry_%.*s_%d\n", PF(t_be), cnt-1);
-                       Fc(tl, 0, "};\n");
-                       Fi(tl, 0, "\tVRT_init_random_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));
-
        }
-       ExpectErr(tl, '}');
-
+       Fc(tl, 0, "\t{ .host = 0 }\n");
+       Fc(tl, 0, "}\n");
+       Fc(tl, 0,
+           "\nstatic const struct vrt_dir_random vdr_%.*s[] = {\n",
+           PF(t_dir));
+       Fc(tl, 0, "\t.nmember = %d,\n", nelem);
+       Fc(tl, 0, "\t.members = vdre_%.*s,\n", PF(t_dir));
+       vcc_EmitBeIdent(tl->fc, t_first, tl->t);
        vcc_NextToken(tl);
-       tl->nbackend++;
 }
 
+/*--------------------------------------------------------------------
+ * Parse directors
+ */
+
+void
+vcc_ParseDirector(struct tokenlist *tl)
+{
+       struct token *t_dir, *t_first;
+
+       vcc_NextToken(tl);              /* ID: director */
+       t_first = tl->t;
+
+       ExpectErr(tl, ID);              /* ID: name */
+       t_dir = tl->t;
+       vcc_NextToken(tl);
+
+       ExpectErr(tl, ID);              /* ID: policy */
+       if (vcc_IdIs(tl->t, "random")) 
+               vcc_ParseRandomDirector(tl, t_first, t_dir);
+       else {
+               vsb_printf(tl->sb, "Unknown director policy: ");
+               vcc_ErrToken(tl, tl->t);
+               vsb_printf(tl->sb, " at\n");
+               vcc_ErrWhere(tl, tl->t);
+               return;
+       }
+}
index 65cd678ff7ca89a22e3552cd0330e87eb19d4527..2faeb8ec94663063d66d5111be7f3d80b61a0d96 100644 (file)
@@ -161,8 +161,8 @@ void vcc_Cond_Ip(const struct var *vp, struct tokenlist *tl);
 void vcc_ParseAction(struct tokenlist *tl);
 
 /* vcc_backend.c */
-void vcc_ParseSimpleBackend(struct tokenlist *tl);
-void vcc_ParseBalancedBackend(struct tokenlist *tl);
+void vcc_ParseBackend(struct tokenlist *tl);
+void vcc_ParseDirector(struct tokenlist *tl);
 
 /* vcc_compile.c */
 extern struct method method_tab[];
index 27a8eb9d886cb5e201b87b089c1d65e387f2d899..70244946e5a6e3ba2dd920b6deaf16790955a724 100644 (file)
@@ -165,32 +165,6 @@ vcl_fixed_token(const char *p, const char **q)
                        return (T_ACL);
                }
                return (0);
-       case 'b':
-               if (p[0] == 'b' && p[1] == 'a' && p[2] == 'c' && 
-                   p[3] == 'k' && p[4] == 'e' && p[5] == 'n' && 
-                   p[6] == 'd' && p[7] == '_' && p[8] == 'r' && 
-                   p[9] == 'o' && p[10] == 'u' && p[11] == 'n' && 
-                   p[12] == 'd' && p[13] == '_' && p[14] == 'r' && 
-                   p[15] == 'o' && p[16] == 'b' && p[17] == 'i' && 
-                   p[18] == 'n' && !isvar(p[19])) {
-                       *q = p + 19;
-                       return (T_BACKEND_ROUND_ROBIN);
-               }
-               if (p[0] == 'b' && p[1] == 'a' && p[2] == 'c' && 
-                   p[3] == 'k' && p[4] == 'e' && p[5] == 'n' && 
-                   p[6] == 'd' && p[7] == '_' && p[8] == 'r' && 
-                   p[9] == 'a' && p[10] == 'n' && p[11] == 'd' && 
-                   p[12] == 'o' && p[13] == 'm' && !isvar(p[14])) {
-                       *q = p + 14;
-                       return (T_BACKEND_RANDOM);
-               }
-               if (p[0] == 'b' && p[1] == 'a' && p[2] == 'c' && 
-                   p[3] == 'k' && p[4] == 'e' && p[5] == 'n' && 
-                   p[6] == 'd' && !isvar(p[7])) {
-                       *q = p + 7;
-                       return (T_BACKEND);
-               }
-               return (0);
        case 'e':
                if (p[0] == 'e' && p[1] == 'l' && p[2] == 's' && 
                    p[3] == 'i' && p[4] == 'f' && !isvar(p[5])) {
@@ -291,9 +265,6 @@ vcl_init_tnames(void)
        vcl_tnames[EOI] = "EOI";
        vcl_tnames[ID] = "ID";
        vcl_tnames[T_ACL] = "acl";
-       vcl_tnames[T_BACKEND] = "backend";
-       vcl_tnames[T_BACKEND_RANDOM] = "backend_random";
-       vcl_tnames[T_BACKEND_ROUND_ROBIN] = "backend_round_robin";
        vcl_tnames[T_CAND] = "&&";
        vcl_tnames[T_COR] = "||";
        vcl_tnames[T_DEC] = "--";
@@ -445,6 +416,17 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, "   struct vrt_backend_entry *bentry;\n");
        vsb_cat(sb, "};\n");
        vsb_cat(sb, "\n");
+       vsb_cat(sb, "struct vrt_dir_random_entry {\n");
+       vsb_cat(sb, "   const struct vrt_backend_host   *host;\n");
+       vsb_cat(sb, "   double                          weight;\n");
+       vsb_cat(sb, "};\n");
+       vsb_cat(sb, "\n");
+       vsb_cat(sb, "struct vrt_dir_random {\n");
+       vsb_cat(sb, "   unsigned                        nmember;\n");
+       vsb_cat(sb, "   struct vrt_dir_random_entry     *members;\n");
+       vsb_cat(sb, "   const char                      *ident;\n");
+       vsb_cat(sb, "};\n");
+       vsb_cat(sb, "\n");
        vsb_cat(sb, "struct vrt_random_backend {\n");
        vsb_cat(sb, "   const char      *name;\n");
        vsb_cat(sb, "   unsigned        weighted;\n");
index 71bb8265282c75ff2823cb671631bf29a97e7025..7dcc53cf44c254ebf7e1030281fc703e6e31b58e 100755 (executable)
@@ -73,12 +73,6 @@ set keywords {
        sub
 
        acl
-
-       backend
-       
-       backend_round_robin
-
-       backend_random
 }
 
 # Non-word tokens
index e601a98b02fb3ea288ba8bc54eebc2a288f3b5d0..d3e70919dcce2a1e4c658db930058953d222d4ab 100644 (file)
@@ -564,13 +564,6 @@ vcc_Parse(struct tokenlist *tl)
                case T_SUB:
                        Function(tl);
                        break;
-               case T_BACKEND:
-                       vcc_ParseSimpleBackend(tl);
-                       break;
-               case T_BACKEND_RANDOM:
-               case T_BACKEND_ROUND_ROBIN:
-                       vcc_ParseBalancedBackend(tl);
-                       break;
                case CSRC:
                        Fc(tl, 0, "%.*s\n",
                            tl->t->e - (tl->t->b + 4), tl->t->b + 2);
@@ -578,6 +571,16 @@ vcc_Parse(struct tokenlist *tl)
                        break;
                case EOI:
                        break;
+               case ID:
+                       if (vcc_IdIs(tl->t, "backend")) {
+                               vcc_ParseBackend(tl);
+                               break;
+                       }
+                       if (vcc_IdIs(tl->t, "director")) {
+                               vcc_ParseDirector(tl);
+                               break;
+                       }
+                       /* FALLTHROUGH */
                default:
                        vsb_printf(tl->sb,
                            "Expected 'acl', 'sub' or 'backend', found ");
index ccbe6a5cd2c86315f5dccb95a489ffa4415b020a..a45dc0b694fdfa55054996f62a9068e4ee953bfd 100644 (file)
 #define T_ELSIF 132
 #define T_SUB 133
 #define T_ACL 134
-#define T_BACKEND 135
-#define T_BACKEND_ROUND_ROBIN 136
-#define T_BACKEND_RANDOM 137
-#define T_INC 138
-#define T_DEC 139
-#define T_CAND 140
-#define T_COR 141
-#define T_LEQ 142
-#define T_EQ 143
-#define T_NEQ 144
-#define T_GEQ 145
-#define T_SHR 146
-#define T_SHL 147
-#define T_INCR 148
-#define T_DECR 149
-#define T_MUL 150
-#define T_DIV 151
-#define ID 152
-#define VAR 153
-#define CNUM 154
-#define CSTR 155
-#define EOI 156
-#define CSRC 157
+#define T_INC 135
+#define T_DEC 136
+#define T_CAND 137
+#define T_COR 138
+#define T_LEQ 139
+#define T_EQ 140
+#define T_NEQ 141
+#define T_GEQ 142
+#define T_SHR 143
+#define T_SHL 144
+#define T_INCR 145
+#define T_DECR 146
+#define T_MUL 147
+#define T_DIV 148
+#define ID 149
+#define VAR 150
+#define CNUM 151
+#define CSTR 152
+#define EOI 153
+#define CSRC 154