Friday, March 17th, 2006

Ajax from Scratch: Implementing Mutual Exclusion in JavaScript

Category: Ajax, JavaScript, Programming

<p> On Developer.com, there’s the first part of a series of articles – “Ajax from Scratch” – that’s looking to describe some of the fundamentals on getting “rich internet applications” built up without any framework assistance.

In this first part, they look at something that can cause an amazing amount of headaches for developers that are dealing with it – mutual exclusion (or dealing with “race conditions”).

Any time there are multiple threads of program logic that access the same data, and execute at the same time, problems arise. Programs normally assume that the data with which they are interacting is not changing underneath them. The portions of code that access these shared data structures are known as critical sections, and the practice of letting only one run at a time is known as mutual exclusion. This situation arises in AJAX applications when the code, asynchronously handling the reply from an XMLHttpRequest, manipulates data that is also being used by the user interface code. This common data could be JavaScript variables implementing an MVC data model and/or the DOM of the Web page itself. The logic of each will break if either is making uncoordinated changes to shared data.

They note that one of the real keys to full-featured, robust internet applications is catching this before it becomes a problem, making it so that this can’t occur.

The method they suggest is the Lamport’s bakery algorithm that’s modeled off of the Command design pattern due to the lack of a thread API in Javascript. This method works by checking a shared memory space between the threads (no outside storage/resource needed) to see if it’s that thread’s “turn” to go. Unofrtunately, as was mentioned, Javascript doesn’t have any real “thread handling” methods, so the author turns to a design pattern to handle the execution of the threads themselves, ensuring that only one is firing at a time.

Of course, there is plenty of code and explaination to go along with this tutorial, and they even show how to include it into their test application they’ll be using for the series – “Gravy”. This method, unfortunately, isn’t really useful outside of a single-load reference frame, however, as the Command pattern setup only can manage the threads on that page.

Related Content:

16 Comments »

Comments feed TrackBack URI

I thought browser Javascript implementations were single threaded (hence no need for a thread API)… is this not the case?

Comment by Bob Lee — March 17, 2006

Yea, this line is funny to me:

“so the author turns to a design pattern to handle the execution of the threads themselves, ensuring that only one is firing at a time”

lol, this is hogwash… javascript can NEVER have more than one code block executing at a time. The only concern in this interruption based asynchronous environment is the order code blocks execute in, NOT whether 2 are trying to execute at the same time (which as I said, can never happen).

They’ve gone and (as seems so common in this “Web 2.0″ world) created a mountain out of a molehill.

Also, from the article…

“Wait,” you say, “why haven’t I run into this problem?” Unfortunately, these kinds of problems are timing dependent (also known as race conditions7), so they don’t always (or even ever) occur. They are probabilistic based on a number of factors. To be robust, Rich Internet Applications2 need to prevent this situation thus insuring that these problems can’t occur.

…the author has some major misconception about the javascript environment, and has made this complicated solution to a problem that doesn’t even exist.

Comment by Ryan Gahl — March 17, 2006

And that’s not the only complicated solution to a problem that doesn’t exist. Check out the setTimeout() call. Instead of using a simple closure to pass some data directly into the timeout function, he invents a Map() object that the timeout function uses to hunt down its data.

Comment by Michael Geary — March 17, 2006

Actually there is an edge case in IE where the onreadystatechange event will be executed regardless of what other code is currently being executed. At least, this is what I ran into last summer, haven’t got a testcase.

Comment by Mark Wubben — March 17, 2006

This is not a comment on the content, but why are all the links listed at the bottom in this article? The footnotes are not even links to the list of footnotes. This is 2006, people, we have hypertext!

Comment by Andy — March 17, 2006

It’s amazing that the author spent so much time writing this based on entirely false pretenses. The only meaningful part of the article is the statement that “JS doesn’t have a thread API” but unfortunately his conclusion based upon that is “so we have to write one” rather than “because it simply doesn’t have interpreter threads”.

Comment by Bob Ippolito — March 17, 2006

From the article:

The logic of each will break if either is making uncoordinated changes to shared data.

This entire problem can be solved by avoiding acquistion of references to the things you will change long before you are going to change them.

