UCW Server

Ahh, finally recovered my password. I had this entire entry written and was starting to look for links, but lost it as I enabled javascript for livejournal elsewhere on the site and could not find any way to recover the list info. This has happened to me before, and makes me a sad panda. I’m now editing in vim with the intent to copy&paste to the livejournal window. *sigh*

I’ve decided that I like UCW a lot, even though there is a steep learning curve (for me, at least). UCW makes heavy use of CLOS and (non-hygenic) macros, so I’m having to learn a lot about CL that doesn’t necessarily carry over well from scheme.

So let’s start by creating a basic server, as well as some utility functions to allow us to generate various kinds of images. The examples I’ve seen of UCW all seem to exist in the UCW-STANDARD package, sooooo

(in-package :ucw-standard)

The only server component in UCW is named STANDARD-SERVER, but it is capable of utilizing different backends. I create a global variable with an instance of the server class attached to the iolib backend. The other backends include an httpd module as well as a mod_lisp adapter. As iolib is the default development backend and I’m told apache‘s mod_proxy iolib is faster than mod_lisp, we might as well use it.

(defvar *ucw-server* (make-instance 'standard-server
:backend (make-backend :iolib :port 9090)))

UCW comes with a standard startup and shutdown pair that takes the server instance as a parameter. I wrap these with trivial funuctions and export them to allow easy use from other packages, such as COMMON-LISP-USER.

(defun startup-thang () (startup-server *ucw-server*))
(defun shutdown-thang () (shutdown-server *ucw-server*))
(export '(startup-thang shutdown-thang))

Next, I have a few SBCL specific functions to generate various image types to allow for faster loading. Note that I do not set up the various hooks, so these cannot be run from a threaded image (such as one where swank or ucw is running). My current approach is to allow the current image to continue running as I invoke a new one to compile, then shutdown the old one and start the new one up. These are explained by the SBCL manual, so I won’t explain them, just toss my source out.

(defun thang-init ()
(sb-alien:alien-funcall (sb-alien:extern-alien "disable_lossage_handler" (function sb-alien:void)))
(sb-impl::toplevel-init)) ; execute the repl

(defun save-out-core ()
(sb-ext:save-lisp-and-die "thang.core"))

(defun save-out-auto ()
(sb-ext:save-lisp-and-die "thang-auto" :executable t :toplevel 'thang-init))

(defun save-out ()
(sb-ext:save-lisp-and-die "thang" :executable t))

As well as a UNIX Makefile to wrap around the image generation commands.

.PHONY : clean

all: thang-auto

rm -vf *.fasl thang.core thang thang-auto


thang.core: $(SRC)
sbcl --eval "(require 'thang)" --eval "(ucw::save-out-core)"

thang: thang.core
sbcl --core thang.core --eval "(ucw::save-out)"

thang-auto: thang
./thang --eval "(ucw::save-out-auto)"

Last modified on August 14, 2012. This entry was posted in Uncategorized and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.