Forum Discussion

IheartF5_45022's avatar
Mar 14, 2014

Queuing traffic in iRules - advisability!!

I posted this codeshare recently which is a pair of iRules which queue requests in front of WAM with the idea being that when they are released the request will be in cache and served from cache, using the entries in the session table as kind of semaphore to signal when a page request was in progress. The purpose of this was to reduce spike load on the backend servers when page objects expire from WAM cache, as the backend system is a CMS for which assembling new pages is relatively CPU-intensive. I haven't deployed this to a production system yet but it's very close to it.


I today stumbled upon a few discussion threads from a few years ago which have alarmed me, to say the least, all saying DON"T do what I have done ie;-


Now, I suspect (hope) that the introduction of command suspension will have alleviated some if not all concerns on this front, but I'd like some prompt advice on the topic!!


7 Replies

  • i wonder if you could instead of using while or for loops (dangerous as these threads indicate) you could build a system of dummy pools that have artificially low max counts and use the built-in queuing mechanisms in pool configuration.
  • Thanks Jason - that's an interesting suggestion and I'll look into it, but I just need clarification that even with 'after' now being a suspending command it's still not recommended running loops of 'after' statement?


    Wouldn't the previous concerns from 2008 "iRule execution is single-threaded, so if you did somehow pause execution (like run a tight wait-loop as someone suggested), then you would be holding up all other packet processing. The multiple watchdogs on the LTM would notice this, and take appropriate action (restart tmm, or failover, or reboot, or some combination thereof)." be nullified now that 'after' is suspending?


    I've done some medium-level testing where I've had 50+ queued connections all running the after loop and no watchdog processes kicked in, although perhaps I wasn't running enough traffic to trigger that behaviour.


    Are there other concerns that I haven't taken into consideration?


  • suspending commands like after and RESOLV::lookup are parked outside the event loop so they do not harm them flow while waiting for actions to occur. For non-suspending commands, like while and for, everything gets stacked behind that bus. A while loop that cuts through 200 counts, really no big deal. However, we've seen people (and by people, I mean me before I was edumacated on this!) suggest or implement for loops that bleed for seconds or longer, and at some point daemons get involved and bad things happen.


    Colin wrote up connection state & suspension concepts a while back, hopefully this will help.


  • That sounded like it had potential at first, but once I thought about it - I need to queue my requests in front of cache, however if I use the pool connection queuing mechanism, my requests will get queued behind cache, so no good.
  • Thanks for the update and the link.


    So how does an 'after' within a 'while' loop get treated? Does each execution of the 'after' result in connection suspension? Or because the 'after' is being executed within the context of a blocking command (while), does it in itself become blocking?


    Will the following code block solidly for up to 120s? Or will it suspend 600 times?


    set i 1
    while {[table lookup "mytable"] ne "" } {
        if {$i > 600} {
             Ensure a single request can never keep queuing beyond 600 iterations
        after 200
        incr i
    • JRahm's avatar
      Icon for Admin rankAdmin
      in this particular case, the after within the while loop parks and so tmm is free to go do its thing.