A java.util.concurrent.ExecutorService may be what you want. This allows you to submit a job for later execution, and returns a Future that you can query to discover if it has completed.
(import '[java.util.concurrent Callable Executors])
(def job-executor
(Executors/newSingleThreadExecutor))
(def jobs (atom {}))
(defn submit-job [func]
(let [job-id (str (java.util.UUID/randomUUID))
callable (reify Callable (call [_] (func))]
(swap! jobs assoc job-id (.submit job-executor callable))
job-id))
(use 'compojure.core)
(defroutes app
(POST "/jobs" [& params]
(let [id (submit-job #(analyze params))]
{:status 201 :headers {"Location" (str "/jobs/" id)}}))
(GET "/jobs/:id" [id]
(let [job-future (@jobs id)]
(if (.isDone job-future)
(.get job-future)
{:status 404}))))