A couple of approaches: 1. Stop using compojure's 'defroutes'. Generate routes via 'routes' that close over your service. Try not to do anything that would make this expensive. 2. Pass it along on a request map via some middleware.
The relevant principle: lifecycle of your component and usage shouldn't be coupled. You said it well: 'I am trying to separate the 'lifecycle' concerns from the 'getting hold of it' concern as they are orthogonal I think.' Dependency injection is all about handing things what they need instead of having them reach out and get it. On Wed, May 15, 2013 at 8:29 AM, Colin Yates <colin.ya...@gmail.com> wrote: > 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. > > > -- -- 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.