views:

637

answers:

5

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.)

A: 

I know even less than you, but this link seems relevant: http://common-lisp.net/pipermail/tbnl-devel/2008-November/004455.html. Apparently just running it in SLIME (sort of) isn't such a terrible idea after all. Found by googling for "deploying hunchentoot".

Logan Capaldo
That seems sketchy in about 3 different ways, and it still doesn't answer why ASDF seems to wedge itself for me (since I still need to use ASDF, right?), but I'll give it a try.
Ken
+2  A: 

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.

Ramarren
+1  A: 

What I do is to have a file that loads the ASDF system definition for my web application, then starts Hunchentoot with everything set up as it should be. This is then run with sbcl --load start-stuff.

Vatine
A: 

You should avoid putting any logic in asd files. You can treat them as simlple makefiles. What you need is a way to save lisp image which will start your server instance on startup. This is platform dependent, to you will need to search your lisp implementation documentation.

Dev er dev
+1  A: 

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.

kmcorbett