I'm sure we've all worked on, or are aware of web applications (especially in the enterprise) that have tightly bound themselves to the server session. In these cases, it's possible that the session will become corrupted if more than one browser session is open and using the same server session cookie. We've examined all of the options and found the best way to move forward would be to discourage the use of multiple browser sessions that share a server session cookie.
This is only really a problem when a user executes New Window - Ctrl+N
in IE or the equivalent of "duplicate tab" in other browsers. Essentially we end up with two active browser sessions sharing the same cookies.
So, to discourage this (as it will likely be inadvertent) I've set out to put some kind of warning system in place to prevent this behavior. Now, our code does plenty of concurrency checking to ensure data integrity, but there can still be issues with data corruption.
My solution, after finding that the general answer is "it's impossible" was to rely on AJAX to send out "pings" and measure the time between. So, we have a general rule: we "ping" at a certain interval and if the delta between the last ping in the current ping is less than the ping duration, we know we have multiple active browser sessions on a single server session.
So, where Pf
is ping frequency; Pc
is current ping; and Pl
is last ping, then we have an error when Pf > (Pc - Pl)
.
p1 p2 p3 p4 TAB1 0-----|-----|-----|-----|---... : : : : p1 : p2 : p3 p4 TAB2 0-----|-----|-----|-----|---... ^ ^ ^ ^ ^ ^ ^ ^ Deltas
----+---+------------ TAB | P | Delta (Pc - Pl) ----+---+------------ 1 | 1 | 5 1 | 2 | 5 2 | 1 | 2.5 -Error 1 | 3 | 2.5 -Error 2 | 2 | 2.5 -Error
Now, if there is network congestion or other factors, then the delta will be greater than the frequency, ruling out false-positives.
We do have a problem if two tabs are open at the exact same momemnt. But, since the ping frequency is just the frequency at which the requests are made, and not a guaranteed elapsed time, we can assume that soon the two browser sessions will begin sliding out of sync.
In the example, I have the ping frequency set to every 5 seconds. If there are 100 simultaneous users then we're lookiing at ~20 requests/second for the ping Servlet/HttpModule. To minimize unnecessary network traffic I was thinking that the ping frequency would decay as time went on until a maximum of 20 pings/second was reached. This would amount to ~5 requests/second with 100 concurrent users. This is a trade-off, though, as it will cause a delay in detection. However, once detection occurs, the frequency resets to 5 pings/second until resolved. (These numbers are just as an example; they would vary a based on the environment)
To minimize concurrency and scalability issues, the last ping timestamp for the session should be kept in the session itself. This will allow any distributed session technology to maintain the availability of the session across JVMs or app domains without our ping service needing to be aware of it.
I'm trying to determine whether or not this is a sound approach of if I'm in for a world of hurt. Any experience with the issue would be helpful.
EDIT: I know this sounds like a band-aid, but this is meant to be a stopgap measure until we can rip out the offending library.