Forum Discussion

dragonflymr's avatar
dragonflymr
Icon for Cirrostratus rankCirrostratus
Dec 14, 2015

Append to list stored in table key

Hi,

First of all I wonder if this is good idea to store list in sub/table key - considering performance nad memory consummatum. Let's say it could be list containing no more that 10 IPs.

Second I wonder if there is faster more elegant way to actually add new value to the list. My idea is:

 

set c_val [table lookup -subtable ip [IP::client_addr]]

lappend c_val $new_val

table set -subtable ip [IP::client_addr] $c_val

 

Seems to be a lot overhead here, so maybe there is better way?

Piotr

20 Replies

  • Hi Piotr,

    Sorry didn't want to confuse you... 😉

    The code above is just a sample code based on some of your previous questions (aka. master table), but also contains the handling of IPs per session_id table entries. The important part of this code is, that you could check a lot of things in a single [table] query to speed up the processing of most of your requests and that you could hide the complex stuff (e.g. counting limits, creation new session_id and master_table updates or new IP_addr entries) as an exception to this initial [table] query. The task of the exception code path is then to analyze why the initial [table] query has failed and then correct this situation, by inserting additional session_id or IP_addr, so that the very next request from the same session_id and IP_addr could be handeled using the fast single [table] query.

    Basically you should try the fastest method first (because it should work most of the time), then catch the possible errors/exceptions/empty results followed by an analyses of whats was going wrong and a fix to make sure the next request won't fail again. The opposite approach would be to perform a rather complex error handling on each request to make sure that the used [table] query never fails...

    Regarding $temp(session_id_counter). This is not a statement, it an [array] variable that can be used as an alternative to classic variables. The handling would look like this....

    set temp(var1) "value1" set temp(var2) "value2" lappend temp(var2) "value3" set temp(var_index) [array names temp -glob "value*"] unset temp(var3) unset temp etc.

    And yes, it is somewhat hard to get a feeling of which command is faster than the other. The available information is unfortunately distributed across the internet and spanning a lot articles, different wiki sites and forum posts. But even if you found some information then it may be already outdated... So in the end you may want to measure the performance of each code block by yourself, using Event timing on or [clock clicks] timestamps with or without some additional [while] or [for] loops. Over the time you'll get the experience which code block should be used for a given scenario...

    BTW: [drop] is working. But you can't send a [HTTP::respond] and [drop] at the same time. BTW2: The -nocomplain option could be skipped in this case. But I tend to use this option in most cases...

    Cheers, Kai

  • Thanks Kai, I need do dive dipper in all nuisances - as you mentioned, knowledge is spread among many articles, sometimes it is hard to figure out which are outdated and which are current. It's hard for me to understand all the code because it's not my area of competence - at least not during last 20 years. Trying to keep up as fast as possible but... I am sick right now so it's hard to master analytic skills, but will try hard. What is great about this forum that there are people that devote time and patience to help and explain things to newbies like me - really, really I am appreciating all this effort, you guys are just amazing!!

     

    Piotr

     

  • Thanks Kai, I need do dive dipper in all nuisances - as you mentioned, knowledge is spread among many articles, sometimes it is hard to figure out which are outdated and which are current. It's hard for me to understand all the code because it's not my area of competence - at least not during last 20 years. Trying to keep up as fast as possible but... I am sick right now so it's hard to master analytic skills, but will try hard. What is great about this forum that there are people that devote time and patience to help and explain things to newbies like me - really, really I am appreciating all this effort, you guys are just amazing!!

     

    Piotr

     

    • Kai_Wilke's avatar
      Kai_Wilke
      Icon for MVP rankMVP
      Hi Piotr, solving your questions makes more fun than solving x-word puzzles. So you're very much welcome! ;-) Cheers, Kai
  • Kay,

    I am stuck with static array usage:

    { $temp(session_id_counter) < $static::conf(session_id_limit) }

    I tried to define this array in RULE_INIT using:

    set static::conf(session_id_limit) 5

    but when saving I am getting such error:

    Dec 16 16:56:50 bigip11 err tmm[5640]: 01220001:3: TCL error: /Common/test_kay_table_log - can't set "static::conf(session_id_limit)": variable isn't array while executing "set static::conf(session_id_limit) 5"

    I can use set ::conf(session_id_limit) 5 but then iRule is demoted from CMP.

    Can't find right way to define static array but for some strange reson when I use:

    set static::conf_my(session_id_limit) 5

    there is no error??

    Piotr

    • Kai_Wilke's avatar
      Kai_Wilke
      Icon for MVP rankMVP
      Hi Piotr, if "conf" is already defined as classic variable [set conf 1] then you can't change it or add stuff to it using [set conf(abc) 1]. Try [unset -nocomlain conf] then use [set conf(abc) 1] again. Cheers, Kai
    • dragonflymr's avatar
      dragonflymr
      Icon for Cirrostratus rankCirrostratus
      Strange, I can't see any set conf in my code. I assume that set conf is not the same as set static::conf, and I for sure do not have any static::conf defined. Weird. Piotr
    • Kai_Wilke's avatar
      Kai_Wilke
      Icon for MVP rankMVP
      Sorry for confusion. The above command was just an example to show the behavior of classic and array variables. $conf is not the same as static::conf but may be the same as ::conf ;-) So change the "Try [unset -nocomlain conf] then use [set conf(abc) 1] again" to " Try [unset -nocomlain static::conf] then use [set static::conf(abc) 1] again". Alternativly you may crawl the variable of the static namespase using [info vars static::co*] and then check the contained variable with [array exists static::conf] Cheers, Kai BTW: Just created static::conf(abc) in my own environment. At least its working for me...
  • Thanks, will try with unset. Anyway I am getting grip on how to use arrays :-)

     

    Piotr

     

  • Hi Piotr,

    arrays can be very much handled like classic variables. The differences are not that much, but they the will also add certain functionality that you should remind when writing more or less complex code.

    • $array($var_name), $array($var_name1$var_name2(key1)) or $array([command]) will work without using [eval].
    • $array(quick brown fox) will work without tranforming the spaces.
    • [unset array] will unset every contained entry in one step.

    Because of the [unset] feature I tend to organise my code using $reqest(var_names), $temp(var_names) and $connection(var_names), where...

    • the $temp(keys) MAY be flushed after each request to free memory.
    • the $reqest(keys) MUST be flushed at the beginning of each request.
    • the $connection(keys) MUST persist for the entire connection. But a single key MAY be erased as needed.

    Using this scheme makes variable handling very comfortable and much more effective compared to regular variables^^

    Cheers, Kai