Friday, 22 May 2009

Serving Gambit Web Applications behind Apache

Now that writing web applications in Gambit Scheme is so easy using Black Hole, I thought I'd write an article on how to set everything up from scratch using Apache as a front end web server.

Using Apache as a front end web server isn't strictly necessary since the Black Hole web server fully supports HTTP and is capable of serving static as well as dynamic content but for robustness, SSL support and to offload the serving of static content it makes sense to place Gambit behind Apache.

Gambit uses lightweight internal threads which allows it to efficiently support thousands of concurrent requests but these run in a single OS thread. This means that if you are running on a multicore or multiprocessor system, you will need to run multiple Gambit processes and load balance between them in order to fully utilise the available CPU. The load balancer would need to be 'sticky' unless you are going to serialize continuations outside of Gambit.

Enter Black Hole
Black Hole is primarily a R5RS compatible module system for Gambit which allows you to easily import libraries into your code including macros which has previously been tricky on Gambit. Conversely you can also export your own code and create your own libraries to fully modularise your development. This is basic stuff but the lack of it has really stifled development on Gambit. For the web developer, the most interesting aspects are the bundled libraries for web serving, SXML and the 'Spork' continuations based web framework.

Getting Started
This guide is based very much on Per Eckerdal's Black Hole Tutorial guide but has been extended based on my own experiences using Black Hole.

Installing Black Hole
Assuming that you have Gambit installed, you need to download the latest Black Hole code from the git repository :-

git clone

That will clone the current code repository to 'modules' directory in your working directory, you now need to copy or symlink this directory to the Gambit lib directory e.g. C:\Gambit-C\v4.4.3\lib\ on Windows to create ~~/lib/modules.

Although not strictly necessary, now would be a good time to build all the modules :-

cd \Gambit-C\v4.4.3\lib\modules
gsc build

Black Hole is now installed and ready to use, simply do a (load "~~/lib/modules/build") in Gambit to initialise. It is recommended that you use gsc rather than gsi because Black Hole uses compilation features that aren't available in gsi.

For convenience, you can create a wrapper command that loads Black Hole at startup, e.g. on Windows :-

bsc.cmd :

gsc -:dar- -e "(load \"~~/lib/modules/build\")" %1 -

Copy this to your Gambit bin directory then you can use 'bsc' in future instead of gsc or gsi.

Setting Up Apache
In this scenario we are using Apache to proxy the requests through to Gambit and to serve any static content, here's a sample Virtual Host setup from httpd.conf :

<VirtualHost *>
ServerName localhost
ProxyPass /spork http://localhost:8080
ProxyPassReverse /spork http://localhost:8080
DocumentRoot ${path}/www

This configuration will forward any requests with a URI that starts with '/spork' to the Gambit server running on port 8080. Any other requests will be served from the 'www' directory under Apache.

Creating your Spork Application
So you are now ready to go, fire up Eclipse (with SchemeScript) or your alternative favorite development tool. Start your Gambit REPL window (with bsc or load the modules manually).

Enter this into REPL :-

(import (std spork/core))

(define c (spork-serve root: "/spork" ))

(add-spork c ("one")
(title "Hello, world!"))
"This is my first web application using Spork :)")))

And fire up your browser :-

OK it's not a spectacular example but you are setup now ready to do some more serious development effortlessly through REPL - just redefine the function and retest with no need for a restart.