Class ordering in an iRule

When writing your iRules there are many different ways that you can store information to memory. Whether you decide to use standard variables, the session table, class files, arrays or something else entirely one thing is for sure, there are many choices. Each option has it's own pros and cons. Most of these structures are standard TCL implementations, and act just as you'd expect. One that is a bit unique, in that we implemented it here at F5 specifically for use with iRules, is the class structure.

Classes (also called Data Groups) were designed with two things in mind: ease of use, and efficiency. The idea was to give people a simple way to input information into a structure via the GUI or CLI to later be accessed via an iRule. This was accomplished and classes are used quite regularly in many iRules, every day. They're easy to maintain and update, they're efficient, and they're widely accepted. This has led to some confusion though, in a couple cases, as people are using them for more and more advanced data processing tasks, and there's some uncertainty about how Classes are actually structured.

The confusion presents itself in that people sometimes expect the order of the information they input into a class to remain the same. They want to be able to loop through the elements in the class, from top to bottom, and get a reproducible result. This just isn't the way that classes were built. See, classes are based on hashes, which are ideal for the high-paced, repeated operations that classes are intended to be used for, but hashes also iterate through the contained elements in an unpredictable manner. When you're looking to access large lists of data many times looking for specific things, hashes are fantastic. If you need things presented in a certain order, however....not so much.

What does all of that mean? It means that you can't just assume that the data in your Data Group is going to come out in the same order it got put in. This means you can't just cycle through the elements and assume it's going to go from top to bottom. This isn't usually an issue, as most folks don't operate solely on the order of information in a class, but what if you have the same iRule on multiple boxes? Would it confuse you if the processing didn't happen the same? It shouldn't.

Take a look at this example. This is a simple iRule that will step through each element in a class and log the value of it:

when CLIENT_ACCEPTED {
  foreach element $::myClass {
    log local0. "$element"
  }
}

The class for this simple iRule would look like:

class myClass {
  "element1"
  "element2"
  "element3"
  "element4"
}

Here's the fun part. That exact information could be on three separate systems, and while one log file read from "element1" to "element4" the other could quite easily read from "element4" to "element1". And a third system could read "element2" first, then 1, then 4, then...you get the idea. This is, as I mentioned earlier, due to the nature of the class files being based on a hash structure.

"But what if I want them the same?" You ask? Well, then you'd want to convert that hashed Class into a different structure, such as a list, so you can step through it in a more organized manner. That conversion in and of itself will have a performance hit, though, as well as the decreased performance of a TCL list compared to a hashed structure like Classes are by default. Make sure to keep that in mind if you're ever trying to get crafty and lsort these things out.

Published Sep 12, 2008
Version 1.0

Was this article helpful?

1 Comment

  • Thanks for a very good description as I was assuming class entries would retain their order.

     

     

    So I have a question from an example I found on DevCentral to obtain the value of a list entry once I matchclass on it. Once I recieve the index, will I reliably be able to obtain the value as in the example:

     

     

    set idx [matchclass $myURI starts_with $::class_redirect]

     

    set idxtxt [lindex $::class_redirect [expr $idx - 1]]

     

     

    will 'idxtxt' contain the value matched?

     

     

    thanks..