Section 17.4. Timeout


17.4. Timeout

Logout, Screensaver, Session, Suspend, Timeout

Figure 17-11. Timeout


17.4.1. Goal Story

Tracy was so keen on leaving the office Friday afternoon that she forgot to shut down the market news web site. Fortunately, the web site monitors mouse movements, meaning that if she doesn't interact with the page for an hour, it will suspend itself, saving a lot of wasted refreshes. On Monday morning, Tracy walks in and sees a screensaver-like animation in the browser, with a message indicating that updates have ceased. She clicks a mouse button and sees the screen update with the latest prices.

17.4.2. Problem

How can you tell whether the user is still working with the application?

17.4.3. Forces

  • Users often leave an application in a browser window for hours or days without interacting with it. Many times, they abandon it altogether. The practice is becoming more prevalent as all major browsers now support multitab browsing.

  • Ajax Apps often use Periodic Refresh or HTTP Streaming to keep informed about server state. The user may not care about the application anymore, but if it's still in the browser, a naïeve implementation will continue to poll the server indefinitelya massive waste of bandwidth and resources.

  • Ajax Apps often contain sensitive data which is at risk if the user forgets to log out when leaving a public terminal.

  • Ajax Apps often involve collaboration and communication between users. To cultivate an awareness of other users and their activities, the server must track the state of individual browsers.

17.4.4. Solution

Have the browser Timeout the user after a period of inactivity and, optionally, inform the server. After a period of inactivity, the application is either suspended, requiring the user to manually resume it or shut down, requiring the user to restart.

This pattern raises the whole question of sessions in Ajax. Conventional applications usually have server-side session objects which represent the user's current session. Typically, this means short-lived information such as shopping cart contents or recently viewed items.

In Ajax, server-side sessions are not so useful. In fact, if you rely solely on RESTful Services, you may not need those session objects at all. In browser-centric Ajax Apps, the browser is a full-fledged application with all of the session state held within. So the browser state is the session. The server-side session, if used at all, is only relevant to authentication and has no impact on the response to any particular query. See RESTful Service (Chapter 9) for more details.

How is all of this relevant to Timeout? Well, consider this familiar nightmare scenario:

The user opens up a form, spends two hours populating it while researching the answers, and clicks submit. The browser then responds with "Your session has expired" and adds insult to injury by presenting a new blank form.

Stories like this are all too common because server-side session Timeouts ignore what's happening in the browser. If the user hasn't submitted a form in, say, 30 minutes, the session times out and all the data is lost. That's a problem if the user has been actively working on the browser side. With an Ajax App, the server has a better chance of staying in sync with the browser thanks to XMLHttpRequest Calls (Chapter 6). In most environments, the server-side session will be automatically refreshed when an XMLHttpRequest Call comes in. However, this is not optimal either because the server still doesn't know why browser calls are occurring. For applications using Periodic Refresh (Chapter 10), for example, a server-side session will stay alive indefinitely even if the user has left the building.

By relying instead on browser-based Timeout detection, you can be more intelligent about how Timeouts will occur. Browser-based Timeout detection is based on Scheduling (Chapter 7). A timer is established to count down to Timeout state. Each significant activity cancels the timer and starts a new one in its place.

What activities are significant enough to restart the timer? Mouse movement is one candidate. You can monitor each mouse movement on the page; one of the following Code Refactoring illustrations below does exactly that. Mouse movements are a very broad indicator, and you might be concerned about "false positives": These may be suggestions that a user is still working with an application when they're in fact not, e.g., they just happened to move the mouse across the browser window while cycling through each open window. You'll also get some "false negatives": A user working only with the keyboard is liable to be timed out. If you'd prefer to keep the session going only if the user is actively changing data, you can instead catch events such as button clicks and keypresses within input fields.

Sudden Timeouts can be frustrating for users, so consider these feedback measures:

  • Unobtrusively show Timeout status, e.g., number of minutes remaining. You might highlight the status as Timeout approaches, and also offer some background and instruction on avoiding the Timeout.

  • When Timeout is approaching, offer a warning and an opportunity to explicitly restart the timer.

Once you've detected that the user is inactive, what do you do? Timeout can be used in several ways:


Stop Periodic Refresh

