Forum Discussion
Append to list stored in table key
Hi Piotr,
when doing performance optimization of a certain code block of you should at first define an expected traffic pattern.
If you expect just a few request from each individual IP address, then the "optimal code" would look somewhat different, compared to a code which is optimized to support long living session - where you may expect hundreds or thousands request coming from the same IP or even a single TCP connection.
Once you have figured out your specific traffic mix, you should start to optimize the code so that this specific traffic patter can be handled as fast as possible. The remaining traffic which is not matching the defined pattern may be executed within certain (sometimes deeply nested and most likely CPU intensive) exceptions.
For your scenario I would like to assume, that you need to optimize the code for a few long living connections without having that many IP address changes. So the mission would be to check if the session ID and the current IP address is already known in a single request, without doing math or enforce restriction on each individual request.
if { [table incr -mustexist -subtable "IPs_[HTTP::cookie value SESSION_COOKIE]" [IP::client_addr]] ne "" } then {
Here comes the fast data path for most of the request
Outcome:
Verified that Session ID and IP already exist and it didn't exceed the connection limits.
Collected additional statistics how often the session id has requested content using this IP
return
} else {
Here comes the slow data path for only a handful requests
Crawl the HTTP::cookie(s) a second time but this time store the result
If { [set temp(session_id) [HTTP::cookie value SESSION_COOKIE]] eq ""] } then {
Cookie does not exist!
Do whatever is needed...
return
}
Crawl the table once and store the result
set temp(session_id_counter) [table keys -count -subtable "IPs_$temp(session_id)"]
Evaluate the results and perform action
if { $temp(session_id_counter) eq 0 } then {
Session ID is not known yet since no IP is stored.
table add -subtable "master_table" $temp(session_id) "1" indef indef
table add -subtable "ips_$temp(session_id)" [IP::client_addr] "1" indef indef
} elseif { $temp(session_id_counter) < $static::conf(session_id_limit) } then {
Session ID has a new IP and has not exceeded its limit
table add -subtable "ips_$temp(session_id)" [IP::client_addr] "1" indef indef
} else {
Session ID has a new IP but has exceeded its max IP limit
drop
}
unset -nocomplain temp
}
BTW: Try to avoid variable usage as much as possible. Only use them if consecutive usage would save CPU cycles. When needing them try to use arrays (e.g. arrays(key_name)), they do have a lot of benefits compared to classic variables (e.g. faster unset for a group of variables, less usage of [eval] to build the name on the fly, etc.)
Cheers, Kai
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com