Forum Discussion

1 Reply

  • DavidH's avatar
    DavidH
    Icon for Nimbostratus rankNimbostratus

    It's possible to do something like this with an iRule. The following example for 11.x has been tested up to a few hundred requests/sec and seems to operate adequately if not perfectly. A few points to note;

    • It uses a subtable per core to track cache entries to queue
    • The maximum queue delay is configurable, the example uses 5 sec, adjust this to suit
    • If you get cache-busting query-strings, add these to HTTP_REQUEST_SEND

    As always, this may or may not work in your environment and there are no guarantees.

    ...David

     HTTP Parallel Request Queueing for 11.x v1.0 10/7/15 DIH
    
    when HTTP_REQUEST {
      set path [HTTP::path]
      set query [HTTP::query]
     Need to match the Accept-Encoding value if it exists
     The server probably sets the Vary header...
      if {[HTTP::header exists "Accept-Encoding"]} {
        set uri [HTTP::uri]:[HTTP::header "Accept-Encoding"]
      } else { set uri [HTTP::uri] }
     Check the queue flag, if set we need to queue in front of the cache
      if {[table lookup -notouch -subtable cq_[TMM::cmp_unit] $uri] == 1} {
        set i 1
       Bail out of the loop if the cache fills
        while {[table lookup -notouch -subtable cq_[TMM::cmp_unit] $uri] == 1} {
         Only queue for a maximum of 5 seconds
          if { $i > 25 } {
            log local0. "Exceeded max queue time on core [TMM::cmp_unit] for $uri"
            break
          }
          after 200
          incr i
        }
       After dequeueing a connection, need a short wait for the cache to fill
        after 200
      }
    }
    when CACHE_REQUEST {
      if {[table lookup -notouch -subtable cq_[TMM::cmp_unit] $uri] == 1} {
        if { [CACHE::age] > 0 } {
         Got a cache hit but the queue flag was set - don't panic!
          log local0. "Failsafe: reset table on core [TMM::cmp_unit] for $uri"
         Fix it up and carry on
          table replace -notouch -subtable cq_[TMM::cmp_unit] $uri 0
        }
      }
    }
    when HTTP_REQUEST_SEND {
     Skip cache-busting URIs here
      if { not ($query contains "ca=n") } {
       Cache miss - set the queue flag
        table replace -notouch -subtable cq_[TMM::cmp_unit] $uri 1
      }
    }
    when HTTP_RESPONSE {
     Only enable the RAM cache if the header is set
      if { [HTTP::header exists "CacheOn"] } {
        CACHE::enable
       Create one table entry per core, match the cache timeout
        table add -subtable cq_[TMM::cmp_unit] $uri 0 3600
      } else {
        CACHE::disable
      }
      HTTP::header remove "CacheOn"
    }
    when HTTP_RESPONSE_RELEASE {
     Server reply - clear the queue flag
      table replace -notouch -subtable cq_[TMM::cmp_unit] $uri 0
    }