37 sites, 19,917 entries and counting...     Get a free blog; Join a Weblog Network!
Top

Simulating Latency with Greasemonkey

September 23, 2005

Julien Couvreur has another approach to simulating network latency in AJAX apps - XmlHttpRequest - Add Latency. Certainly a neat solution in terms of lines of code ;-) Some random thoughts, perhaps to give Julien ideas.

When considering AJAX Proxy had half thought of Greasemonkey although figured an HTTP proxy is a more “honest” solution. Re-thinking, will probably work just as well with Greasemonkey.

Some specific things I wanted to be able to simulate with AJAX Proxy, with reference to Julien’s approach;

  • Latency swings both ways. A delay could occur in the direction from client to server, sending a request. A delay could also occur from server to client, as the response is delivered. OK - that’s not exactly how the HTTP protocol works but from an application point of view, it makes a useful simplification.
    For example consider an AJAX chat application - there might be an operation on the server called “save message” which stores a single chat message sent in a request by a client. The response from the server to this operation is simply an “OK” or “Failed”. So what’s interesting is really any delay in the client to server direction. If the latency is varying over time (which it might), it could be possible that “Message A” and “Message B”, sent by the client, are received in order “Message B” then “Message A” by the server. The server needs to check the messages are stored in the right sequence (which implies the client is providing some kind of sequence information)
    Meanwhile another server operation, “get new messages”, is polled by the client to obtain new messages after a certain time or sequence ID - varying delay in either the server to client direction or vice versa causes new messages to be received by the client in the wrong order; the client also needs to check the order of what it receives.
    At the moment Julien’s solution is only delaying messages in the client to server direction - the delay he uses is inserted before the request is actually sent. Think it also needs to be possible to have a delay inserted after the response was received from the server but before the corresponding callback function is executed ( that’s going to dramtically increase the lines of code required though).
  • Latency may vary over time. Julien uses a consistent delay, which will highlight painful end-user experiences but as the above point illustrates, it’s more subtle than that. On a typical network would get “spikes” and similar that mean things like for half a second response times are really bad but then recover. Depending on what you’re doing with AJAX this may mean you need to implementing “queueing” or sequencing - the Starbucks factor.
  • Latency is not predictable. Basically the same point as above but would be nice if Julien’s solution supported “randomness” as another mode of testing.
  • Sometimes it just fails. And a request might fail to get to the server or a response might fail to get back to the client - complete network failure somewhere down the line. From what I’ve seen with AJAX Proxy, when completely dropping requests and responses, the current browser XMLHttpRequest implementations do little, if anything, to report this to the caller (or callback). And from testing a few online AJAX demo’s (I’m avoiding naming names here but I’m sometimes sorely tempted) this will mean data loss for some apps.

Think it should be possible to simulate all of those conditions with Greasemonkey, although it’s a fair amount of work. Wish Julien good luck with it.

At some point will give AJAX Proxy a decent CLI startup interface (rather than having to hack the code) and package it with py2exe but right now, no time.

Another angle someone should look at is fiddler, which is basically AJAX Proxy but a lot better (Windows only though). Check out this forum post - should be possible to implement all of the above with JScript and fiddler.

Question: Is all this really a problem? We all care about accessibility, right? Well this is accessibility in the literal sense. You need to leave localhost realise this is a real problem - take a holiday to South Africa then try accessing your AJAX app over in the States. Failing that, make a friend of a South African - you may learn some new swear words.

AJAX Proxy 0.2

August 8, 2005

Version 0.2 of of AJAX Proxy is out - available here. This one actually passes on the POST body (duh).

The basic instructions on setting up Python are the same, as described earlier.

Configuration of the script has now changed - at the end of the script you would modify;

[code lang="python"]
if name == ‘main’:
REAL_TIMEOUT = 10 # Timeout between AjaxProxy the remote host
# If you’re behind a proxy server yourself, use these
#PROXY_HOST = ‘proxy.server.com:8080′
#PROXY_USER = ‘yourusername’ # Not required
#PROXY_PASS = ‘yourpassword’ # Required if PROXY_USER is set
LOG_DOMAIN = ‘localhost’ # Restrict logging to this domain
LOG_FAVICON = 0 # Log requests for favicon.ico
PI.load(’proxy.instructions’) # Load the instructions file
[/code]

The instructions file allows you to tell the proxy how it should delay requests. An example;

