Sunday, September 30, 2012

Sequential Chaining of Nested Callbacks

Back in the old days of programming, the days we used to have blocking function calls, things were easy: first do this, and then do that, and finally clean things up. While this sequential style of programming has its own advantages in terms of human perception, it imposes certain concurrency related limitations. That is, each expression in a program is supposed to wait for the completion of the execution flow up until the line above, regardless of if it has anything to do with the current expression or not. Asynchronious programs are known to solve this problem of concurrency, (at least, to some extent) with the cost of sacrificing the sequential program flow. At its most basic form, functions are provided interfaces to specify dependencies between each other and hence, independent functions are allowed to execute concurrently. These interfaces are generally provided in the form of callback functions, that is, when f() gets completed do g(), and when g() completes do h(), and so on. The premise of this blog post is to investigate whether it is possible to still preserve the dependency between functions by still allowing the programmer to syntatically structure the program sequentially.

In the context of asynchronious programming, JavaScript is an exceptional example, where almost every functionality in the language is shaped according to asynchronous callbacks, which eventually enforces you to program in a totally top-down callback-oriented style. In this post, I prefered to use CoffeeScript (which is a programming language compiled to JavaScript) to enhance the plain text the explanations.

Ok, enough talk. Let's start with working on a small sequential program snippet.

Simple and intuitive. You just grab the logic behind at first sight: First, connect to the database, and then query the rows of a table, and finally close the connection and return the results. And as a bonus you can catch errors that would occur during this sequence. Here is its asynchronious, callback-driven counterpart:

Um... Not as intiutive as its sequential counterpart. And the nested callback chains expands the code to the right, which makes it harder to understand as well. But, not that bad... with a serious glitch: Orphan exceptions. That is, for instance, who is supposed to catch a connection error exception after db.open completes gracefully and the execution passes over the try-catch block? While code will be get polluted a little bit, this problem can be tackled by returning an error, instead of raising an exception.

Better now, at least in terms of correctness.

So far, we always beforehand knew the callbacks that will be nested into each other. That is, we knew that a simple query will follow just after the database connection gets established. What if we wouldn't? What if the next callback is to be dynamically determined according to a runtime variable? Think about this scenario: You need to query the database multiple times depending on the input passed by the user. A pretty common day-to-day practice. Terrorizing the code with unknown number of nested callbacks would buy us no credits.

On the other hand, forming nested callbacks using a recursive function solves the problem.

I admit that this is not intuitive, also more error-prone. (I also could not be sure if I wrote it right. But anyway, you get the idea.) There must be some other way. Wouldn't it be cute if there would exist some sort of sequencer mechanism that allows me to sequentially chain my nested callbacks?

This Aha! moment helped me to come up with below tiny helper class.

SequentialExecutor helps you to push your functions into an array and executes them in order for you. Specifically, it passes you the pointer to the next function (i.e., next) that is supposed to be executed after current function. So, it is up to you to execute it or not. Here is an example using this cute SequentialExecutor class:

Yes, now we have something! Let's also try to implement the case where the total number of queries are dynamically determined on the run.

Oops! That is not what we were expecting. Database connection is supposed to be closed at the end of the execution flow. Hrm... Can't we enhance SequentialExecutor to label tasks with priorities? Here is the poor man's sequential executor with priority support.

Let's give our new gear, PrioritizedSequentialExecutor, a try.

Mission accomplished! Now we have a fully-fledged sequencer where we can dynamically push tasks with different priorities.

Note that while PrioritizedSequentialExecutor is quite good at doing what it is advertised for, especially compared to the lines of code written, there exists other libraries (e.g., seq, chainsaw, futures, async, windjs, streamlinejs, etc.) with similar flow-control purposes. While you are at it, you might want to check them out too.

Sunday, September 16, 2012

An Authentication Service for AngularJS

I am so tired to form up explanatory, coherent sentences, but at the same time I really like to share a user authentication service that I wrote for AngularJS. Hence, pardon my brevity.

In this example I use RailwayJS with CoffeeScript both at the client- and server-side. (See my previous post on auto-compiling assets with connect-assets.) Here is the scenario: You have assignments.html such that only authenticated users are allowed.

First things first, here is our /config/routes.coffee:

Then we implement our controller /app/controllers/home_controller.coffee as follows.

Note that the authenticate used in login action handler is meant to be provided by you.

Later, we write /app/views/home/index.ejs to fire up AngularJS:

We first start by implementing app.js of AngularJS in /assets/js/app.coffee:

The extra bit for listening on $rootScope for $routeChangeStart is to check access to authentication required pages.

After app.js, we implement /assets/js/controllers.coffee:

For each controller, we implement a view, that is, /public/partials/login.html and /public/partials/assignments.html:

And here goes the magic, /assets/js/services.coffee:

Hope it works for you as well.

Auto-Compiling Assets with connect-assets

I have been using RailwayJS for a couple of weeks with great satisfaction and joy. Its built-in support for CoffeeScript files is fantastic. That being said, like a majority of other NodeJS web frameworks (e.g. Geddy, Tower.js, SocketStream, FlatIron) it doesn't provide a way to ship client-side CoffeeScript files. (In this context, Meteor represents a notable exception, where it is capable of handling CoffeeScript files both at the server- and client-side.)

To establish a complete CoffeeScript experience both at the server- and client-side, one can use connect-assets by Trevor Burnham to auto-compile assets (i.e., CoffeeScript, Stylus, LESS files) on-the-fly. For this purpose, you just need to (1) add a app.use require('connect-assets')() line to your environment.coffee, (2) create js and css folders under assets directory, and you are ready to go.

One minor glitch that you need to pay attention is, while using connect-assets, you must include asset files using accessor functions ‐ js() and css() ‐ provided by connect-assets. These functions in addition to generating necessary <script src="..."></script> tag, also register the file into the asset processor service. connect-assets auto-compiles an asset the first time it is called and caches the produced output in memory; later calls will be served from the cache. (It also provides options to write produced outputs to disk and watch file changes.) For instance, say you want to use /assets/js/main.coffee in /app/views/main/index.ejs file. For this purpose, you need to add <%- js('main') %> into your view for enabling connect-assets serving your main.coffee file.

As a final note, since connect-assets is a Connect plugin, you should be able to run it on any other web framework that runs on Connect or ExpressJS.