Table timeout/lifetime Not Reflected in -count
I am attempting to build an IRULE that functions as a gate keeper, limiting the number of active sessions at any given point in time.
I am using a sub-table to manage each session. When the count of keys is less than some threshold, the request is allowed, a UUID is established, a cookie is set with the UUID, and a table entry is created using the UUID as the key and with timeout/lifetime X. If that same UUID accesses a certain URI, the timeout/lifetime is reset to Y. Otherwise, the table entry is expected to timeout, thus lowering the count of keys.
Under a controlled environment, this works as expected, and I can predictably identify when a session is active and/or blocked. However, within production and under load, the count of keys never goes down. Here's the kicker: if I iterate over the keys and calculate the count myself, the value aligns with expectations! Unfortunately this technique performs poorly and impedes functionality.
Below is an excerpt from the log, where:
[Dis]Allowing request: [Domain] | [URI Milestone] | [Manual Key Count] v [Table -count] | [Has UUID] | [Remaining Lifetime] | [UUID] | [Is Bot]
Sat Feb 4 14:46:11 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 119 v 16355 | 1 | 318 | UUID9 | -1
Sat Feb 4 14:46:11 CST 2012 info local/tmm2 tmm2[6171] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 119 v 16355 | 0 | 152 | 0 | -1
Sat Feb 4 14:46:11 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 119 v 16355 | 0 | 152 | 0 | 6
Sat Feb 4 14:46:12 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 117 v 16355 | 0 | 151 | 0 | 31
Sat Feb 4 14:46:12 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 117 v 16355 | 0 | 151 | 0 | -1
Sat Feb 4 14:46:12 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 117 v 16355 | 0 | 151 | 0 | -1
Sat Feb 4 14:46:12 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | | 117 v 16355 | 1 | | UUID7 | -1
Sat Feb 4 14:46:12 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | | 118 v 16356 | 1 | | UUID5 | -1
Sat Feb 4 14:46:12 CST 2012 info local/tmm tmm[6169] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 119 v 16357 | 1 | 320 | UUID5 | -1
Sat Feb 4 14:46:13 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 118 v 16357 | 0 | 150 | 0 | 31
Sat Feb 4 14:46:13 CST 2012 info local/tmm tmm[6169] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 118 v 16357 | 1 | 310 | UUID3 | -1
Sat Feb 4 14:46:13 CST 2012 info local/tmm3 tmm3[6172] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 118 v 16357 | 1 | 303 | UUID1 | -1
Sat Feb 4 14:46:13 CST 2012 info local/tmm tmm[6169] Rule IRULE_GateKeeper : Allowing request: www.mywebsite.com | Default | 118 v 16357 | 1 | 205 | UUID0 | -1
Note the massive discrepancy between the two session key counts.
Below is the code...
Making the table entry:
; declare session table values
set table_uri "Default"
set table_timeout $tier1_timeout
set table_mode "add"
if {[HTTP::path] contains "OrderReceipt" } {
; if request URI corresponds with Order Receipt page
set table_uri "Receipt"
set table_timeout $tier4_timeout
set table_mode "set"
} elseif {[HTTP::uri] contains "Checkout"} {
; if request URI corresponds with Checkout action
set table_uri "Checkout"
set table_timeout $tier3_timeout
set table_mode "set"
} elseif {[HTTP::path] contains "AddToCart"} {
; if request URI corresponds with an Add to Cart action
set table_uri "Add2Cart"
set table_timeout $tier2_timeout
set table_mode "set"
}
table $table_mode -subtable $table_subname $client_id $table_uri $table_timeout $table_timeout
Calculating the key count:
set session_count_native [table keys -subtable $table_subname -count]
set session_count 0
foreach { key } [table keys -subtable $table_subname] {
set key_timestamp [table lookup -notouch -subtable $table_subname $key]
incr session_count 1
}
And the log entry above:
log local0. "Allowing request: $host | $session_value | $session_count v $session_count_native | $has_uuid | $session_life | $uuid | $is_bot "
The F5 seems like the simplest and most appropriate layer to enforce this type of logic. Anything you can offer to help troubleshoot this concern will be GREATLY APPRECIATED.
Thank you