Forum Discussion
Frank_Mancini_3
Nimbostratus
Mar 11, 2008Irule that waits?
Is it possible to write an iRule that has a wait time of 25 seconds before proceeding to the next step?
22 Replies
- Nicolas_Menant
Employee
i would be curious to see how you will handle global data through multiple TMM since it's stored on the TMM by default ! - Chris_14455
Nimbostratus
We have found that it is NOT single threaded. Or at least what we are trying to do with it is not.
My question was going to be "Is there an iRule syntax for Semiphores/Mutexs?"
And the reason is that we have found in our case that concurrent access is a problem.
We have a token (similar to an HTTP session id) that is shared between users. That token is used to lookup the node for which all of these users should be connected.
Problem is that the first user to come through with any given token will find that there is no existing node assigned and thus will use the least connection algorithm to define the node for that token. The idea that all subsequent users with the same token would be sent to the same node is what we are trying to get.
The problem is that apparently some piece of this process is not concurrent safe as concurrent access has PROVEN to send one user to one node and the rest to another node. This occurs when two threads are attempting to determine the least connections at the same time over writting each other in the mapping table afterwards.
Anyway, if there is a capability to make it single threaded or a Mutex/Semiphore capability that would be great. - spark_86682Historic F5 AccountFrom your description, this sounds like a pretty straightforward UIE persistence setup, and so it should just work. Are you doing all of your decision making AND node lookup AND node selection AND node recording in the same iRule event? If not, then that could be the source of your problem. Which version are you running? Could you also post at least a simplified version of your iRule?
- Chris_14455
Nimbostratus
Here is the iRule.. Pretty basic.. - spark_86682Historic F5 AccountThanks for posting that. As I suspected, the problem that you describe is happening because you are spreading your actions across iRule events.
So, what's happening is:
1) Client A comes in with new SessionID 12345
2) The CLIENT_DATA event notices that the ::auctiontable doesn't have an entry for that SessionID, does a load-balancing selection, and starts to connect to that server.
3) Client B comes in with that same SessionID.
4) The CLIENT_DATA event notices that the ::auctiontable *still* doesn't have an entry for that SessionID, does a (new, different) load-balancing selection, and starts to connect to that (new, different) server.
5) The first server connection completes, thus adding that entry to the ::auctiontable for SessionID 12345.
6) The second server connection completes, thus overwriting that entry to the ::auctiontable for SessionID 12345.
So Client A and Client B get sent to different servers even though they have the same SessionID. To fix this, you can move all the "set ::auctiontable($SessionID)" logic and put it in the CLIENT_DATA event. That way, in step 4 above, there will be an ::auctiontable entry, and Client B will get sent to the same server as Client A. - Chris_14455
Nimbostratus
I see.. At that point I guess my question would shift from concurrency to how I might be able to determine where a least connections load balance would go from within the CLIENT_DATA event? Currently, we set it after it is connected. Of course we could set it from the CLIENT_DATA even if we knew what it would select?
Any advice?
Thanks by the way.. - spark_86682Historic F5 AccountI don't think it's possible to know what the load-balancing decision is/will be in the CLIENT_DATA event. What you might be able to do instead is leverage the LB_SELECTED event, where you can use the LB::server command. I don't know exactly what you're now looking to do, but one possibility is to record the SessionID in CLIENT_DATA, but do all your selection logic in LB_SELECTED, overriding the load-balancing decision if your array already has an entry in for the SessionID.
- Chris_14455
Nimbostratus
Yea our problem is one of timing. In the CLIENT_DATA we parse the request for a token. We use that token to lookup the node we should load balance the request to. However, if there is no mapping at that point we would like to load balance the request to the least used server. All subsequent requests with the same TOKEN would then get sent to the same node.
Note in this case the token is shared by multiple users and the request only occurs on connect. Connections are long lived like an SSH/Telnet session.
Now as it stands today we do the select in CLIENT_DATA if there is one defined already. If not we attempt to load balance it at which point we set it after it is known. The timing issue comes as a result of the separation of get/set. Unless we do both the get and the set in the same event we will run into concurrency issues correct?
Our current train of thought would be to check the session table when we attempt to set the value. If it is still null at the point we are attempting to write to it everything is good. However, if its not null then we know we had a concurret connect and its the second one that needs to be adjusted. Obviously the problem with this is that we are already connected so the only way we could adjust the connection is by breaking one side of the link or both. Thats doable but not desireable.
Now you suggest we look at the LB_SELECTED. I suppose we could do the same thing there. Aka set the value (assuming its available of course) if and only if the session table is still null. If it is not null then override the selected node with the one from the table? Once that was complete the connection process continues with that new node?
Of course it gets more complicated. If the connection fails we clear the record and restart. Aka our session table lives for as long as the node is up. Its down state is detected by a failure to connect. Assuming we have no false positives there I suppose we could make that work too.
Ideas/suggestions? - The_Bhattman
Nimbostratus
Can you post your code so we can take a look at what you have come up with so far?
/CB - Chris_14455
Nimbostratus
OK I have modified the original code to one I think may work better. I have attached it.
Does the LB_SELECTED event occur before the client is actually connected to the server?
Also does setting the specific pool and member result in the LB_SELECTED event being fired or does it only get fired when a standard load balancing algorithm does the selection?
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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
