Asynchronous Semaphore

Semaphore

Semaphore is a super simple notion, in short it is a “method of controlling access by several processes to a common resource”

Think about a Database that can provide no more than 5 parallel connections OR a bit more complex, a buffer that has X slots with few parallel readers and writers..  ( readers-writers problem)

When process A “need” a unit of a specific resource, process A calls the P() method which checks: if the semaphore value is larger than 0 (which mean that the resource has some free units) then it decreases the semaphore in order to state that one of the units is now taken. otherwise P() makes process A to wait until some other process increases the semaphore value.

When process A doesn’t need the unit anymore, process A increases the semaphore value ( by calling the V() method which also signal the other processes that have been blocked).

As for naming conventions, in case the resource has only one unit we call it a binary semaphore otherwise it’s a counting semaphore.

** it’s important to mention that P() and V() are atomic methods.

Asynchronous Semaphore

This was a short description of a Semaphore, but what is Asynchronous Semaphore (hereinafter: ASemaphore)?

In the asynchronous programming world, sometimes we would like to call N async methods, imagine that we would like to invoke a different F method (async or sync) only after ALL the N methods got invoked.

Asynchronous Semaphore is a construct that support this requirement.

(In short asynchronous method is a method that will get invoked later on in time, yet the thread doesn’t block and wait() for its results, the thread runtime continues to the next line of code. the async method usually get a “callback() method” as a parameter and invoke it when the results arrive.  ( E.g. setTimeout,  DHTML events, most WebServices invocations))

The ASemaphore works a bit different than the Semaphore, it gets the F function as a parameter , and it fires it only when the counting variable equals to zero, before calling a async method we increases the counter and when the async method get invoked we decreases the counter.

Here are the details: One should initialize the ASemaphore with the F method and increases it (calling V()) to one.

Before calling a async method, One should increase the ASemaphore (V())

Internally to the callback() function one should decrease the semaphore (P()).

After calling all the N async methods, One should decrease (p()) the ASemaphore.

The Asemaphore fires() only when the counting variable equals to ZERO.

* notice that the ASemaphore is a solution for the asynchronous world for a specific process and therefor parallelism is not an issue ( the methods P() and V() aren’t atomic)
** notice that it’s irrelevant to use a binary ASemaphore, in case of only 1 async call you could easily invoke the F() method internal to the async method callback()

Examples

1) In my Alligator project, when rendering a page on the server-side, one might develop a JSSP scirpt that invokes few asynce calls (e.g. putting a variable on the memcahced, dealing with the file system, connecting a database), yet Alligator needs the send the HTTP response back to the client only when all those methods have been invoked…

2) One had like to call 10 timers with random time and notify only when the last one is all set.

JavaScript Impl’

I have implemented an ASeamphore in JavaScript, you can find it on my github repository.

The actual code can be found here

var ASemaphore = function(semaphore,fireFunc){
	this.semaphore = (semaphore==undefined?0:semaphore);
	this.fire = fireFunc;
	log.debug("Starting Asemaphore with semaphore:" +this.semaphore);
};

ASemaphore.prototype.v = function(){
	++this.semaphore;
	log.debug("Asemaphore semaphore after v(): " +this.semaphore);
	return this.semaphore;
};

ASemaphore.prototype.p = function(){
	if((--this.semaphore)<1){
		log.debug("Asemaphore fire() after p()");
		this.fire.apply(this,arguments);
	}
	//log.debug("Asemaphore counter after p(): " +this.counter);
	return this.counter;
};