[code lang="python"]
# On each line, enter two instructions seperated by whitespace
# The first is executed after a request has been received by the proxy but before it forwards it
# The second is executed after the response has been fetched by the proxy but before it returns it to the browser

# The available instructions are;
# wait < creates a delay
# - the delay can be specified a colon then an integer (seconds up to 10)
# - or the word "random" for a random delay of 0 - 10 secs
# fail < the request or response fails - nothing delivered
# end < just outputs a message saying it’s the last instruction without interfering with the request for info only
# - use of this is optional

wait:0 wait:1
wait:random wait:random
wait:10 wait:10
wait:0 wait:0
fail # no need to define a response instruction
end
[/code]

Each line of instructions is used to apply to a single request / response lifecycle. The next request will use the instructions on the next line.

Otherwise, it now dumps the complete request and response (HTTP headers and body) which can be handy for debugging.

A friendly explaination some other time. Meanwhile it’s interesting to try some of the AJAX applications out there - there’s some tails or madness, rage and data loss waiting to be told ( and JPSpan is not entirely innocent either) …

AJAX Proxy 0.1

August 5, 2005

If you’ve read any of the posts I’ve been dumping here, you’ll know I’m critical of the way AJAX is frequently being used on the grounds that the network / server (and their inherant instability) aren’t being considered. Specifically have the feeling alot of AJAX development is happening @localhost so these problems simply aren’t showing up.

Enter AJAX Proxy, which is meant as a tool to simulate network / server delays by sitting between your browser and your web server and delaying things.

The first version is up here and currently in very hacky form. It’s based on HTTP Debugging Proxy which in turn was based on TinyHTTPProxy. To get it to run on Windows, got some help from rgutils.async, which I used to replace the signal calls. Also, with a little hacking, got it to support a proxy itself (if you’re behind one) - see globals at start of ajaxproxy.py.

To run it, unzip the source somewhere, make sure you have Python installed then from the command line;

[code]
$ ajaxproxy.py 8080
[/code]

The argument is the port number it should run on (defaults to port 8000).

You then need to reconfigure your browser to use it as a proxy server (Firefox > Tools > Options > Connection Settings > Manual Configuration: http proxy = localhost, port = whatever port you used). Also make sure localhost (if that’s where you server is) is not listed in the “No Proxy For” field.

If you now make a request to localhost, you should see the request and response headers logged to your command prompt (TODO: extend this logging to include the payloads)

By default it won’t interrupt anything. To get it to delay / interrupt the request or response, right now you need to hack the source code (TODO: mini language to make this easier). In ajaxproxy.py, check out the following functions;

[code lang="python"]
def beforeRequest():
“”"This function is executed before the request happens”"”

#Constant sleep
#time.sleep(2)

# Random sleep
# r = random.Random(time.time())
# time.sleep(r.choice((0,5)))”"”

# return 0 # Request never happens
return 1

def afterResponse():
“”"This function is executed after response is received
but before it’s given to the browser”"”

#Constant sleep
#time.sleep(2)

# Random sleep
# r = random.Random(time.time())
# time.sleep(r.choice((0,5)))”"”

# return 0 # Response not sent to browser
return 1
[/code]

It doesn’t support HTTPS (or FTP or anything but plain old HTTP) but if you’re confident to hack a little python, it’s hopefully good enough to get a feeling for what your AJAX app is like when delays start happening.

More as it evolves…

Vindication!

July 12, 2005

Looks like I’m not just a grumpy dwarf battling against the flow. Someone else uncovering problems with AJAX’s asynchrony here.

In 99% of cases this worked fine, until I suddenly discovered nodes appearing under the wrong parent. What had happened was that the server was under more load, there were more nodes in one particular branch and the data was taking longer to return than before.

I get the feeling that for many, that is works right 99% of the time is good enough. The problem is 1% of the time it wasn’t just “not working”, it was actually providing misleading information to the user which might also load to data “corruption”, if a user was to make changes, based on that false state of the application. From my perspective that 1% means == malpractice if you deliver it to a client.

There are two solutions I know to this problem:
1. Lock the view.
2. Pass the view state to the remote method and return it along with the data.

From my angle, I’d prefer to handle this at a “transport” level. I see people implementing cool things in the UI like “faders”, “throbbers” etc. but that’s not fixing the problem, it’s just warning the user to be nervous.

The simplest solution I can think of is that Harshit recommends - only ever have one async request in progress at a time.

