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.


Reply via email to