I ordered PAIP today. Good computer books are so expensive. It hurts me to spend $80 on a book. But there are many worse ways to spend $80 than on something which contains so much knowledge, I guess. I got a $25 gift card for a book store for Christmas, so may as well put it to good use. I've read good reviews of PAIP, so I hope it lives up to them. I had only one AI course in college, and it was taught in C (ugh) by a grad student, and I learned little to nothing from it. It'll be nice to revisit the subject. (And learn more Common Lisp, of course.)
In other non-news, my Common Lisp-powered website is still up and running after a few days, no crashes or spontaneous hard drive reformats or anything, so that's good. Deploying it was interesting. Actually compared to the one Ruby on Rails site I deployed, Hunchentoot was far easier to deploy in many ways.
When you deploy Rails you have the problem that Rails is a beast of a framework, and Ruby is slow as a dog to begin with. So there are all kinds of silly nasty ugly hacks to get it to run with acceptable performance. Personally for my Rails site I have to run three Mongrel servers and use Apache's mod_proxy_balancer to send traffic to them. Some other people use fastcgi or such CGI-caching scripts, which I never could get working well. Just to run Rails apps at all, there are all kinds of Apache mod_rewrite hacks going on to get routes to work. Etc. etc. etc. It's a huge mess and I pray my Rails server never dies because I sure don't want to have to go through to pain of re-deploying it now that it's up and running.
With Hunchentoot on the other hand, you start Lisp once and it runs forever. No Apache to screw with means happy times are had by all. In fact my Hunchentoot-run website does exactly what Rails routes do, all via a single function that parses the request URI and dispatches based on it. With no .htaccess wizardry or cryptic Rails config files anywhere in sight.
Every request to Hunchentoot is apparently handled in a Lisp thread, so concurrency issues are generally all taken care of for you, no worries. In fact since you have Lisp running forever you can get away with crazy things like using Lisp objects as a sort of cache for data instead of hitting your database for every request, which I imagine probably works wonders for performance. I'll never know for sure, because my site will never ever be popular enough to put it to the test, but one can dream.
There were a few snags deploying my Hunchentoot server, none of which were the fault of Lisp, more the fault(?) of Linux. One was that I wanted to bind Hunchentoot to port 80. As you may know, only root has the right to bind a program to a "privileged" port like 80. I certainly did not want to have a Lisp image permanently running on my server as root, for security reasons. Thankfully Debian has a drop-in solution for this in the form of authbind, which lets normal users bind programs to privileged ports.
The second problem is that Common Lisp via SBCL is a sort of interactive program (see also, the REPL), and isn't really made to be run as a daemon, at least not the way I usually run it. There are many solutions to this however, and the solution I chose was detachtty, which does exactly what the name says. As the linked site describes, it's like a very stripped-down sort of GNU Screen.
Then there's the issue of how I can log into that running Lisp image from my home computer to run commands. I could easily SSH to the server, and use
attachtty (which comes with detachtty) to attach to SBCL directly and type commands there. But SBCL's built-in REPL is a bit primitive. SLIME would be nicer. The solution here is to start Swank on the server. then use Slime running on my local machine to connect to the remote Swank.
This is, again, extremely simple. In a previous entry I linked to a movie that describes in great detail how this can be done, start to finish. You can see another more thorough example of how to do it here. Essentially you run
SWANK:CREATE-SERVER in the remote SBCL; Swank binds only to localhost on the server, so to use it from home, you then have to make an SSH tunnel. Local Emacs can
slime-connect to the remote Swank via the tunnel.
So that's it. authbind starts detachtty, which runs SBCL, which --loads a little 5-line Lisp script that imports some libraries and my photo blog source code, then starts Swank, and then starts my server. A little init script to make this happen by default every time the server reboots, and there's nothing more to be done. There's no real need to restart the server from now on, since I can log into the REPL and run commands and update the running program on-the-fly. But if I had to restart it or redeploy it entirely, it would be no problem.
This strikes me as an example of one of the great things about Linux. Many small tools that all do a single job very well. A tool to let non-root users bind port 80, a tool to let you run any program as a daemon, the glue to make those things work together with SBCL, and a great text editor to talk to SBCL after it's running. It all works beautifully, and there are no mysteries anywhere in the process start to finish.