source: lib/libvcl/vcc_gen_fixed_token.tcl @ 0b0c12

Revision 0b0c12, 8.2 KB checked in by Cecilie Fritzvold <cecilihf@…>, 7 years ago (diff)

Added support for load balancing among backends in varnish. It is still experimental
and very basic, but it should be ready for testing. Two strategies for load balancing
are implemented: a simple round robin, and a simple weighted random. The following
is an example configuration in vcl. The weight parameter for random is optional. Default
is equal weight.

backend foo {

set backend.host = "foo.bar.com";
set backend.port = "http";

}

backend_round_robin rr {

set backend.set = {

{ "foo1.bar.com", "http" }
{ "foo2.bar.com", "http" }
{ "foo3.bar.com", "http" }

};

}

backend_random rrr {

set backend.set = {

{ "foo1.bar.com", "http", 0.3 }
{ "foo2.bar.com", "http", 0.6 }
{ "foo3.bar.com", "http", 0.1 }

};

}

sub vcl_recv {

if {req.http.host ~ "foo"} {

req.backend = foo;

} elseif {req.http.host ~ "bar"} {

req.backend = rr;

} else {

req.backend = rrr;

}

}

git-svn-id:  http://www.varnish-cache.org/svn/trunk/varnish-cache@1931 d4fa192b-c00b-0410-8231-f00ffab90ce4

  • Property mode set to 100755
