Forum Discussion
DavidH
Aug 18, 2015Nimbostratus
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
}