
Deploying Clojure websites - bgray
http://briancarper.net/blog/deploying-clojure-websites
======
sunkencity
Why use apache in front of jetty when jetty is a decent server for serving
binary data (unlike older versions of tomcat).

Why not just enable jettys built-in automatic file-update-deploy stuff, and
just use git to push the data and deploy that way?

I've used .war files and tomcat which is dead simple to deploy with the
downside that there's no way to start swank-server (unless maybe disabling the
security manager). Another downside is that .war files tend to be rather big.

Why use screen + emacs? Just recompiling things in emacs might probably
introduce weird bugs as code is not removed from the system when it is removed
from a source file. Seems a bit tough to manually go through all the source
files in the right order and recompile them. It'd be easier IMHO to just start
a swank server with every jetty started.

~~~
prospero
Under the described setup, you don't have to recompile anything. Using the
REPL, you can redefine functions one at a time, without ever taking down the
server. For a simple site, I think this trumps ease of deployment.

~~~
sunkencity
my point is that you can't remove stuff by compiling stuff from emacs to the
repl, just add.

the repl is very nice for development, but not as a consistent deployment
tool, imho.

~~~
weavejester
Clojure does allow you to remove symbol mappings from a namespace. The only
problem with deploying via the REPL is that there isn't a function for
atomically deploying a namespace, or set of namespaces. I suspect one would
have to use a global lock to pause all request-handling threads for the second
or so Clojure needs to teardown and reload all its libraries.

~~~
sunkencity
Looking into this, you mean using (use 'mynamespace :reload) instead of C-c
C-k - that is a good idea!

It should be trivial to write a ring middleware to reload everything between
every request (for a railsy development environment) maybe a version for
production use that checks all files for changes every 1 minute or so.

~~~
weavejester
I think it's a touch trickier than that. As far as I'm aware, a reload cannot
remove namespace mappings; it can just add new ones and overwrite existing
ones. So with continual reloads you might find yourself with old deprecated
functions cluttering up your namespace.

Another problem is that Clojure loads up namespaces sequentially, rather than
atomically. So you might end up with an a new version of one function calling
the old version of another.

In order for your reloading middleware to be robust, I suspect you'd have to
(1) wait for any existing request-handling threads to finish, (2) suspend any
new request-handling threads, (3) reload your namespaces, (4) resume any
suspended request threads.

