I would do the latter.

I like the extend types to component/Lifecycle wherever possible. The goal 
is to have all components in your system only interact via protocols. This 
way, you have established interfaces between components, and if you want to 
swap an implementation, you just satisfy the protocol. So adapting your 
example

(defprotocol IRegistry
  (register-with [registry cb spec]))

I also like to provide all reference as arguments instead of assoc'ing them 
inside component/start. This allows them to be more easily used in other 
parts of the system, and gives you the opportunity to validate the 
references, continuing the idea of protocol interface

(defn validate-system
  "validate the portion of the system contained within the component"
  [schema cmp]
  (s/validate {s/Keyword s/Any} schema)
  (->> (select-keys cmp (keys schema))
       (s/validate schema)))

(defrecord Registry [state]
  Lifecycle
  (start [this]
    (validate-system {:state clojure.lang.Atom} this) ;; this could be more 
general, let's be specific though
    ;; start the registry
    this)
  (stop [this]
    ;; stop the registry
    this)
  IRegistry
  (register-with [registry cb spec]
    (swap! state :assoc cb spec)))

(defrecrod UsesRegistry [registry]
  Lifecycle
  (start [this]
         (validate-system {:registry (s/pred (partial satisfies? 
IRegistry))} this)

         this)
  (stop [this]
        this))
  

On Sunday, March 1, 2015 at 7:50:58 AM UTC-5, Colin Yates wrote:
>
> If I have a stateful thing with a lifecycle then is the system component 
> the instance of the thing or a wrapper that contains the thing.
>
> For example, let's say I have a registry of clients that want to be polled 
> then I might have the following:
>
> (defrecord Registry [state])
> (defn register-with [registry cb spec] (swap! (:state registry) :assoc cb 
> spec))
> (defn start [registry] ...)
> (defn stop [registry] ...)
> (den some-other-thing [..] ....)
>
> Great.
>
> Now I want to expose that and use Stuart's excellent component library 
> (which I really wish a global 'everything has been defined, now the actual 
> system is starting' lifecycle event, but anyway). I seem to find most 
> examples do:
>
> (defrecord RegistryComponent [] 
>   component/Lifecycle
>   (start [this]
>     (let [registry (->Registry (atom {}))]
>       (start registry)
>       (assoc this :registry registry))
>   (stop [this]
>      (stop (:registry this))
>      (assoc this :registry nil)))
>
> Other components get the RegistryComponent but then have to unravel the 
> actual :registry. 
>
> Another approach would be to adjust the actual Registry and that that 
> implement the lifecycle:
>
> (defn register-with [registry cb spec] (swap! (:state registry) :assoc cb 
> spec))
> (defn start [registry] ...)
> (defn stop [registry] ...)
> (den some-other-thing [..] ....)
> (defrecord Registry [state]
>   component/Lifecycle
>   (start [this] (start this) this)
>   (stop [this] (stop this) this))
>
> On the one hand, the Lifecycle component can be viewed as separate from 
> the thing it is managing, and this wrapping and unwrapping is only a 
> concern of Components. Nothing outside of a Lifecycle instance worries 
> about it and nothing ever receives a Lifecycle instance.
>
> On the other hand, it all felt a little bit OO-ish - and actually I don't 
> quite see the 'vanilla' Registry implementing the Lifecycle component as 
> complecting anything inappropriate. The Lifecycle instance is only 
> describing behaviour - there is no separate 'thing'.
>
> Is that correct or have I missed something? What do you all do?
>
>

-- 
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/d/optout.

Reply via email to