In Javascript that might simply mean using a single, global XMLHttpRequest object and protecting it from multiple requests using some of the techniques I mentioned before here. The next step from there might be implementing a queue onto which requests can be placed until the XMLHttpRequest object is ready to handle them, although that’s already an order of magnitude more complex and leaves some grey areas in terms of how the queue relates to the end user experience. Long term some real solutions are needed here. Meanwhile find this @ ajaxpatterns somewhat confused…

Anyway - slowly exploring the solutions which I’ll try blogging another time.

AJAX: The Starbucks Factor

June 28, 2005

Via Neil Kandalgaonkar ran into Starbucks Does Not Use Two-Phase Commit which is one of the essay’s referenced in Joel Spolsky’s new book The Best Software Writing I: Selected and Introduced by Joel Spolsky.

When you place your order the cashier marks a coffee cup with your order and places it into the queue. The queue is quite literally a queue of coffee cups lined up on top of the espresso machine. This queue decouples cashier and barista and allows the cashier to keep taking orders even if the barista is backed up for a moment.

By taking advantage of an asynchronous approach Starbucks also has to deal with the same challenges that asynchrony inherently brings. Take for example, correlation. Drink orders are not necessarily completed in the order they were placed. This can happen for two reasons. First, multiple baristas may be processing orders using different equipment. Blended drinks may take longer than a drip coffee. Second, baristas may make multiple drinks in one batch to optimize processing time. As a result, Starbucks has a correlation problem. Drinks are delivered out of sequence and need to be matched up to the correct customer.

Sound familiar?

The trail leads on to Will the Real Asynchrony Please Stand Up? and a book called Enterprise Integration Patterns. Some food for thought…

AJAX: telling it like it is…

June 3, 2005

Marcus Baker, author of the excellent PHP unit testing toolkit Simple Test lays it on the line: Listen kids, AJAX is not cool;

Marcus is goes straight for the jugular, playing the “it’s the network stupid” card and puts it in far more succinct terms than I’ve been cautiously trying to do in some of these blogs.

The more I think about it, the more it’s clear that some kind of delaying HTTP proxy, that I was suggesting here, is badly needed to make people see how badly AJAX can suck when you inject a little latency - AJAX@localhost is always going to look good.

Marcus mainly refers to hooking up UI components a user can interact with directly with AJAX. There is another way to go with AJAX, which is suggested in Ajax: It’s not all about XMLHTTPRequest (part I) and part 2 - namely start treating Javascript as a real runtime, occasionally “syncing” with the server to prevent data loss. In theory that’s probably the right way to go but it raises a whole bunch of new issues, from redefining the notion of a session to whether Javascript is really a robust platform for application development (see point 3 then follow that up by reading Javascript sucks vol. 1). Marcus highlights the lack of mature testing tools for Javascript (or even the lack of an environment to automating testing of Javascript in), which is part of this picture of Javascripts deficiancies.

From where I stand, Javascript is today where it should have been about 5 years ago as people were discovering DHTML - you can now write code which has a pretty good chance of running under all the modern browsers for the sake of neat web page gimmicks. But what Javascript isn’t is a sane environment for building MVC applications where the data model is available courtesy of AJAX.

Things like GMail and Tibco General Interface are exceptions, not the final destination. With enough money and manpower practically any technological pig can be made to fly - that doesn’t translate to the reality of small web shops building apps for SME’s.

Of course this not going to stop anyone from trying - we’re talking holy grail here. But what is worth remembering is if you decide to go AJAX, realize that you’re significantly increasing the risk that your project will “fail”. Don’t try it where real money is involved. As Marcus puts it;

When you write AJAX applicatons you drive a horse and cart through one of the most successful metaphors of all time.

Javascript static variables

June 2, 2005

Something I find strange about Javascript;

[code lang="javascript"]
function Foo(){};
Foo.prototype = {

bar: [], // or ‘new Array()’ or ‘new Object()’

set: function(val) {
this.bar.push(val);
},

displayBar: function() {
alert (this.bar);
}
}

var foo = new Foo();
foo.set(1);
foo.set(2);

// Alert displays 1,2
foo.displayBar();

// Destoy the object
foo = null;

// Create a new one…
var x = new Foo();

// What does this display?
x.displayBar();
[/code]

By declaring the bar property to be an Array, it seems to make it static to values assigned to the array are in effect updating the class definition - later objects inherit those values. The same works for Objects and both Moz and IE behave the same way, so this would seem to be a feature. The only way to really free the memory is to modify the prototype e.g. Foo.prototype.bar = null;

