yazz.com
yazz.com

Reputation: 58786

How can I create a constantly running background process in Clojure?

How can I create a constantly running background process in Clojure? Is using "future" with a loop that never ends the right way?

Upvotes: 16

Views: 5076

Answers (3)

Alex Miller
Alex Miller

Reputation: 70201

You could just start a Thread with a function that runs forever.

(defn forever []
  ;; do stuff in a loop forever
)

(.start (Thread. forever))

If you don't want the background thread to block process exit, make sure to make it a daemon thread:

(doto 
   (Thread. forever)
   (.setDaemon true)
   (.start))

If you want some more finesse you can use the java.util.concurrent.Executors factory to create an ExecutorService. This makes it easy to create pools of threads, use custom thread factories, custom incoming queues, etc.

The claypoole lib wraps some of the work execution stuff up into a more clojure-friendly api if that's what you're angling towards.

Upvotes: 17

mikera
mikera

Reputation: 106351

My simple higher-order infinite loop function (using futures):

(def counter (atom 1))

(defn infinite-loop [function]   
  (function)
  (future (infinite-loop function))
  nil) 

;; note the nil above is necessary to avoid overflowing the stack with futures...

(infinite-loop 
  #(do 
     (Thread/sleep 1000) 
     (swap! counter inc)))

;; wait half a minute....

@counter
=> 31

I strongly recommend using an atom or one of Clojures other reference types to store results (as per the counter in the example above).

With a bit of tweaking you could also use this approach to start/stop/pause the process in a thread-safe manner (e.g. test a flag to see if (function) should be executed in each iteration of the loop).

Upvotes: 7

Shantanu Kumar
Shantanu Kumar

Reputation: 1240

Maybe, or perhaps Lein-daemon? https://github.com/arohner/lein-daemon

Upvotes: 1

Related Questions