Conventional applications tend to do nothing when the user is idle, but many Ajax Apps continuously poll the server. Thus, the Timeout should trigger cancellation of any Periodic Refresh timers.


Clear data

Sometimes an inactive application is a hint that the user may no longer be in control of a terminal. There's a risk that someone else could gain access to the user's data and permissions. After a Timeout, document.url can be pointed to the main application URL in order to refresh the page. In addition, you might decide to delete cookies holding sensitive data.


Save data

If you clear data, you might also consider first saving it on the server. There's nothing more annoying than arriving back from lunch and finding that a partly filled-out form has been cleared for security purposes. With an XMLHttpRequest Call, you have the option of saving the user's progress as a "draft."


Inform user

If you're performing Timeout activities, you'll need to provide some feedback to the user about what's happening and what he should do about it.


Inform server

Although the browser controls session Timeouts, the server can nevertheless be kept informed, and it can use server-side sessions for this purpose. There are quite a few applications of server-side session tracking:


Invalidating server-side session

The server can invalidate any server-side session data for security purposes.


Historical records

The server can retain Timeout data to help personalize the web site, to provide feedback to users, and also to inform you, the site operator.


Multiuser awareness

In multiuser systems and especially in any sites hoping to foster a community, users should be aware of each others' activities. Indeed, the "live web"or, as Technorati puts it, "What's Happening on the Web Right Now?"is becoming a key phenomenon on the Web. If the server is able to track what users are working on and how long they have been idle, this information (subject to privacy considerations) can be conveyed to other users. That's especially important when users are collaborating on the same workspacefor instance, in an Ajaxian wiki environment.


Pessimistic locking

Pessimistic locking is a technique used to prevent two users from working on the same thing at once. In a wiki, for example, a user can lock the article and thereby have sole access to it until it's saved or until the user is idle for a while. While this can be open to abuse on the public web, it would actually be quite a good model for many intranet applications. However, it hasn't been practical because of the risk that the user might walk away and leave the lock intact. Server-side session Timeouts don't help much because the user might be busily working in the browser but not be ready yet to submit content. But once the server is aware of what the user is doing in the browser, pessimistic locking starts to become practical. If the user hasn't done anything for the last 30 minutes, for example, she loses the lock. Again, Ajax helps with this, because with Periodic Refresh (Chapter 10), you can immediately inform the user that she has lost the lock.


Work scheduling

With this variant of Predictive Fetch (Chapter 13), it's possible for the server to proactively prepare for future actions. By tracking active users, the process becomes more focused. For example, a blog aggregator could run a periodic background process to build a list of unread articles for each active user should they decide to view the list.

So informing the server of a Timeout is a good thing. But there's still a small problem with this approach: What if the user quits the browser or moves away to another site? Then a Timeout will never occur and the server will blissfully continue assuming that the user is logged in for all eternity. To alleviate this problem, have the server refresh the user's record upon each incoming request that suggests user activity. The rest remains, however, of inadvertently timing out a user who is performing browser-only activity. So what we need is a way for the browser to keep telling the server that the user is still active, explicitly noting that a Timeout hasn't actually occurred. That's exactly what the Heartbeat pattern is aboutsee later in this chapter for more details.

17.4.5. Decisions

17.4.5.1. How long will the Timeout period be?

The Timeout period will depend on the purpose for having the Timeout period in the first place. For example, if the purpose is primarily to stop Periodic Refresh (Chapter 10), you need to weigh the benefits of reduced bandwidth and server costs against the frustration caused to users who will have to reactivate the page and wait a few seconds for the latest data. In practice, there are probably several reasons to use Timeout, and the needs in each situation must be taken into consideration.

17.4.5.2. How will Timeout affect the user interface?

A Timeout can impact the interface in different ways. You may choose to use any of the following:

  • Wipe the entire display and show a message that the user was timed out or the session suspended. This is worthwhile if the data is sensitive.

  • As a variant on the previous option, reload the entry point for the application (as if the user had typed in the main URL).

  • Perform a Page Rearrangement to insert a message about the Timeout into the page.

In addition, if you want to be really sure that users know they've been timed out, you could produce an alert. Use Timeout alerts with caution: it's quite obtrusive, and you could probably make the Timeout equally obvious with a carefully considered page element. A Popup (Chapter 15) is a less obtrusive mechanism.