Take, for example, a multi-stage wizard that implements auto-complete in one of the stages. The user starts typing, and then the auto-complete Ajax call is fired off. Before it comes back, the user has actually entered the text in full and moved on to the next step, destroying the DOM nodes (or at least making them non-visible) that the auto-complete would fill in. There is your race condition. But why would you want to fill in a DOM node only to have it be removed since we don’t need it anymore? Or why would we want to keep the user from progressing to the next stage just because we have a pending Ajax call that hasn’t returned yet (or might not)? The function that handles the Ajax return value should look for the DOM node to manlipulate during the handling of the return value, rather than just assuming it does exist (or that the reference to it that was acquired before the Ajax call is still valid).

There definitely are server side issues with multi-processing depending on the language/environment you are using on the server, but the same issues don’t exist on the client if you don’t actively cause them. Rich Internet Applications need to prevent problems caused by client side data sharing between event handlers, but that prevention is better obtained through better programming in general, not through the addition of mutexes.

Comment by Andy — March 17, 2006

It’s a meaningful post anyway. Bruce Wallace give his thinking to that not-popular thing.

Comment by linb — March 17, 2006

Wow, such a long article to solve a problem that does not exist! Javascript code in a browser will run to completion and not be interrupted. There may indeed be many different threads invoking Javascript code within a single document, but they are serialized for you by the browser itself.

Comment by Jim — March 18, 2006

Ajaxian » Quality JavaScript from Scratch

The book mentioned here is, to me, “just another JavaScript book”. When browsing Amazon, Barnes & Noble, or any other place I get books, I’m not interested in something like this. Books devoted to Ajax and effective techniques are what I’m in…

Trackback by Random Thoughts of Jon Trelfa — March 20, 2006

hi all,

Our application uses AJAX using I.E’s webservices.htc (http://msdn.microsoft.com/workshop/author/webservice/webservice_node_entry.asp)
wrapper.

I’ve often seen more than 5 threads from I.E. This was observed in the number of servicing threads in tomcat and in Fiddler (http://www.fiddlertool.com/fiddler/) .

Bob : I’ve long wanted thread API in browser javascript. I’m not sure if that’s a focus area in javascript 2.0. Can anyone comment ?

thank you,

BR,
~A

Comment by Anjan Bacchu — March 21, 2006

Anjan, are you confusing server requests and threads with browser JavaScript threads? A browser may download multiple objects at once from a server. That doesn’t imply that JavaScript code in that browser runs in multiple threads.

Comment by Michael Geary — March 21, 2006

Although this article does seem a bit confused, there are places where you do need to worry about race conditions with AJAX. Just because you send request “A” and then request “B” to the server doesn’t mean you’ll get a response from “A” first. If “B” needs to render something within “A”, you’re going to have problems.

A command queue can help ensure that “A” responds before “B” is sent.

Also, using a command queue to chop up processing helps avoid the annoying “This script is running slowly…” message if you’re dealing with large amounts of data.

Comment by JD — March 22, 2006

Where is all this certainty about threading and JScript coming from? I cant find anything definitive on MSDN about JScript and threading or atomic operations. What is the URL everyone is looking at that specifies what Microsoft says it will implement with regard to JScript on IE (much less interacting with XMLHttpRequest)?

Comment by AL — April 9, 2006

Not a comment on the article, but the comments themselves… Yes, JavaScript is single threaded, but it sometimes triggers asynchronous events in native code, those events triggering side effects in DOM or browser state, thus leaving that simple threading model. Window.open() is one such case, though only in some browsers… apparently XHR is another.

Comment by Adam Peller — May 25, 2006

Javascript is single-threaded, so no matter how many AJAX request you have coming back at the “same time” (not the best term), only ONE will be processed at a time. There are already solutions out there for managing multiple requests, for example check out prototype.js or YUI!, both provide handles to your AJAX requests which can be checked for completed status. Here’s a simple but not so elegant example:
var req1 = {…. oncomplete:someFunction1};
var req2 = {…. oncomplete:someFunction2};
var data1 = null;
var data2 = null;
function someFunction1(response) {
data1 = response;
if(data2) someFunction3();
}

function someFunction12(response) {
data2 = response;
if(data1) someFunction3();
}

Comment by Ike Love — April 10, 2007

Leave a comment

You must be logged in to post a comment.