Anyway haven’t seen it discussed before before - perhaps a useful feature or otherwise a path to eat up memory and forget to free it.

Async Requests over an Unreliable Network

June 1, 2005

The biggest void in the AJAX discussion, IMO, is how network and server availability affects XMLHttpRequests. I can only guess this void is a result of skill set - if you’re hot with CSS is issues relating to UI design, chances are you’re less fluent in the fine print of HTTP or used to thinking in terms of writing fault tolerant clients to remote services.

That gets further compounded by developing on localhost where you don’t get to see the impact of synchronous requests, for example, when the network or remote server is taking a break.

Question Time
Good news is there’s more discussion of such AJAX implementation details starting to appear, beginning with some excellent insight from Weiqi Gao in questioning AJAX and some concerns about the impact on development strategy from Bjorn Schott: AJAX: redesign your PHP applications?, with follow up from Marco Tabini in the anatomy of an AJAX framework. Yet more good stuff to be found in Ajax: It’s not all about XMLHTTPRequest (part I) and part 2.

Not Invented Here

Meanwhile one thing I keep seeing is comments like this one - not invented here - bloated: write my own. To some extent, fair enough and happen to like Alexander’s use of XMLHttpRequest because he has paid some attention to the impact the network may have on it.

But the point is, doing a “Hello World!”, directly against the ‘raw’ XMLHttpRequest API on localhost can be done with only a few lines of code. Unfortunately there’s more glue required before you can safely deploy it in the wild in a way that won’t drive users mad. And once you’ve repeated that glue a few times in a few places, you starting evolving your own “bloat”.

Issues with ASYNC requests in Live Environments

Getting back on track, there’s probably two major issues that occur to me with ASYNC requests, which aren’t solved “by default” by the XMLHttpRequest object.

  1. Dealing with Delay: if the network or remote server is taking it’s time, how does that relate to your AJAX application?
  2. Response Sequencing: network (or server) latency may vary over time. That means responses may not return in the order they were requested.

1. Dealing with Delay

In AJAX mistakes, Alex Bosworth makes reference to the problem with points 1. and 4.;

1. Not giving immediate visual cues for clicking widgets.

If something I’m clicking on is triggering Ajax actions, you have to give me a visual cue that something is going on. An example of this is GMail loading button that is in the top right. Whenever I do something in GMail, a little red box in the top right indicates that the page is loading, to make up for the fact that Ajax doesn’t trigger the normal web UI for new page loading.

4. Blinking and changing parts of the page unexpectedly

The first A in Ajax stands for asynchronous. The problem with asynchronous messages is that they can be quite confusing when they are pop in unexpectedly. Asynchronous page changes should only ever occur in narrowly defined places and should be used judiciously, flashing and blinking in messages in areas I don’t want to concentrate on harkens back to days of the html blink tag.

Alex is arguing this from the standpoint of an end user or a UI designer. Will aim to extend those points here with a practical step to help this.

First think it’s important to understand the effect by seeing it happen. Using the same Python server script from here, I modify the client script slightly to get it to place async requests instead or synchronous;

[code lang="xml"]

Do it!

[/code]

Now if you save this as async1.html under my Python server’s directory (read this one again for longer instructions), and try clicking on that “doIt!” link a few times, you’ll see the sort of wierdness a delay on the server can cause.

Sometime you’ll get a response immediately. Other times it will take ages. Sometimes you’ll get this in your Javascript console (assuming Firefox);

[code]
Error: uncaught exception: [Exception...
"Component returned failure code: 0xc1f30001
(NS_ERROR_NOT_INITIALIZED) [nsIXMLHttpRequest.send]”
nsresult: “0xc1f30001 (NS_ERROR_NOT_INITIALIZED)”
location: “JS frame :: http://localhost:8000/async1.html
:: doIt :: line 42″ data: no]
[/code]

That last one is caused by calling send() on an XMLHttpRequest object which is already processing an existing request. Will get to dealing with this problem in a minute…

Need for Tool: would really help people see the impact of latency on AJAX applications for themselves if there was tool to “slow” the network down. Any takers?

From my angle the easiest way to do this would be running a local HTTP proxy, through which your browser requests are tunnelled, and the responses are delayed by a small sleep() in the proxy.

Took half a shot at this by adding a filter to WebCleaner. Unfortunately WebCleaner has some internal mechanism to terminate connections which are taking too long, which killed my hack and my free moment. There’s a useful resource here on Python HTTP Proxies, some of which should be easy to hack. Would also be fairly easy to do with Perl’s HTTP::Proxy but a little messing in that area suggests that’s a *Nix only solution.

