Automatic reloading of web app sources in Ring

I’ve been wondering how to test out the librarian-clojure web application I’m developing with Ring and just stumbled upon this thread on the ring-clojure mailing list – What is the best way to run a ring application in REPL? in which James Reeves wrote:

“The ring-serve library should work the same way as “lein ring server”, minus the automatic reloading of modified source files.”

That was it! It made my day. I’d already been using lein ring server command (as described in Interactive Development), but didn’t even think it’d provide such a feature – automatic reloading. But hey, the aforementioned page says:

“When you’ve done that, you can start a new server at the command line with:

lein ring server

The server will automatically reload any modified files in your source directory.”

I’d bet I read it with a great care a few times – it turns out not carefully enough!

I ran lein ring server in a terminal and left Jetty/Ring/librarian-clojure up and running.

jacek:~/oss/librarian-clojure
$ lein ring server
2012-01-29 21:03:30.160:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
Started server on port 3000
2012-01-29 21:03:30.161:INFO::jetty-6.1.25
2012-01-29 21:03:30.184:INFO::Started SocketConnector@0.0.0.0:3000

In another terminal I executed curl to see the output (I knew the tool as an alternative to wget, but it’s just a couple of days ago when I learnt the -X command-line option to test RESTful Web Services and it suddenly became the tool of choice).

jacek:~
$ curl -X GET http://localhost:3000
HELLO, WORLD

Should you want to experience it yourself, simply git clone the librarian-clojure project and follow the steps above. It’s really that easy.

I’d love hearing your thoughts about it. The upper-case function is my first attempt at, shall I say, a middleware in Ring which also helped me get familiar with the threading macro ->. I read and tested it many times, however it’s my first “production” use for something real. See core.clj in the repo.

(ns librarian-clojure.core
  (:use ring.adapter.jetty
        ring.handler.dump))

(defn hello-world [app]
  (fn [req]
    {:status 200
     :headers {"Content-Type" "text/html"}
     :body "Hello, world"}))

(defn upper-case [app]
  (fn [req]
    (let [resp (app req)
          body (:body resp)
          upper-case-body (.toUpperCase body)]
      (conj resp {:body upper-case-body}))))
 
(def app
  (-> handle-dump
    hello-world
    upper-case))

(defn -main [port]
  (run-jetty app {:port (Integer. port)}))

Ah, did I mention about Counterclockwise (CCW) I use for Clojure development in Eclipse? I even imported clj-http, clout, compojure, hiccup and ring projects to dive into web development in Clojure. I’m yet to import ClojureScript One, but I guess it’ll take some time before it happens.

I’m also curious how Eclipse EGit will work out as that’s the tool for git.

And the last but not least, you can see the app working on Heroku – http://librarian-clojure.herokuapp.com. Just uploaded v6 (this time on the command line). Have fun!

jacek:~/oss/librarian-clojure
$ git push heroku master
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 313 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)

-----> Heroku receiving push
-----> Clojure app detected
-----> Using cached Leiningen 1.6.2
       Downloading: rlwrap-0.3.7
       Writing: lein script
-----> Installing dependencies and compiling with Leiningen
       Running: LEIN_NO_DEV=y lein deps
...
-----> Discovering process types
       Procfile declares types -> web
-----> Compiled slug size is 12.5MB
-----> Launching... done, v6
       http://librarian-clojure.herokuapp.com deployed to Heroku

To git@heroku.com:librarian-clojure.git
   1e12914..80c5bfb  master -> master
Be Sociable, Share!
This entry was posted in Languages.

Leave a Reply

%d bloggers like this: