0

In haproxy, I implemented a simple way to delay clients sending too many requests too fast:

In haproxy.cfg:

acl conn_rate_high              sc1_conn_rate(ipsticktable) gt 20
http-request lua.delay_request  if conn_rate_high

In the lua file:

function delay_request(txn)
    core.msleep(1000)
end
core.register_action("delay_request", { "http-req" }, delay_request);

This works okay, but what if I want to delay more if there are even more requests? I can have multiple delay functions with different delays, and multiple acls and conditions, but this gets clunky really fast.

The sensible thing would be to calculate the delay inside the lua function from the connection rate. My problem is, that I cannot pass the connection rate value to the lua function.

Here is what I tried and does not work:

In haproxy.cfg:

http-request set-var(txn.sc1_conn_rate) sc1_conn_rate(ipsticktable)

In the lua script:

function delay_request(txn)
    local cr = tostring(txn:get_var("sc1_conn_rate"))
    txn:Alert("conn_rate: ")
    txn:Alert(cr)
    txn:Alert("\n")
    core.msleep(tonumber(cr) * 500)
end

The output in the log is:

Nov 18 14:41:06  haproxy[10988]: conn_rate:
Nov 18 14:41:06  haproxy[10988]: conn_rate:
Nov 18 14:41:06  haproxy[10988]: nil
Nov 18 14:41:06  haproxy[10988]: nil
Nov 18 14:41:06  haproxy[10988]: conn_rate:
Nov 18 14:41:06  haproxy[10988]: conn_rate:
Nov 18 14:41:06  haproxy[10988]: nil
Nov 18 14:41:06  haproxy[10988]: nil
Nov 18 14:41:06  haproxy[10988]: .
Nov 18 14:41:06  haproxy[10988]: .
Nov 18 14:41:06  haproxy[10988]: Lua function 'delay_request': runtime error: /etc/haproxy/delay.lua:6: attempt to perform arithmetic on a nil value from /etc/haproxy/delay.lua:6 C function line 1.
Nov 18 14:41:06  haproxy[10988]: Lua function 'delay_request': runtime error: /etc/haproxy/delay.lua:6: attempt to perform arithmetic on a nil value from /etc/haproxy/delay.lua:6 C function line 1.

So, as far as I understand, get_var got nil for some reason. :(

My main question is: How do I pass the value of sc1_conn_rate(ipsticktable) to the lua function?

Bonus question: Why are all alerts printed twice?

P.Péter
  • 1,527
  • 16
  • 39
  • You should use `txn:get_var("txn.sc1_conn_rate")`. Quote: _The name of the variable starts with an indication about its scope._ Links: [1](https://docs.haproxy.org/2.4/configuration.html#var), [2](https://docs.haproxy.org/2.4/configuration.html#var) – Andrei Vasilev Nov 29 '22 at 09:01
  • @AndreiVasilev This seems to work. If you post it as an answer, I will mark it accepted. – P.Péter Nov 29 '22 at 15:49

0 Answers0