Anyway, the above example, if you try it, should give you a feeling for the sort of problems a delay can cause with async requests. The browser not longer “locks up” as it did with the sync requests, which is good, but the user get’s to keep on clicking stuff while wondering vaguely when the result will arrive.

Parting of solving this issue is giving visual feedback to the user - some kind of “in progess” status. But that’s not all - how long to you want to keep telling a user that they should keep waiting? If you’re not careful it could be in progress for a long long time - if the server delivers something like an HTTP ‘Content-Length’ header which is erroneously longer than the actual content you send, this could happen. To the end user, it’s likely that after a given number of seconds the request no longer bear relevance to what they’re doing - they’ve moved on to clicking other things and may be especially freaked out if a response shows up when they’d given up on it.

Timing Out

The usual approach, in other environments, where HTTP is being using is to implement some kind of timeout. If you’ve worked behind a corporate HTTP proxy, you’ve no doubt run into HTTP 504 status codes, where the proxy basically gave up trying to reach the web site you wanted it to.

Meanwhile most socket client APIs provide some kind of timeout setting you can control programmatically, like PHP’s fsockopen(). In fact it’s strange that XMLHttpRequest fails to offer this, but it’s fairly easy to add.

Uncaught Exception

Before adding a timeout capability to XMLHttpRequest, first going to solve the problem with that exception up there.

The fundamental problem is you can’t tell one XMLHttpRequest object to do two things at once and that’s solvable by using multiple instances of it, rather than the single global instance in the example above. In other words just create a new one whenever you need it. A note of fear and loathing here - have heard and possibly experienced strange things when lots of XMLHttpRequest objects are at work together. Have yet to really track it down - the exact circumstances / browser versions etc. unknown - whether it’s a garbage collection issue or what, I don’t know. Just be afraid ;-)

So it might be you want to re-use an XMLHttpRequest object once it’s finished the current request, for the sake of a little efficiency. Solving this problem also makes timeouts easy to implement. So I can do it with a function that accepts an XMLHttpRequest instance and checks it’s ready state;

[code lang="javascript"]
function callInProgress(xmlhttp) {
switch ( xmlhttp.readyState ) {
case 1, 2, 3:
return true;
break;

// Case 4 and 0
default:
return false;
break;
}
}
[/code]

Actually documented this here.

Now before calling send(), I can look first to see if the object is busy e.g.

[code lang="javascript"]
if ( !callInProgress(xmlhttp) ) {
xmlhttp.send(null);
} else {
alert(”I’m busy. Wait a moment”);
}
[/code]

Aborting a Request

The XMLHttpRequest object also comes with an abort() method, to terminate the current request.

Only problem with abort(), as I remember (exact details purged from head and no desire to re-create circumstances) is if you call it on an object which isn’t processing a request (readyState 0 or 4) - weird things happen.

So the above callInProgess function can be useful.

Implementing Timeouts

Knowing all of the above, timeout can now be fairly easily implemented using window.setTimeout();

[code lang="javascript"]
var timeoutId = window.setTimeout(
function() {
if ( callInProgress(xmlhttp) ) {
xmlhttp.abort();
}
},
5000 // Five seconds
);
[/code]

One catch here though, which I failed to mention here but implemented in JPSpan, is if you’re going to re-use the XMLHttpRequest object for another request, you need to remember to remove the timeout once the first request is completed, using
window.clearTimeout(), otherwise it will turn up to bite unexpectedly on a later request.

In the example I’ve been using, that would probably mean adding it to the callback function e.g.

[code lang="javascript"]
// Callback
function handleResponse() {
if ( xmlhttp.readyState == 4 ) {

window.clearTimeout(timeoutId);

alert (xmlhttp.responseText);
}
}
[/code]

The only problem now is how we inform the end user (or the code that’s waiting for the response) that the request was timed out? Right now we’re just killing those requests quietly. Users probably need to know in some instances (like when they clicked “Save”) while code might like a chance to react, such as terminating that progress indicator or re-attempting the request.

Simply raising an exception from inside the anonymous function I registered with window.setTimeout() won’t work because there’s nothing in a position to catch it. Easier is probably calling some error reporting function e.g.;

[code lang="javascript"]
function reportTimeout() {
// Fairly inexact but still something
alert(’A request was timed out. Taking too long’);
}
[/code]

Now the timeout function becomes;

[code lang="javascript"]
var timeoutId = window.setTimeout(
function() {
if ( callInProgress(xmlhttp) ) {
xmlhttp.abort();
reportTimeout();
}
},
5000 // Five seconds
);
[/code]

So timeouts are now possible but the quantity of extra glue is starting to rise…

2. Response Sequencing

Need a break from typing so will pick this up in detail some other time but consider this example which came up here;

Let’s say I’m showing a catalog that someone is shopping in, and asynchronously updating their shopping cart when they add items, sending an XMLHttpRequest message to the server and having it update the shopping cart display. Now let’s say the user wants one more item, adds it to the cart, and quickly clicks the checkout button… which one gets through first, the shopping cart add or the checkout?

It’s not safe to assume that your callback functions will be trigger in the same order that requests were made. If the “addToCart” operation takes a long time for the server to process, while “proceedToCheckout” is quick, it could well be that your “proceedToCheckoutHandler” function get’s called first.

Solving this needs some real glue, which I don’t have right now. Off the top of my head it needs some kind of queue to allow the responses to “fire” in the right order as well as a temporary “callback cache” which will likely need some tricks with Javascript closures.

More some other time…

FEATURED INFORMATION

In the recent years, webmasters are more aware about their websites search engine ranking and they are continuously making effort to improve it. Now many business web hosting companies provide the facility of search engine placement along with their regular services like unix hosting and virtual dedicated hosting etc. Also doing affiliation with online training authorities like cisco training and indulging in pay per click can not only increase ranking but also revenue.

AJAX: what’s a session?

May 27, 2005

As I mentioned here, my concern about the buzz surrounding AJAX is not what’s being said but what isn’t being said.

One question I’ve got nagging me, which I’ve yet to see serious discussion of, is the that of AJAX and sessions / state. I guess either no one is thinking about it or it’s got brushed under the carpet of “implementation detail”. The furthest I’ve seen seen the discussion go in this direction is Diego blogging on ajax. That said Joshua Eichorn did a great job of hinting at the issues with his memento demo - move the pictures around then hit your browser’s “reload”.

From where I stand AJAX redefines the notion of state in web applications - the “new session” exists for a user for as long as they keep the current web page running. Session data is being “persisted” locally on the client, in memory in Javascript variables.

Of course it’s not that simple and Diego hits the right term, in talking about the “the thin-fat client”.

Background

The web is inherently stateless. That is HTTP is stateless - once a web server has delivered it’s response to you, the connection is closed and it no longer cares you exist.

Of course that’s not great if you want your web app to recognize returning users, either for the purpose of displaying a “Welcome back Joe Bloggs” message or implementing functionality like a shopping cart. To get round this inherent statelessness, you need to build things on top of HTTP, which Netscape did somewhere around 1997 with their cookie spec.

With cookies it is possible to store data “permanently” on a given client, tied to the domain that issued the cookie. The cookie data is then exposed to the domain that issued it, for all future requests, until the cookie expires.

Of course cookies aren’t suitable for all data. If it’s sensitive information such as a credit card number or a password, that data is at risk to anyone with access to the client filesystem or anyone able to listen in on the conversation between the client and the server (i.e. when using HTTP not HTTPS). It’s also a bad idea to store large quanties of data in cookies, as it’s going to eat bandwidth and resources on the client and server. And these days users often work with many different client computers, from their home PC, their desktop at work, from an Internet cafe or even mobile devices. Unfortunately cookies don’t travel as well as users do.

So some of this data you want to keep on the server and the natural next step was using cookies to implement the notion of “sessions” - send a cookie containing a unique identifier for a given user during a given “visit” to a web site and the server can retrieve data specific to that user without exposing it to the world. Cookies aren’t the only way to implement sessions. Another approach is attaching an ID to all “internal” URLs but this introduces greater security risks. It’s also common to use hidden form fields in POST requests, sometimes for short-term “state” for a multi page form or “wizard” (see Application Controller) or, in more extreme form, ASP.NET’s view state. And there are more obscure ways to track sessions. But cookies remain the most popular compromise for solving this problem in general, most web based solutions, from PHP to J2EE implementations, providing default solutions based on cookies.

Persistance on the Server

While not directly related to AJAX, thinking about what happens on the server is also important, at least when it comes to implementation time. I’ve already had questions along this line regarding JPSpan and it’s clear what’s obvious to me isn’t obvious to everyone.

This is an itchy subject in web applications. Once you’ve started using sessions, you need to live with the consequences. When you’ve only got one web server, storing user session data is no problem. But crank up the traffic volume and you start wanting to add more servers to cope with it, balancing requests between them, scaling horizontally. Suddenly you have a problem in providing all servers access to the session data.

The solution to this depends on who you ask and the arguments are often conflicting.

The J2EE crowd, for example, bought the notion that databases == evil (or perhaps database vendors == evil - independence baby!). Somehow that’s extended to database == bottleneck == can’t scale.

Meanwhile Rasmus describes shared nothing and PHP;

PHP encourages you to push scalability issues to the layers that require it. If you need a shared datastore, use a database that supports replication and can scale to the levels you need. If you need to load balance requests or distribute certain requests to certain servers, use a front end load balancer that supports this. By avoiding a central controlling process, PHP avoids being the bottleneck in the system. This is the defining characteristic that separates PHP from what people commonly refer to as application servers.

Which could be read as “pick a decent db vendor and use the features you paid for”.

The two key issues, as I see them, for scaling horizontally are efficiency and transparency. If replication traffic floods the local network your servers run on, grinding it to a halt that’s clearly bad news - now the network has to scale vertically. Meanwhile it should be possible to tap into a back end “farm” from your web application without having to significantly modify code, or even spend vast effort in design the code to scale in the first place.

So my personal bias is leaving this to filesystem or database vendors to get right. The technology is mature, it’s alot easier to tap into scalability in these layers without massive effort in code design and, perhaps most of all, the future of people like these guys depends on solving this one.

Alternatively you can take a gut level view. If you want to build something that works, talk to techies with a solid understanding of networks and, better yet, those who happen fluent in Perl and just coincidentally play a part in defining the spec we rely on and keep returning to bite later on.

Obscure side note: is HTTP subversive by design? Perhaps the design concerns were simply “This must scale” but HTTP keeps dropping reminders that the web is not there to be centralized. Attended a keynote by Roy Fielding where he remarked that he knew the work he was doing on Apache would help protect the HTTP spec. from vendors. Whether that’s in retrospect I don’t know (should have asked) but if you like the word “Open”, Roy is one person to thank.

AJAX and State

Back on track after rambling, so what’s the impact of AJAX on sessions and state in web application? Personally don’t have answers, only more thoughts and questions.

As already said, as I see it, AJAX redefines the notion of what a session is in web applications. The state of a given user’s session can be maintained client side in Javascript and will remain there so long as they don’t click reload.

Data that you “check out” from the server via AJAX resides locally and can be changed locally without the servers awareness, until you “commit” it back to the server.

A user may change their “personal preferences” in your application but this information is finally only transmitted to the server, via AJAX, on Unload and recalled on the next reload.

Technically that means we can now ditch cookies and server-side session implementations and the server side can be just as stateless as HTTP. In practice, common sense suggests it’s not so simple and this is more a matter of drawing lines in the right places, of which data should be preserved where.

Implementation Detail

Resorting finally to bullet points;

Data Loss?
User has locally modified data

  • User’s browser crashes - session data is lost. Seems like a good reason to keep those server-side sessions
  • The network / server is down and updates can be no longer sent. Use cookies as backup until data can be sent? Security implications of that?
  • Can we send data reliably? Are we sure it got there? HTTLR?

When to transmit changes?

  • Do we want fine grained updates? Transmit the change as the user makes it. What’s the network cost? Or should we send a bunch of changes together, e.g. onUnload? See Point 9.
  • Do we transmit changes automatically, without bothering the user? Or do we give them a “Save” button, like Word, and warn them of potential data loss onUnload? Ever thought how 1990’s that Save button is?

Difficient Runtimes
Are we heading for nightmares with Javascript garbage collection? Certainly keeping 100,000 records on the client is going to be a bad idea.

Concurrency

Users A and B are both modifying record X. User B “saves” then User A “saves”, overwriting User B’s changes.

Technically this is already problem with todays web apps but think the “immediacy” data exchange with AJAX compounds the problem. It’s notiously difficult to implement “locking” mechanisms effectively over the web, given statelessness and inherent “brokeness”. Best attempt I’ve seen is Dokuwiki, which users timed locks to prevent multiple users editing together.

Authentication

Somehow HTTP Basic Authentication appeals most to me as something you can implement transparently, vs. “inline” authentication based on something like cookies / server sessions or POST data.

Problem is there’s pretty much no access to the browsers HTTP basuc auth APIs with XMLHttpRequest, other than two arguments to the open method;

[code lang="javascript"]
void open ( AUTF8String method , AUTF8String url , boolean async , AString user , AString password )
[/code]

My own experiments with them suggest they’re better left unused - farm this problem off to the browser and rely on the HTTP status codes.

What else?

Synchronous Requests == BAD

May 25, 2005

This is one point where I agree strongly with the name AJAX - remember what that first letter stands for…

To grasp why, it’s worth seeing some examples and discussing which I’ve attmpted before here.

In essence, when you make a synchronous call with XMLHttpRequest, everything else stops and waits for the request to complete. And that means everything - even any intervals you’ve set. You can’t even abort() the request via the readyStateChange property (don’t believe me? try and watch a [browser dependent] crash…).

In other words submitting a synchronous request puts you at the mercy of the network and the server you’re making the request to. While developing on localhost, you’ll probably be unaware of this and living under the illusion that synchronous requests are just fine. But on a live site, if the server happens to get Slashdotted, while you’re busy SJAXing, expect a very long wait and a dead browser - to an end user, particular when using IE, it looks like it’s crashed (if I remember right IE does eventually recover but only after about 5 minutes).

To really get a feel for this you need to see it in action, which I’ll do with the help of a simple Python HTTP server that only accepts on request at a time, then goes into a sleep for 10 seconds before serving the next request. Any other incoming requests have to wait until the server is free to continue working. This sort-of-simulates a web server that’s got too much work to do.

Note if you’re using Windows and don’t have Python installed, do so - it’s completely painless. Make sure you add the python executable to your PATH (i.e. Start > Control Panel > (Administration) > System > Advanced > Environment Variables and add C:\Python24\ at the end of the PATH variable).

The code for the server is simply;

[code lang="python"]
#!/usr/bin/python
# minimal web server. serves files relative to the
# current directory.
#
# See: http://effbot.org/librarybook/simplehttpserver.htm
# http://docs.python.org/lib/module-SimpleHTTPServer.html
# http://docs.python.org/lib/module-SocketServer.html
#
# IMPORTANT QUOTE:
# “[the basic SocketServer implementations] process requests
# synchronously; each request must be completed before the
# next request can be started.”

import SimpleHTTPServer
import SocketServer
import time;

PORT = 8000

class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
# Go to sleep for 10 secs after serving request
time.sleep(10);

httpd = SocketServer.TCPServer((”", PORT), MyHandler)

print “serving at port”, PORT
httpd.serve_forever()
[/code]

Put this in some directory on your filesystem, in a file named server.py. Now add another file called response.txt to the same directory, containing simply;

[code]
Hello World!
[/code]

Finally add a third file called ajax.html to the same directory, containing the following;

[code lang="xml"]



Do it!


[/code]

With that done, you can now fire up the server script - run server.py. For Windows users that’s something like;

[code]
C:\path\to\server.py
[/code]

If you put the python executable in your path or;

[code]
C:\Python24\python.exe C:\path\to\server.py
[/code]

if you didn’t.

The server is now listening on port 8000 so you should be able to access from your browser via the URL http://localhost:8000.

Follow the link to the ajax.html. Now click “doIt” a few times and see what happens - sometimes you’ll get a quick response (an alert that says “Hello World!”). Other times you’ll get a longish wait, during which your browser will be hung up. Now imagine users starting to fidget…

Then, to really see why synchronous requests are a bad idea, try running Apache Benchmark at the same time (it’s provided with Apache 2 as an executable for Windows users) e.g. from a DOS box;

[code]
C:\Progra~1\Apache2\utils\ab.exe -n 50 http://localhost:8000/response.txt
[/code]

Now try clicking on that “doIt” link a few times. Is this something you really want your users to experience?

Otherwise, another thing to try to really grasp the difference between synchronous and asynchronous requests is watching code execute with Venkman.

The bottom line here is remembering the Internet has instability built in - it’s a network you don’t control and can (and will) vary in percieved responsiveness, like when they release the verdict on Michael Jackson, complete with video.

The only two possible exceptions I’d make to this are for an Intranet application, where the end users are in shouting distance, or perhaps in the special case of a sychronous multipart requests (work work only in Mozilla anyway) - see this Sync Multipart demo and notice how the browser “recovers” while the request is still in progress.

So, to repeat, Synchronous Requests == BAD.

Next Page »

Credit Counseling - Credit Consolidation - Credit Card Consolidation - United Specialties
Bottom