Forum Discussion
BlurredVision_1
Nimbostratus
Mar 11, 2008HTTP Double Dipping...
All,
I know this is a crazy corner case, and that there are probably 100 ways to do this with the app, the application guys are looking for some f5 lovin to get this working as a short term workaround (I have been talking up iRules for so long, I think they decided to make me put my money where my mouth is!!)
I have an application owner who needs to run extended QA n the new version of a server while maintaining the old version as the production system for a while. Long story short, it is a web services environment that they need to run 2 versions of the application side by side on the same data stream. The aim is to have the same WS transactions run against V1 and V2 one after the other, but for V1 to be the one that is actually carried back to the requesting server. (ie: to start with V1 is authorative, V2 is run, but the responses are ignored)
So far the config has a VS with a 2 pools of 1 server (v1 and v2).
Using an iRule, we have managed to get the following workflow:
iRule INIT
set loop 0
set lb_run 0
when HTTP_REQUEST
UNCHUNK
stuff HTTP::request into a var
if loop == 0
select pool V2
if loop == 1
select pool V1
when HTTP_RESPONSE
if loop == 0
incr loop
HTTP::retry $var
when LB_SELECTED
if loop == 0
if lb_run == 0
LB::reselect pool v2
set lb_run 1
else
LB::reselect pool v1
I know there is some weirdness in the logic of the flow, but I am still not 100% sure how the rule events hang topgether.
output of this rule runs correctly the first time, but as the key vars are established in irule init, it gets stuck in the second iteration as the deafult state.
I tried to reset the loop and lb_run counters in various places, but it ends up looping.
Where should I be looking to reset the state of the loops to get it to run properly again.
Full iRule as follows:
when RULE_INIT {
outputs useful information to logs when debug is set to 1
set ::debug 1
set ::first_lb_selected 0
set ::iteration 0
}
when HTTP_REQUEST {
unchunk
HTTP::version "1.0"
if { $::iteration == 0} {
set creq [HTTP::request]
if { $::debug } { log local0. "HTTP_REQ at ::iteration 0" }
pool Pool-V2
}
if { $::iteration == 1} {
if { $::debug } { log local0. "HTTP_REQ at ::iteration 1" }
pool Pool-V1
}
}
when HTTP_RESPONSE {
if { $::debug } { log local0. "HTTP_RES triggered" }
if { $::iteration == 0 } {
if { $::debug } { log local0. "HTTP_RES at ::iteration 0" }
if { $::debug } { log local0. "HTTP_RES lb detach:" }
LB::detach
if { $::debug } { log local0. "HTTP_RES set ::iteration to 1" }
set ::iteration 1
if { $::debug } { log local0. "HTTP_RES retrying" }
HTTP::retry $creq
}
if { $::debug } { log local0. "This is the last line!" }
if { $::first_lb_selected == 1 && $::iteration == 1 }{
set ::first_lb_selected 0
set ::iteration 0
}
}
when LB_SELECTED {
if { $::debug } { log local0. "LB::server is [LB::server addr]" }
if { $::iteration == 0 } {
if { $::first_lb_selected == 0} {
if { $::debug } { log local0. "LB_Selected at ::iteration 0 setting GP10" }
LB::reselect pool V2
set ::first_lb_selected 1
}
} else {
if { $::debug } { log local0. "LB_Selected at ::iteration 0 setting GP7" }
LB::reselect pool V1
}
}
- Nicolas_Menant
Employee
Hi, - BlurredVision_1
Nimbostratus
Worked a charm.. here is the final iRule for the annals of history:when RULE_INIT { HTTP Double Dip Turn logging on or off (0=off, 1=on) set ::debug 1 if { $::debug } {log local0. "" } } when CLIENT_ACCEPTED { set retrying 0 if { $::debug } {log local0. "Resetting Iteration and Replay to 0"} } when HTTP_REQUEST { if { $::debug } {log local0. "Entering HTTP_REQUEST" } Unchunk set HTTP::version "1.0" if { $::debug } {log local0. "Setting HTTP version 1.0" } Store the request into a variable set request [HTTP::request] if { $::debug } {log local0. " HTTP Request: $request" } check to see if replay trigger is set if { $retrying == 0 } { If replay trigger *IS NOT* set, play the connection to V2 first pool Pool-V2 if { $::debug } {log local0. "Retrying = $retrying, sending request to [LB::server pool] " } } elseif { $retrying == 1} { If replay trigger *IS* set, play the connection to V1 pool Pool-V1 if { $::debug } {log local0. "Retrying = $retrying, sending request to [LB::server pool] " } } if { $::debug } {log local0. "Leaving HTTP_REQUEST" } } when HTTP_RESPONSE { if { $::debug } {log local0. "Enternig HTTP_RESPONSE" } if { $::debug } {log local0. "HTTP Response from [LB::server pool] of [HTTP::status]" } Check to see if we are set to play to V1 if { $::debug } {log local0. "Starting Retrying assesment." } if { [ LB::server pool] eq "Pool-V1" } { if { $::debug } {log local0. "Response is from [ LB::server pool ] " } set retrying 0 return } else { set retrying 1 if { $::debug } {log local0. "Retrying = $retrying" } if { $::debug } {log local0. "Initiating HTTP::retry" } HTTP::retry $request } if { $::debug } {log local0. "Exiting HTTP_RESPONSE" }
- Nicolas_Menant
Employee
Hi,
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects