Saturday, September 6, 2008

Resurge


Seed revolt
still stifled stymied
from 68 and 40; blossom

Friday, September 14, 2007

Handling asynchronous JavaScript

JavaScript in its current client (browser) implementations does not support multi-threading or any other form of real concurrent programming 1). However, JavaScript in the browser does often portray asynchronous behaviour as:
  • some API members (like XMLHttpRequest and parts of Flash and Google Gears) are truly executed parallel to code running in the JavaScript interpreter. However, JavaScript functions called from the API (callbacks) are executed sequentially to any code running in the interpreter.

  • use of global functions setTimeout and setInternval allow for a
    kind of cooperative multi-tasking .

A web developer therefore can be confronted with several pitfalls of concurrent processes. Trouble is that JavaScript does not provide the programmer with any built-in mechanism to cope with these issues, i.e. you have to build them yourself.

Note that the standard way of dealing with asynchronous behaviour in JavaScript is to plug into its event-driven programming model and utilize custom events. Although you can directly handle things from within a callback function, it's more convenient to raise an event and let other part of the application worry about handling the event. Note that there are a lots of issues concerning browser compatibility so it is sensible to utilize a JavaScript library to abstract away any differences in event handling between the dominant browser version.

For example: a callback executed by any XMLHttpRequest started from a function "authenticate", will update the global variable "loginStatus" and consecutively raise the event "loginStatusChanged". Several components on the page (a login status indicator, a user profile information box, different content areas which show user-related information) are all subscribed to this particular event and will independently update their contents.

Although different "repaint" functions could be called from within the callback as well, the clear advantage of using events is that it conforms to the idiomatic way of system interaction, while separating the generator of the event (e.g., the XMLHttpRequest callback) from the handler(s) of the event (the page components) means that the separate pieces are kept loosely coupled and can easily be designed and modified independently of each other.

Note that keeping global state in order to handle asynchronous event might not be sufficient to deal with concurrency problems. A typical example would be animations. These are performed having the setTimeout or SetInterval global function repeatedly call a function which will "draw" one "frame" out of a series, creating the illusion of movement. Code below shows an example using JQuery:

var ef = function(e) { //2)

if ($(e.target).css("opacity") > 0.90)
$(e.target).fadeTo(1000, 0);
else
$(e.target).fadeTo(1000, 1);
};

$("div#panel").mouseover(ef); //1)

  1. A div with id "panel" is assigned a function for the "mouseover"
    event

  2. when the user moves the mouse over the panel, the event-handler
    will make the opaque div fully transparent and vice versa

If the event is fired multiple times before the animation has finished, the effect will be ruined as the animation will be started multiple times. Instead you would want the events to wait (or to be ignored) until the animation has finished so the effect would be a smooth on-and off blinking of the div when the user hovers the mouse over the panel.

This can be achieved by creating a so-called "mutex" variable, which will store the state of whether the function is currently running or not. You could use a global variable for this purpose but this would quickly become unwieldy if more mutex variables would be needed while a fixed number of global variables would prevent utilizing a variable number of functions.

Alternatively implementation could be done in such a way that the mutex is bound to the function object itself. In this case a global factory function "lock" will encapsulate any event handler within an anonymous function which will function as a stub and intercept any call to the event handler.

function lock(f){
var in_f = false; //1)
var _f = function(){

if (in_f) return; //2)

var clear = function(){
in_f = false;
};

var args = [clear]; //3)

for(var i = 0; i < arguments.length; i++){
args.push(arguments[i]); }
in_f = true;
f.apply(this, args); //4)
};
return _f;
}
  1. the event handler is passed to the lock function. The interface of the event-handler function will change as the lock function will call it with a reference to the clear function

  2. this function will be called from the callback which is being
    executed once the animation has finished.
In this way the animation will be smoothly "blinking". Note that although the function resembles the "synchronized" or "locked" keywords from Java and C# respectively, the JavaScript function is not really equivalent as the mutex is effectively non-blocking: the functions will not wait for the original function to finish. Apart from not having the desired effect in this particular case, the real point to make here is that in JavaScript it would not be possible to implement this is a straight forward way.

A way to achieve this would be to create a synchronization queue to which any halting function would need to be added. After completion of the original event-handler it would then be possible to "continue" with any function reference which was added to the queue.

Note that such a queue is also the way to implement a mechanism when separate asynchronous processes need to be executed sequentially and in a particular order. A good example would be multiple XMLHttpRequest calls. Suppose we model two calls to an synchronous functions with the following code:

function async(timeOut, func){
setTimeout(func,timeOut); //1)
}
}

async(3000, function() {alert("Async1"); next();} );
async(200, function() {alert("Async2"); next();} );

  1. the setTimeout function will execute the function after the specified timeout in milliseconds.

Note that in this case the second process obviously ends before the first one, somethings which would be a very real possibility when using XMLHttpReuquest. A solution would be the following serialized function queue:


function assyncChain(init){
var _procs = null;
var idx = -1;
var _init = init;

var next = function (){ //3)
idx++;
if (idx >= _procs.length) return; //abort if no more procs to run
var _proc = _procs[idx];
var _args = _proc.arguments || []
_proc.func.apply(null, _args);
};

var add = function (){
var _proc = {};
_proc.func = arguments[0];
_proc.arguments = [];
for(var i = 1; i < arguments.length; i++ ){
_proc.arguments.push(arguments[i]);
} _procs.push(_proc);
};
return function(){ //1)
if (_procs == null) {
_procs = [];
init(add, next);
}
idx = -1;
next(); //2)
};
}

var chain = assyncChain(function init(add, next){ //1)
add(async, 3000, function() {alert("Async1"); next();} ); //4)
add(async, 2000, function() {alert("Async2"); next();} );
});
chain();
  1. the factory function will return an anonymous function which when called will call the initializer function which need to be passed to it. The user can add the asynchronous functions which need to be added
    to the queue from within the initializer.

  2. after initialization the first function in the queue will be
    executed through the next function

  3. the next function will fetch the next available function from the queue and call it with the arguments as supplied from the initializer function

  4. the asynchronous function delegates control to the next function
    in the queue by calling the "next" function.

Note that the queue can easily be extended with a priority mechanism and with a way to dynamically change the order of execution.



1)Rhino, the "other" JavaScript implementation of the Mozilla Project, does support multi-threading

Tuesday, September 11, 2007

Gifted

I came across this blog post about a job offer posted on infojobs.net by my previous employer in the beginning of this year. A weeny bit xenophobic but slightly amusing nonetheless. Apart from the rather entertaining and pointed impressions of the company and its website, the author rambles on about the "typical endless list of requirements" in order to attract an authentic "superdotado" (gifted person). But apart from the deliberately roaring title, the offer contained a clear description of an all-round developer, well versed in either Java, DOT.NET or LAMP with some web client-side stuff sprinkled in. To describe such a programmer derisively as "gifted" is probably a telling indicator about the skill-level of the author.

A common attitude among web designers and developers alike is to flinch at the effort required to become a skilled C# or Java programmer. For a programmer brains is a bonus, back-bone is a must. We are talking about a serious intellectual investment here, which seems hard to grog for those which lack experience or a formal training in computer science. Mind you, part of that is cultural: you need to be creative and inspired rather than (yawn) disciplined, methodical and studious in order to be a web monkey. But probably the main reason is that the low entry barrier to web development means that it has attracted a lot of people for whom the prospect of becoming an all-round programmer is unattainable as they cannot cope with the sheer amount of study and hard work required to become a real hacker.

Mind you, there are quite a few exceptions. I have known several "web developers" who would humble any "software engineer" with their knowledge, professionalism and craftsmanship. But then, it took them years of hard work to become the giants they are now. No free ride for them either. And many developers, having attained a rather precarious skill-level, seem to fall victim to a certain degree of sloth. "OOP" is the final paradigm and they will cringe when scary alien things like Haskell or Erlang will get too close to their comfort zone. That stuff is too ephemeral, too academic. For the "gifted" among us.

Problem is that the times really are a-changing. Lots of those weird concepts from functional programming are making their way into the main stream. C# 3.0 is a completely different beast from the original Java clone of a few years ago which carried the same name. And although the model of web development, that of scripted markup languages, seems to become more pervasive, none of the new developments in that respect (Adobe Air, Microsoft SilverLight, a whole series of new Mozilla initivatives, ECMAScript 4) are very forgiving for those with only a faint grasp at their craft. It's going to be a tough ride for those who gather that studying is only for the "gifted".

And as an answer to the blogger: we did find a "superdotado". A young programmer, quite experienced with Java and HTML/JavaScript and after a few months up to speed with DOT.NET as well. He is talented, a good all-round coder, speaks excellent to fluent English, French, Italian and Spanish of course, as he is from Valencia, Spain. And the best yet, he will not consider himself "gifted" but will work and study long strenuous hours to better himself.


Clean sheet

Last August, through all the turmoil, I felt a sense of relief as well. A fresh start: working again as a free-lancer, applying for a new job, perhaps even going in more adventurous directions. "To be free again". But like a clean sheet of paper beckoning fresh prose invariably leads to a daunting writers block, it took me nearly two weeks to get started on updating and translating my CV. In Spanish this time as I can no longer hide from the simple fact that migrating to Spain also means working and living in Spain. Hoy empezó el resto de mi vida, so I got going.

I pretended a writers block (or was it the crushing pressure of work load and mediocrity) kept me from from taking up writing again. I lost most of my data during the move to Spain so that did not really help matters. A clean sheet indeed. So today I took the plunge and decided to "get back online".