Forum Discussion

Chad_Roberts_21's avatar
Chad_Roberts_21
Icon for Nimbostratus rankNimbostratus
Jun 14, 2006

Pools and Persistence

I'm having a persistence issue with an iRule I am testing on a site that will be partially inaccessible on holidays. The code below is part of an experiment to find the syntax that will make this work. Note that this assumes that there is a group list containing holiday dates in a mm/dd/yy format.

 

 


when HTTP_REQUEST timing on {
  if { ([HTTP::uri] starts_with "/sc/") } {
    set current_date [clock format [clock seconds] -format {%D} ]
    
    if {([matchclass $current_date equals $::Holidays ] )} {
      HTTP::uri "/offhour.html"
      log "Blocked for holiday"
      persist none
      pool after_hour_pool
    }
    else {
      log "Access to SC allowed"
    }
  }
}

 

 

By itself, it appears to work great... if you open a browser and go to https://my.domain.com you can connect at any time, and if you open a browser from scratch and type https://my.domain.com/sc/ (and the day's date is matched as a holiday) the uri is rewritten correctly and your traffic is forwarded to a different pool, so you receive a page that says the site is unavailable.

 

 

However, the problem is this: if you open a browser, go straight to the restricted page, receive the after hours error, and then immediately try to go to https://my.domain.com/ without closing and reopening the browser, the traffic continues to be sent to the pool for the server that contains only the error page. I thought the inclusion of "persist none" would resolve the issue, but it has not helped. Any ideas?

8 Replies

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    You need an outer else clause for when the HTTP::uri does not start_with "/sc/" that resets the pool to the default pool:
    when CLIENT_ACCEPTED {
       set default_pool [LB::server pool]
    }
    when HTTP_REQUEST {
       if { [HTTP::uri] starts_with "/sc/" } {
          ...
       } else {
          pool $default_pool
       }
    }
    Persistence has more to do with subsequent connections than with subsequent requests within the same keep-alive connection. The connection to the server is kept open until the pool selection actually changes (or OneConnect is configured).
  • I hear what you're saying, but I'm afraid it didn't affect my problem. I updated the code as you recommended:

     

     

    when CLIENT_ACCEPTED {
      set default_pool [LB::server pool]
    }
    when HTTP_REQUEST timing on {
      if { ([HTTP::uri] starts_with "/sc/") } {
        set current_date [clock format [clock seconds] -format {%D} ]
        
        if {([matchclass $current_date equals $::Holidays ] )} {
          HTTP::uri "/offhour.html"
          log "Blocked for holiday"
          persist none
          pool after_hour_pool
        }
        else {
          pool $default_pool
          log "Access to SC allowed"
        }
      }
    }

     

    But the same thing still happens.
  • I meant to mention that I thought that might be what you meant but that I tried that too. Actually, when you just bump it one level back, it negates the pool command from within the if statement.

    However, while I awaited your reply, I realized the solution to that problem. I simply need to start the HTTP_REQUEST script with a pool definition and negate it instead when the if statement matches. It finally works using this:

    when CLIENT_ACCEPTED {
      set default_pool [LB::server pool]
    }
    when HTTP_REQUEST timing on {
      pool $default_pool
      if { ([HTTP::uri] starts_with "/sc/") } {
        set current_date [clock format [clock seconds] -format {%D} ]
        
        if {([matchclass $current_date equals $::Holidays ] )} {
          HTTP::uri "/offhour.html"
          log "Blocked for holiday"
          persist none
          pool after_hour_pool
        }
        else {
          log "Access to SC allowed"
        }
      }
    }

    Thanks for your help! You've saved me again.
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Doesn't the "pool" command load balance the request to that pool immediately?

     

     

    I was under the impression that the "pool" command had to come after all the relevant conditions had been considered because it will do just that, thus inserting it at the top of the REQUEST event would effectively bypass any later conditional pool selection.

     

     

    Wiki definition of pool command says in part: "Causes the system to load balance traffic to the specified pool." (it also says must be conditional, which isn't exactly true... but maybe it means what I'm so eloquently trying to spit out above?)

     

     

    I guess my real question is, is the request actually released to the selected pool at the end of a specific event, rather than with the use of the "pool" command as I've assumed all along?

     

     

    thanks for making us smarter!

     

    /deb
  • That's what I thought too before this experiment, but as I mentioned before when I put one pool command within an if statement and then another after the if statement concludes, the second one overwrites it every time. When I rewrote it so that I started off with a pool command that only confirmed what the virtual server already had defined and then included another one within the if statement, the second one took over when the conditions were met, otherwise all new traffic (even within the same keep-alive session) used the default pool.
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    No, the pool command only "sets" the pool to use.

     

     

    Answering your question is a little more tricky though. This is because it depends on what other profiles are in play. Basically, a connection is accepted up through the layers and when that finally reaches the proxy, the LB decision is made.

     

     

    So, for example, you might select the pool in CLIENT_ACCEPTED. This doesn't mean that the load-balancing will occur at the end of the CLIENT_ACCEPTED event, because if you have HTTP also configured then the HTTP_REQUEST event is triggered first. So, you could actually change the pool selection again in the HTTP_REQUEST event. Generally, there's not another layer above HTTP, so, usually the load-balance does happen after HTTP_REQUEST. But, you can't always count on that. For example, there is the XML profile that might hold until a certain XML tag is found and can then influence the load-balance decision.

     

     

    Thanks for asking this. It just goes to show that there is probably at least some misundertanding about it. Also, I'm sure you were probably thinking this was the case because 4.x worked like that.

     

     

    HTH
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Wow, that's really good to know.

     

     

    I've been setting an extra variable to manage conditionally changing pool selections, and most likely have been imposing some unnecessary constraints on the logical flow in some cases due to my misguided assumptions.

     

     

    Thanks again for cluing us in!

     

    /deb