Submission Throttling and the Browser-Server Dialogue
The second part of this series of articles dealing with browser-server information flow discussed periodic refreshing. This one covers submission throttling and explicit submission. The third of a multi-part series, this article is excerpted from chapter 10 of the book Ajax Design Patterns, written by Michael Mahemoff (O'Reilly, 2006; ISBN: 0596101805).
Submission Throttling and the Browser-Server Dialogue - Decisions about Submission Throttling (Page 2 of 7 )
How will the server deal with incoming commands? Will all commands still be valid?
Submission Throttling is vulnerable to integrity issues, because synchronization is being deliberately downgraded. The universe will have moved on since the user submitted the original commands--the time will be different, new information may be available, existing information may have changed or been deleted, and other users may have executed commands in the meantime. All of these scenarios are unavoidable manifestations of the asynchronous nature of Ajax, and the design must take them into account.
The server needs to decide whether to process each incoming command as it's quite possible some are no longer valid. For example, a stock purchase order might be refused on the basis that the price has just risen or because the server has since expired an initial quote it made to the client. Some of these decisions can be made by standard techniques such as atomic database transactions, but others might require some custom business logic. Furthermore, some business logic will be required to decide what to do with the rest of the Commands in a queue, should one Command in the middle fail. Sometimes, it's okay to keep processing the rest and sometimes not.
How will buffer uploads be triggered?
The most obvious algorithm for upload sequencing is a timer. Every minute (say), the browser polls the buffer and makes the corresponding call sequence. Or, if nothing has changed, it might do nothing for another minute. If a timer is used, a decision must be made as to when it will trigger. First, the period is usually fixed, but does not have to be. It might be increased during times of known server activity, or even altered to respond to those constraints dynamically. Furthermore, it might be based on the user in question: service level can be tweaked by giving premium users shorter throttle periods.
A variant, usually more useful, is to cap the rate but immediately send the first command after a long wait. This helps a user who changes information only occasionally. Let's say the throttle period is 30 seconds. With a standard, fixed-interval, algorithm, the following sequence occurs:
00 secs: system polls, no activity so no upload
30 secs: system polls, no activity so no upload
60 secs: system polls, no activity so no upload
65 secs: infrequent user does something; no upload yet
75 secs: infrequent user does something; still no upload
90 secs: system polls and uploads both pending commands
We can still cap the rate at 30 seconds, but upload a command immediately if there's been no activity for the past 30 seconds:
00 secs: system polls, no activity so no upload
30 secs: system polls, no activity so no upload
60 secs: system polls, no activity so no upload
65 secs: infrequent user does something
65 secs: system notices and uploads command immediately
75 secs: infrequent user does something; this time, the command must wait since there was a recent call
95 secs: system polls, uploads if there was any further activity after 65 secs
Prioritization is another technique. A timer might be used for regular events, but with priority given to any critical commands. A Live Form (Chapter 14) might periodically upload the progress of an individual field, so the server can provide suggestions, for example. But as soon as the user proceeds to the next field, a call takes place immediately.
A further consideration is the user's activity during upload. Its wise to avoid uploading something the user is currently working on, especially if other users will see it and if they probably won't be working on it much longer. So, one policy might involve uploading only after a period of idle activity.
How many buffers per browser application?
There's no reason to have just one buffer for all commands. It's possible to have several buffers running in parallel, providing you have considered the consequences of commands arriving in a different order to the user requesting them. Prioritization was already mentioned above, which would be one reason to have several buffers--higher-priority buffers being processed with greater frequency.
Here's how a blog reader might use three buffers in parallel:
A low priority queue uploads comments submitted by the user. Throttle period: 15 seconds.
A medium priority queue pulls down requested feeds from the server. Throttle period: 3 seconds.
A high priority text buffer lets the user tag articles with a Suggestion mechanism. While it's not necessary to upload upon each keystroke, any new information must be transferred quite rapidly. Throttle period: 0.2 seconds.
This example illustrates that it's quite easy to run several buffers without threat to data integrity and without user confusion.
How long should the throttle period be?
Deciding on the throttle period requires some analysis of user needs. As the previous blog reader example demonstrates, there is a range of periods that might be required:
For background synchronization, the period can be a few minutes if resource constraints apply, although it should ideally be in the order of 10 seconds. If it is several minutes, users should be kept informed with appropriate Progress Indicators (Chapter 14), lest they quit and lose work before the upload kicks in. Ideally, there should be an Explicit Submission (later in this chapter) mechanism as well, to allow immediate saving.
At the other end of the spectrum, for low-level interaction while the user types and mouses around, the period must be in the order of 100 milliseconds.