Tuesday 6 November 2012

Javascript: It’s All A Question of Timing



Accurate Session Timeout Notification Using Javascript: Part 1

JavaScript timer methods (setTimout, setInterval) are notoriously inaccurate. Given that JavaScript executes within a single browser thread, timer functions and are subject to drift depending on resource required by other operations taking place. Although this doesn’t normally cause major problems for non-animation based development, cumulative inaccuracies over a period of time are still something that can cause a headache for front-end developers. 

Rationale

Part of my bread-and-butter work is developing web applications for clients where a secure login is required to access sensitive resources. Developing for IIS usually means that once logged in, the user is allowed 20 mins (if you stick with the default settings) of inactivity before their session times out. For the sake of security I’m personally not too keen to extend this period too far. It’s far too easy for a user to login, start an activity that requires a significant amount of data input, pause for a cuppa, and return later to complete their task. Now, I realise that there could be a number of off-tangent arguments here whereby the user shouldn’t leave their machines with sensitive information unattended, and that if a large amount of data input is required then perhaps a re-think/re-design of the input forms is required. I agree. However, sometimes, where the decision isn’t the developers to enforce, you have to work with what you have and make the best of it for all concerned.

Just this situation arose recently at work. A web-app we are developing contains a form that may require a fair bit of interaction from the user, without making a request of the server. The issue here is that although the user is busy beavering-away, the server quietly times out behind the scenes. When the user is ready to submit their data, the server simply redirects them to the login page as the session has timed out losing all their work. Quite understandably, the user could be left somewhat bewildered and a little put-out by this ‘security’. 

As I’m personally loathe to increase the session timeout too far, as the session-timeout still has it’s place, the next best thing must, surely, be to warn the user of an impending timeout and provide them the opportunity to continue working. Which leads me back, to the subject of this blog. 

Ideally, it would be nice to set a simple JavaScript timer on the front-end which displays a timeout warning to the user 5 mins before the end of their session. The trouble is that, depending on the single-threaded, blocking nature of JavaScript and the effect of user interaction on the thread, the timer may not be particularly accurate. Admittedly, there isn’t a 5 min drift in a 20 min period, but it may be several seconds. In fact a simple jsFiddle test confirms that there could be up to between a 1 ms to 3 sec loss each minute. Cumulatively, that could be as much as a 60 second loss in every 20 minute period. Potentially enough of an inaccuracy for the user to attempt to maintain their session seconds before s/he believes the session will expire, but the session has already expired behind the scenes anyway. It’s plenty enough of a risk for me to feel that a more accurate timer is needed.

Embrace the Latency!

One way to do this is to adjust the time out taking into account the latest latency suffered. but to do this we need to know what the latency is. JavaScript makes it easy for us to calculate the latency using the Date object. Another jsFiddle shows us how this can be achieved:
The doTimer function expects the total milliseconds to time and the checking interval. For example, we want to run the timer for 20 minutes and test every second. We start by getting the time the function was called. Each second the start time is deducted from the current time taking into account the period of time that is expected to have elapsed. The difference in this calculation is the latency experienced for this iteration. We then set up another timeout for 1 second +/- the latency. 

When we hit the magic 20 minutes the timer stops. This function provides us with a more accurate timer that takes into account the load placed on the system by other applications and the current thread itself and attempts to minimise the drift caused by inaccuracies.

We can use this function to provide a warning to the user that their session is about to expire, but this isn’t really enough on its own. We need to encapsulate this function in a generic plugin that allows us to setup the session timer, setting the total sessiontime, the time that the user should be warned and actions to take based on user interaction. In time honoured fashion, that’s the subject of the next post.

Written by:  Dan Hacker, Software Developer, DSCallards

For more information visit:  www.developer-solutions.co.uk

No comments:

Post a Comment