17.4.6. Real-World Examples

Many conventional web sites have a session Timeout feature, though it's implemented server side rather than the way I've described in this section.

17.4.6.1. Lace Chat

Brett Stimmerman's Lace Chat (http://www.socket7.net/lace/) is an Ajax chat app. As such, it requires a Periodic Refresh in order to keep showing new messages, a serious bandwidth concern if the user is no longer interested in the conversation. So after some idle time, a dialog box appears indicating that Lace has stopped; it includes a button allowing the user to resume (Figure 17-12). Lace also has a Status Area (Chapter 15) that always shows whether the application is runningi.e., whether the server is being polled. In fact, you can pause and resume it manually too. The Timeout mechanism hooks into this state by forcing the application to pause upon Timeout.

Figure 17-12. Lace Chat Timeout


17.4.6.2. Pandora

Pandora uses Flash to stream music into a browser. After a long idle period, it stops playing and produces a dialog to confirm that the user is still listening.

17.4.6.3. Session Warning Demo

Eric Pascarello has explained a demo system which has a standard server-side session Timeout but which also pops up a warning near Timeout allowing the user to renew the Timeout (http://radio.javaranch.com/pascarello/2005/07/05/1120592884938.html). There are implementations in both VB.net and JSP.

17.4.6.4. Operating system Timeouts

A precursor to Ajaxian Timeout is evident in operating systems, such as Apple OSX, that show a warning when they are about to enter standby mode. A pop-up dialog says something like "You haven't used the mouse or keyboard for 15 minutes. Standby mode will start in 30 seconds." The dialog will count down, and the user can prevent the Timeout with a keyboard or mouse action or by explicitly hitting a Cancel button. A similar precursor is present in remote terminal systems that output an idle warning to the console.

17.4.7. Code Refactoring: AjaxPatterns Timeout Wiki

17.4.7.1. Introducing Timeout to the wiki

Timeout is a very useful pattern for a wiki on several counts. Firstly, it cuts down on Periodic Refresh (Chapter 10) wastage. Secondly, it helps users understand what others are up to. Thirdly, it improves security if users are logged on. For all of these reasons, we will now add some Timeout functionality to the Basic Wiki Demo (http://ajaxify.com/run/wiki). (The Periodic Refresh Time Demo [http://ajaxify.com/run/time/periodicRefresh] also has a couple of similar Timeout refactorings under it.)

17.4.7.2. Initial refactoring: unconditional Timeout

This initial version, Timeout Wiki Demo (http://ajaxify.com/run/wiki/timeout), is merciless. Log into the wiki and, no matter what you do, you're timed out a few seconds later (Figure 17-13). The point, of course, is to introduce and prove the basic Timeout functionality, which can be built on later.

Figure 17-13. A timed-out wiki


A Timeout message that will initially be hidden is added to the initial HTML:

   <div >     Timed out. Please <a href=".">reload the page</a> to continue.<br/>   </div> 

The script begins by hiding the Timeout message and kicking off a Timeout timer:

   window.onload = function( ) {     ...     $("timeoutMessage").style.display = "none";     timeoutTimer = setTimeout(onTimeout, TIMEOUT_TIME);   } 

When Timeout occurs, the Timeout message is made visible (with some fanfare, courtesy of a Scriptaculous effect [http://script.aculo.us]). Most importantly, the periodic sync stops, so the server is no longer polled. All the messages are removed from the page as well:

   function onTimeout( ) {     new Effect.BlindDown($("timeoutMessage"));     stopPeriodicSync( );     removeMessages( );   }   ...   function removeMessages( ) {     while ($("messages").hasChildNodes( )) {       $("messages").removeChild($("messages").firstChild);     }   } 

17.4.7.3. Warning that Timeout is pending

If only for the selfish reason that we want to avoid being flamed by the user, it would be nice to warn them that a Timeout is about to occur. And nicer still to let them prevent it from occurring. So this demo (http://ajaxify.com/run/wiki/timeout/warning) introduces a warning mechanism.

To the previous Timeout message we add a warning message. Both are initially invisible. The warning includes a renew button, which will invoke renewSession( ).

   <div >     Near timeout. Please <button >Renew</button> your session now.   </div>   window.onload = function( ) {     ...     $("renew").onclick=renewSession;     ...   } 

renewSession( ) is not only used on renew but also on startup. It resets both the timeoutTimer and the warningTimer. Note that these timers have been introduced as variables in the script, precisely so that we can cancel them in this method. In addition, renewSession( ) kicks off the standard wiki sync timer and hides the warning and Timeout messages in the case that either is showing:

   var timeoutTimer = null;   var warningTimer = null;   ...   function renewSession( ) {     $("warningMessage").style.display = "none";     $("timeoutMessage").style.display = "none";     clearInterval(warningTimer);     clearInterval(timeoutTimer);     warningTimer = setTimeout(onWarning, WARNING_TIME);     timeoutTimer = setTimeout(onTimeout, TIMEOUT_TIME);     startPeriodicSync( );   } 

So as long as the user clicks on the renew button while it's showing, he can force all timers to be restarted. But if he doesn't click on it, Timeout will proceed. We simply have to ensure that the warning message is shown before the Timeout message, i.e., WARNING_TIME must fall short of TIMEOUT_TIME. When Timeout occurs, we can assume that the warning is already being shown, so we replace it with the Timeout message. And as before, we stop synchronization and remove all messages:

   function onTimeout( ) {     new Effect.BlindUp($("warningMessage"));     new Effect.Appear($("timeoutMessage"));     stopPeriodicSync( );     removeMessages( );   } 

17.4.7.4. Monitoring mouse movements

A warning's better than nothing, but it does have the slight odor of techno-centeredness. From the user's perspective, why should she have to explicitly renew the session. What's this Timeout business anyway? For most users, it's better to handle Timeout on their behalf. This demo (http://ajaxify.com/run/wiki/timeout/monitoring/) builds on the initial Timeout demo to suspend activity when the user is idle.

Here, we'll make an assumption that the user is working with the mouse. That is, we can assume that the user is idle if (and only if) he hasn't used the mouse for a while. As before, we have only one Timeout message, which we've altered to help the user understand how to bring all of those messages back again:

   <div >     Timed out. Please wiggle your mouse to continue.<br/>   </div> 

The key to this pattern is watching for mouse movements on the page and renewing the session when one occurs. Actually, that's easy enough to achieve:

   window.onload = function( ) {     ...     document.getElementsByTagName("body")[0].onmouseover = function(event) {       renewSession( );     }     ...   } 

Calling a function on each mouse movement could get grossly inefficient. In real life, you might want to be just a little more intelligent about this. For example, use some sort of throttling algorithm to ensure that renewSession( ) isn't called more than once every few seconds.

renewSession( ) itself works similarly to the preceding warning demo: it hides the Timeout message and kicks off sync and Timeout timers.

   function renewSession( ) {     if ($("timeoutMessage").style.display!="none") {       new Effect.BlindUp($("timeoutMessage"));     }     clearInterval(timeoutTimer);     if (!syncTimer) {       startPeriodicSync( );     }     timeoutTimer = setTimeout(onTimeout, TIMEOUT_TIME);   } 

17.4.8. Related Patterns

17.4.8.1. Heartbeat

Heartbeat (see the next pattern) is a companion pattern that helps the server monitor whether the user is still working in the browser.

17.4.8.2. Periodic Refresh

For Ajax Apps, a big motivation for Timeout functionality is the prospect of reducing Periodic Refreshes (Chapter 10).

17.4.8.3. Progress Indicator

Progress Indicator (Chapter 14) is normally used for feedback during an XMLHttpRequest Call. However, another application of it would be to count down toward the Timeout. The display could be present as a permanent fixture, or, alternatively, you could introduce it near Timeout.

17.4.8.4. Direct Login

If your Timeout requires reauthentication for users to continue working with the system, you probably want to offer a Direct Login (see earlier).

17.4.8.5. Status Area

You can show Timeout-related messages and countdowns in a Status Area (Chapter 15).

17.4.8.6. Popup

You can show Timeout-related messages and countdowns in Popups (Chapter 15).

17.4.9. Metaphor

If a car engine remains idle long enough, you're probably going to assume that it's dead and give up trying to start it. To keep going would only be a waste of energy.




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net