on 28-Nov-2007 23:01
In the first part of this series, we discussed the various components of an iRule and specifically how we have implemented the concept of events in the TCL language. The "when" command is used to define a block of code associated with a given event and in this article I'll go over the commands usage and optional arguments. Other articles in the series:
SYNOPSIS
when EVENT_NAME ?options? {body}
DESCRIPTION
The when command is used to define a block of code to be executed if and when a specific state, specified by event_name, occurs within the packet path of a connection through the BIG-IP. We refer to these "states" as "events". An iRule must consist of one or more when commands.
The list of available events can be found in the Event reference section of the iRules documentation. Events such as CLIENT_ACCEPTED and CLIENT_CLOSED are available for all virtual server configurations while others such as HTTP_REQUEST and CLIENTSSL_CLIENTCERT are only applicable when associated profiles are part of the virtual server's settings (the http and clientssl profiles respectively). The RULE_INIT event is special in that is occurs once at configuration load time and is not tied to the connection. All variables created in the RULE_INIT event are in the global scope (as opposed to connection based variables).
The following options are currently supported:
The priority is an optional attribute associated with any iRule event. When the iRules (one more multiple) are loaded into the internal iRules engine for a given virtual server, they are stored in a table with the event name and a priority (with a default of 500). When a situation occurs that will trigger an event, the engine will pass control to each of the event blocks for that given event in the order of lowest to highest priority. Multiple events with the same priority will be executed in the order they are inserted into the table. The valid values for the priority are 0 to 1000 inclusive. The main feature for segmenting your logic into multiple "like" event blocks is to allow code reuse across multiple virtual servers. The default value for the priority attribute is 500.
The timing command can be used to enable iRule timing statistics. This will then collect timing information as specified each time the rule is evaluated. Statistics may be viewed with "b rule <name> show all" or in the Statistics tab of the iRules Editor. You'll likely only want to look at the average and min numbers as max is often way, way out there due to the optimizations being performed on the first run of the rule. Additionally, enabling timing does have some overhead, though it should be negligible. The default value for the timing attribute is "off". The timing argument is also a special command that can be placed at the start of an iRule before all when commands. The usage is the same as the argument, but in the case where it is specified at the top, it changes the default to either "on" or "off", depending on what is specified.
The body is a block of TCL code containing core TCL commands as well as F5 developed iRule TCL commands. For a reference of all available commands, see the command reference in the iRules wiki.
EXAMPLES
when RULE_INIT { # this is a global variable set ::TRACE 1 # this is a global variable as well set DEBUG 1 } when HTTP_REQUEST priority 100 { # With the lowest priority, the event code will get executed first # Timing is not specified, so it is off as it's default. # the following variables are connection based, not global. # To make them global, prefix them with double colons ("::"). if { [HTTP::uri] starts_with "/login" } { set ATTEMPTING_TO_LOGIN 1 } else { set ATTEMPTING_TO_LOGIN 0 } } when HTTP_REQUEST priority 200 timing on { # This will get executed second when a HTTP request state is entered # CPU Metric timing is also enabled for this iRule event block log local0. "Request Event 2 - login state: '$ATTEMPTING_TO_LOGIN'" } when HTTP_REQUEST timing on { # The priority is not specified so it defaults to 500 and this will get executed last. # CPU metric timing is also enabled for this iRule event block unset ATTEMPTING_TO_LOGIN }
timing on when HTTP_REQUEST { log local0. "Timing is on due to global default set to on". } when HTTP_RESPONSE timing off { log local0. "Timing is turned off for this event block. }
CONCLUSION
If you've seen an iRule, you will no doubt see the when command in action. With knowledge of how multiple "like" event blocks can be prioritized allows for modular development of your iRules and understanding how timing works, will allow you to more easily profile your iRules when you want to squeeze every bit of performance out of them.
Is this just an artifact of the example, or bad programming?