Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using ASDF to start Hunchentoot

I'm working on a web app using Hunchentoot (on SBCL and Linux), and usually I just run it from Emacs (SLIME), but for deployment I want something that's easier to automate. So I'm trying to figure out ASDF, because that seems to be what everybody's using these days.

myapp.asd:

(in-package #:asdf)
(defsystem :myapp
  :name "my app"
  :depends-on ("hunchentoot")
  :components ((:file "package")
               (:file "server" :depends-on ("package"))))

package.lisp:

(defpackage myapp
  (:use :cl))

server.lisp:

(setq hunchentoot:*dispatch-table*
      (list (hunchentoot:create-static-file-dispatcher-and-handler "/foo" "foo")))
(hunchentoot:start-server :port 8705)

If I try loading it by hand:

$ sbcl
* (require 'asdf)
* (asdf:operate 'asdf:load-op 'myapp)

it loads and compiles a whole bunch of functions, but then just stops. Hunchentoot isn't running, and the prompt doesn't accept input. I don't know what state it thinks it's in: the last lines printed are:

STYLE-WARNING: Implicitly creating new generic function STRINGIFY-COOKIE.
STYLE-WARNING: Implicitly creating new generic function DISPATCH-REQUEST.
STYLE-WARNING: Implicitly creating new generic function WRITE-HEADER-LINE.

Is there a way to make this work? (Confession: I really don't understand ASDF or Common Lisp packages very well at all, despite many hours of reading about them.)

like image 475
Ken Avatar asked Mar 21 '09 20:03

Ken


2 Answers

Running Lisp applications from command line

Many (not all) Lisp implementations support a save-image (or save-world or dump) mechanism that will encapsulate a body of code and run functions at startup. As another poster said, these mechanisms are platform- and vendor-specific.

Most Lisp implementations (all?) have a command-line interface. So a conventional approach to deploying a Lisp application is to wrap a shell script around Lisp. The script must set up the program environment and pass command line arguments. Typically the runtime context includes application files to load (via ASD or LOAD-FILE) and one or more forms to evaluate or functions to run.

Using / extending clbuild

You can roll your own script, or you can re-use some existing technology. Take a look at clbuild which is useful for several reasons. (See below for more about clbuild functionality and portability.)

You can extend clbuild to run your own application with command line arguments. For example, to load the "myapps" system and run the function "myapp1:start" you would invoke clbuild as follows:

clbuild run any :myapps "\\(myapp1:start 1 2 3\\)"

Note the character escape syntax for parentheses; this is needed for most command interpreters.

An alternative approach is to redirect standard input from a file. For example:

clbuild run any :myapps < commands.lisp

clbuild functionality and portability

clbuild is most commonly used to install and run open source CommonLisp libraries.

It is a bash script, so it is highly portable. The download facility relies on programs like CVS, Subversion, darcs, git, and Mercurial.

By default clbuild runs sbcl but it is very easy to configure it to run another Lisp such as (shameless plug) Clozure CL (ccl). Copy clbuild.conf.default to clbuild.conf and edit clbuild.conf to point to the Lisp executable you want to use.

like image 166
kmcorbett Avatar answered Nov 04 '22 20:11

kmcorbett


Your example works for me, at least modified to work with current Hunchentoot 1.0.0, but that is merely change of (hunchentoot:start-server :port 8705) to (hunchentoot:start (make-instance 'hunchentoot:acceptor :port 8705)).

In any case, while possible, you are not really supposed to run things from inside files loaded by ASDF. It serves a role analogous to a build system, and I don't think having make launch a webserver is exactly common...

For deployment see cl-launch, sbcl command-line options, in particular --eval, or saving an image.

like image 31
Ramarren Avatar answered Nov 04 '22 20:11

Ramarren