Line 
1#!/usr/local/bin/tclsh8.4
2#-
3# Copyright (c) 2006 Verdens Gang AS
4# Copyright (c) 2006-2007 Linpro AS
5# All rights reserved.
6#
7# Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12# 1. Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14# 2. Redistributions in binary form must reproduce the above copyright
15#    notice, this list of conditions and the following disclaimer in the
16#    documentation and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28# SUCH DAMAGE.
29#
30# Generate various .c and .h files for the VCL compiler and the interfaces
31# for it.
32
33# These are the metods which can be called in the VCL program.
34# Second element is list of valid return actions.
35#
36set methods {
37        {recv           {error pass pipe lookup}}
38        {pipe           {error pipe}}
39        {pass           {error pass}}
40        {hash           {hash}}
41        {miss           {error pass fetch}}
42        {hit            {error pass deliver}}
43        {fetch          {error pass insert}}
44        {deliver        {error deliver}}
45        {timeout        {fetch discard}}
46        {discard        {discard keep}}
47}
48
49# These are the return actions
50#
51set returns {
52        error
53        lookup
54        hash
55        pipe
56        pass
57        fetch
58        insert
59        deliver
60        discard
61        keep
62}
63
64# Language keywords
65#
66set keywords {
67        include 
68
69        if else elseif elsif
70
71        sub
72
73        acl
74
75        backend
76       
77        backend_round_robin
78
79        backend_random
80}
81
82# Non-word tokens
83#
84set magic {
85        {"++"   INC}
86        {"--"   DEC}
87        {"&&"   CAND}
88        {"||"   COR}
89        {"<="   LEQ}
90        {"=="   EQ}
91        {"!="   NEQ}
92        {">="   GEQ}
93        {">>"   SHR}
94        {"<<"   SHL}
95        {"+="   INCR}
96        {"-="   DECR}
97        {"*="   MUL}
98        {"/="   DIV}
99}
100
101# Single char tokens
102#
103set char {{}()*+-/%><=;!&.|~,}
104
105# Other token identifiers
106#
107set extras {ID VAR CNUM CSTR EOI CSRC}
108
109#----------------------------------------------------------------------
110# Boilerplate warning for all generated files.
111
112proc warns {fd} {
113
114        puts $fd "/*"
115        puts $fd { * $Id$}
116        puts $fd " *"
117        puts $fd " * NB:  This file is machine generated, DO NOT EDIT!"
118        puts $fd " *"
119        puts $fd " * Edit vcc_gen_fixed_token.tcl instead"
120        puts $fd " */"
121        puts $fd ""
122}
123
124#----------------------------------------------------------------------
125# Build the vcl.h #include file
126
127set fo [open ../../include/vcl.h w]
128warns $fo
129puts $fo {struct sess;
130
131typedef void vcl_init_f(void);
132typedef void vcl_fini_f(void);
133typedef int vcl_func_f(struct sess *sp);
134}
135puts $fo "struct VCL_conf {"
136puts $fo {      unsigned        magic;
137#define VCL_CONF_MAGIC  0x7406c509      /* from /dev/random */
138
139        struct backend  **backend;
140        unsigned        nbackend;
141        struct vrt_ref  *ref;
142        unsigned        nref;
143        unsigned        busy;
144       
145        unsigned        nsrc;
146        const char      **srcname;
147        const char      **srcbody;
148
149        unsigned        nhashcount;
150
151        void            *priv;
152
153        vcl_init_f      *init_func;
154        vcl_fini_f      *fini_func;
155}
156foreach m $methods {
157        puts $fo "\tvcl_func_f\t*[lindex $m 0]_func;"
158}
159puts $fo "};"
160
161close $fo
162
163#----------------------------------------------------------------------
164# Build the vcl_returns.h #include file
165
166set for [open "../../include/vcl_returns.h" w]
167warns $for
168puts $for "#ifdef VCL_RET_MAC"
169set i 0
170foreach k $returns {
171        if {$k == "error"} {
172                puts $for "#ifdef VCL_RET_MAC_E"
173                puts $for "VCL_RET_MAC_E($k, [string toupper $k], (1 << $i), $i)"
174                puts $for "#endif"
175        } else {
176                puts $for "VCL_RET_MAC($k, [string toupper $k], (1 << $i), $i)"
177        }
178        incr i
179}
180puts $for "#else"
181set i 0
182foreach k $returns {
183        puts $for "#define VCL_RET_[string toupper $k]  (1 << $i)"
184        incr i
185}
186puts $for "#define VCL_RET_MAX $i"
187puts $for "#endif"
188puts $for ""
189puts $for "#ifdef VCL_MET_MAC"
190set u 0
191foreach m $methods {
192        puts -nonewline $for "VCL_MET_MAC([lindex $m 0]"
193        puts -nonewline $for ",[string toupper [lindex $m 0]]"
194        set l [lindex $m 1]
195        puts -nonewline $for ",(VCL_RET_[string toupper [lindex $l 0]]"
196        foreach r [lrange $l 1 end] {
197                puts -nonewline $for "|VCL_RET_[string toupper $r]"
198        }
199        puts -nonewline $for ")"
200        puts $for ")"
201        incr u
202}
203puts $for "#else"
204set u 0
205foreach m $methods {
206        puts $for "#define VCL_MET_[string toupper [lindex $m 0]]\t(1 << $u)"
207        incr u
208}
209puts $for "#endif"
210puts $for "#define N_METHODS $u"
211close $for
212
213#----------------------------------------------------------------------
214# Build the compiler token table and recognizers
215
216set fo [open "vcc_fixed_token.c" w]
217warns $fo
218
219set foh [open "vcc_token_defs.h" w]
220warns $foh
221
222puts $fo "#include <stdio.h>"
223puts $fo "#include <ctype.h>"
224puts $fo "#include \"vcc_priv.h\""
225puts $fo "#include \"vsb.h\""
226
227set tn 128
228puts $foh "#define LOW_TOKEN $tn"
229
230
231proc add_token {tok str alpha} {
232        global tokens tn fixed foh
233
234        lappend tokens [list $tok $str]
235        puts $foh "#define $tok $tn"
236        incr tn
237        lappend fixed [list $str $tok $alpha]
238}
239
240proc mk_token {tok str alpha} {
241        set tok T_[string toupper $tok]
242        add_token $tok $str $alpha
243}
244
245foreach k $keywords { mk_token $k $k 1 }
246foreach k $magic { mk_token [lindex $k 1] [lindex $k 0] 0 }
247foreach k $extras {
248        set t [string toupper $k]
249        lappend tokens [list $t $t]
250        puts $foh "#define [string toupper $k] $tn"
251        incr tn
252}
253for {set i 0} {$i < [string length $char]} {incr i} {
254        set t [string index $char $i]
255        lappend token2 [list '$t' T$t]
256        lappend fixed [list "$t" '$t' 0]
257}
258
259set tokens [lsort $tokens]
260set token2 [lsort $token2]
261
262# We want to output in ascii order: create sorted first char list
263foreach t $fixed {
264        set xx([string index [lindex $t 0] 0]) 1
265}
266set seq [lsort [array names xx]]
267
268set ll 0
269
270puts $fo {
271unsigned
272vcl_fixed_token(const char *p, const char **q)}
273puts $fo "{"
274puts $fo ""
275puts $fo "      switch (p\[0\]) {"
276
277foreach ch "$seq" {
278        # Now find all tokens starting with ch
279        set l ""
280        foreach t $fixed {
281                if {[string index [lindex $t 0] 0] == $ch} {
282                        lappend l $t
283                }
284        }
285        # And do then in reverse order to match longest first
286        set l [lsort -index 0 -decreasing $l]
287        scan "$ch" "%c" cx
288        if {$cx != $ll} {
289                if {$ll} {
290                        puts $fo "              return (0);"
291                }
292       
293                puts $fo "      case '$ch':"
294                set ll $cx
295        }
296        foreach tt $l {
297                set k [lindex $tt 0]
298                puts -nonewline $fo "           if ("
299                for {set i 0} {$i < [string length $k]} {incr i} {
300                        if {$i > 0} {
301                                puts -nonewline $fo " && "
302                                if {![expr $i % 3]} {
303                                        puts -nonewline $fo "\n\t\t    "
304                                }
305                        }
306                        puts -nonewline $fo "p\[$i\] == '[string index $k $i]'"
307                }
308                if {[lindex $tt 2]} {
309                        if {![expr $i % 3]} {
310                                puts -nonewline $fo "\n\t\t    "
311                        }
312                        puts -nonewline $fo " && !isvar(p\[$i\])"
313                }
314                puts $fo ") {"
315                puts $fo "                      *q = p + [string length $k];"
316                puts $fo "                      return ([lindex $tt 1]);"
317                puts $fo "              }"
318        }
319} 
320puts $fo "              return (0);"
321puts $fo "      default:"
322puts $fo "              return (0);"
323puts $fo "      }"
324puts $fo "}"
325
326puts $fo ""
327puts $fo "const char *vcl_tnames\[256\];\n"
328puts $fo "void"
329puts $fo "vcl_init_tnames(void)"
330puts $fo "{"
331foreach i $token2 {
332        puts $fo "\tvcl_tnames\[[lindex $i 0]\] = \"[lindex $i 0]\";"
333}
334foreach i $tokens {
335        puts $fo "\tvcl_tnames\[[lindex $i 0]\] = \"[lindex $i 1]\";"
336}
337puts $fo "}"
338
339#----------------------------------------------------------------------
340# Create the C-code which emits the boilerplate definitions for the
341# generated C code output
342
343proc copy_include {n} {
344        global fo
345
346        set fi [open $n]
347        while {[gets $fi a] >= 0} {
348                regsub -all {\\} $a {\\\\} a
349                puts $fo "\tvsb_cat(sb, \"$a\\n\");"
350        }
351        close $fi
352}
353
354puts $fo ""
355puts $fo "void"
356puts $fo "vcl_output_lang_h(struct vsb *sb)"
357puts $fo "{"
358set i 0
359foreach k $returns {
360        puts $fo "\tvsb_cat(sb, \"#define VCL_RET_[string toupper $k]  (1 << $i)\\n\");"
361        incr i
362}
363
364copy_include ../../include/vcl.h
365copy_include ../../include/vrt.h
366copy_include ../../include/vrt_obj.h
367
368puts $fo "}"
369
370close $foh
371close $fo
Note: See TracBrowser for help on using the repository browser.