Hi all,

I have a scheduler which creates a future that basically does a (while true 
(let [next-job (.take queue)]...)), where queue is a LinkedBlockingQueue. 
 The problem is that once it is running, because futures aren't daemon 
threads it hangs lein.  It will ultimately run inside a compojure web app 
where, whist it doesn't stop the web server being shut down, it should do 
it more elegantly by explicitly being told to shut down.

It is necessarily a singleton because it is sized to allow the maximum 
amount of concurrency.  Starting up more than one scheduler would swamp the 
system.

What is the idiomatic way of managing this?

In terms of accessing the singleton I could:
 - use a root level *binding* which smells of global state
 - pass in the instance to the consumers of the scheduler.  Fine, but that 
means threading it through from the bootstrapping code all the way down the 
call stack to the function that needs it.
 - add a (get-scheduler) accessor in the scheduler ns

In terms of controlling the lifecycle I could:
 - add a  "with-scheduler" construct which starts it, delegates to the 
delegate in a try/finally and then closes it in the finally clause.  Given 
that this is infrastructural and will be used in lots of places I would 
need to wrap the whole application inside with-scheduler.
 - add (start-engine) and (stop-engine) functions in the scheduler ns which 
are then called from the relevant parts in the Compojure/testing framework 
lifecycle

I could also not use a future and use a deamon thread instead but this 
feels like I am working against Clojure a little.  It also side steps this 
question which I want to resolve.

I am trying to separate the 'lifecycle' concerns from the 'getting hold of 
it' concern as they are orthogonal I think.  the with-scheduler pattern 
seems to combine both concerns.

I am currently deciding between:
 - expose a (start-engine) which delegates to an internal (defonce).  This 
is called on compojure's start up
 - expose an (get-engine) in the scheduler namespace which delegates to an 
internal (defonce)
 - expose a (shutdown) function/shutdown protocol method in the scheduler 
namespace which is called on Compojure's shut down
 - create a test utility (def with-scheduler [delegate] ...) or use 
pre/post setup hooks which manages the lifecycle of the scheduler

or

 - expose a (with-scheduler) which is integrated into Compojure's lifecycle 
such that it wraps Compojure's lifecycle.  Not sure this is even possible.
 - expose a (get-engine) in the scheduler namespace which delegates to an 
internal (defonce)
 - use the (with-scheduler) for testing

Any and all advice is welcome.

Thanks,

Col

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to