Re: bug? rand based acl keep re-evaluating

2015-03-05 Thread Willy Tarreau
Hi Vivek,

On Thu, Mar 05, 2015 at 01:31:53AM -0600, Vivek Malik wrote:
 Hi Willy,
 
 I am using haproxy/rand to simulate A/B/C... testing between multiple
 environments. Each backend emits a long expiry cookie to put the
 session into their experiment. If a request comes with a cookie of the
 experiment, the request goes to that backend. If a session comes
 without a cookie, rand is used to decide which backend would be used
 for the request.

OK.

 My earlier code looked similar to
 
 acl testa req.cookie(abtest) eq a
 acl testb req.cookie(abtest) eq b
 acl testa_rand rand(100) lt 80
 acl testb_rand rand(20) lt 20
 http-request set-header expirment=a if testa
 http-request set-header expirment=b if testb
 
 http-request set-header expirment=a if !testa !testb testa_rand
 http-request set-header expirment=a if !testa !testb testb_rand
 
 use_backend bk_a if testa
 use_backend bk_b if testb
 use_backend bk_a if testa_rand
 use_backend bk_b if testb_rand

One possibility is also to use default_backend as a fallback. But
it would indeed not fix the multiple/missing header addition.

 However, this config was failing as request would often to backend
 with experiment header not set properly. Once I understood that acl
 was evaluating rand every time, I was able to write the configuration
 something like
 
 http-request del-header experiment
 http-request set-header experiment a if { req.cook(abtest) eq a }
 http-request set-header experiment b if { req.cook(abtest) eq b } 
 !{ req.hdr(experiment) -m found }
 http-request set-header experiment a if { rand(100) lt 80 }  !{
 req.hdr(experiment) -m found }
 http-request set-header experiment b if { rand(20) lt 20 }  !{
 req.hdr(experiment) -m found }
 
 use_backend bk_a if { req.hdr(experiment) eq a }
 use_backend bk_b if { req.hdr(experiment) eq b }
 
 Using the request header as a temporary variable, I was able to keep
 state and avoid calling rand acl more than once.

Yes that definitely is the way to go.

Cheers,
Willy




Re: bug? rand based acl keep re-evaluating

2015-03-04 Thread Willy Tarreau
Hi Vivek,

On Sun, Mar 01, 2015 at 12:21:57AM -0600, Vivek Malik wrote:
 Hi,
 
 I spent last few hours scratching my head and wondering where my
 configuration was wrong and why was it acting weird. Sending this to
 ML to see if this is a bug or expected behavior. I expected ACL to
 evaluate its condition only once and store the true/false outcome,
 however with rand(), I believe that ACL keeps re-evaluating on every
 use. Example,
 
 acl random rand(50) lt 25
 http-response set-header H1 V1 if random
 http-response set-header H2 V2 if random
 http-response set-header H3 V3 if random
 
 I would except either all 3 headers H1, H2, H3 to be set or none to be
 set. However, in my test config I observed that H1, H2, H3 are set
 independent of each other essentially meaning that ACL is getting
 re-evaluated every time it is getting used.
 
 Is this the expected behavior of ACLs? If yes, how would using a named
 ACL be different than using an anonymous ACL?

It's normal and it works as expected (eventhough it doesn't match your
expectations). ACLs are evaluated when they're used. So here what happens
is that the random value is evaluated on each line.

In practice we can find various ways to work around this depending on
your use case. Could you please describe what you wanted to achieve,
as I suspect that your config above was made only to confirm your
observation, and is not related to your target use case ?

Thanks,
Willy




bug? rand based acl keep re-evaluating

2015-02-28 Thread Vivek Malik
Hi,

I spent last few hours scratching my head and wondering where my
configuration was wrong and why was it acting weird. Sending this to
ML to see if this is a bug or expected behavior. I expected ACL to
evaluate its condition only once and store the true/false outcome,
however with rand(), I believe that ACL keeps re-evaluating on every
use. Example,

acl random rand(50) lt 25
http-response set-header H1 V1 if random
http-response set-header H2 V2 if random
http-response set-header H3 V3 if random

I would except either all 3 headers H1, H2, H3 to be set or none to be
set. However, in my test config I observed that H1, H2, H3 are set
independent of each other essentially meaning that ACL is getting
re-evaluated every time it is getting used.

Is this the expected behavior of ACLs? If yes, how would using a named
ACL be different than using an anonymous ACL?

Regards,
Vivek