Alex Rivera | Logout

Ajax concurrency

Asked 2010-01-16T17:12:39.437
16

I have a web application where there is a timer that is constantly counting down. Meanwhile, the client frequently checks with the server to see if more time has been added to the timer. The code looks something like this:

function tick() {
    // This function is called once every second
    time -= 1;
    redisplay(time);
};
function update(newtime) {
    // This function is called whenever the ajax request
    // to the server yields a new time
    time = newtime;
};

It is, of course, a bit more complex than that, but you can see the inherent race condition. What if the update and the tick function are both trying to modify time at the same time?

Frankly, I don't know nearly enough javascript to understand how to deal with this sort of concurrency issue: is there an easy way to do this, or if not, can somebody point me towards resources where I can learn more?

Thank you.

Edit
Report

3 Answers

8

Javascript is single threaded. There is no race condition. There's no way in javascript for the two lines time = newtime; and time -= 1; to overlap during execution. In fact, the two functions are guaranteed not to overlap. One of them will run and then the other will run.

answered 2010-01-16T19:35:47.513
-1

The problem needs some semaphores. I do that a lot for sending ajax after previous one finishes. Your case is a bit alike ;)

Try something like that. It should ignore all attempts to decrement time that collide with ajax callback.

window.TimeKeeper = new function(){
this.time=0; //initial value, whatever
this.isopen=true;

this.decrement = function(){ 
 if(this.isopen){
  this.time--;
  redisplay(this.time);
  }
 }
this.set = function(val){
 if(this.isopen){
  this.isopen=false;
  this.time=val;
  this.isopen=true;
  } else {
  //another AJAX callback is modifying time. 
   //You can enqueue current value and put it later
  }
 }

}

function tick() {
    TimeKeeper.decrement();

};
function update(newtime) {
    TimeKeeper.set(newtime);
};

One more thing - the setTimeout works like a new thread and I would expect that browsers do the synchronising mem access, so It might be enough to check if the value didn't grow before decrementing. But the above solution is more flexible and safe.

And one little tip - avoid querying with AJAX too often - it may cause extra problems - like requests coming back in different order than sent, and firefox memory usage building up a lot on too much ajax a minute ;)

answered 2010-01-16T19:14:09.323
-2

As long as you add some more seconds to you current time you should be fine.

Instead of doing time = newtime; try time += newtime; This way you will not lose the second you're worried about.

Still, you are only losing a second at worst.

answered 2010-01-16T17:17:43.947

Your Answer