I've also been investigating the nested system approach/problem.

The primary use case that I have is composing subsystems which are mostly 
independent modules using a higher order system to run in one process. The 
modules themselves can be easily extracted into separate applications thus 
becoming their own top level systems which makes it desirable to keep their 
system maps intact. 

Components inside modules might depend on the *whole* modules, not their 
constituent parts. This allows to have modules call each other through the 
API's in-process as well as being easily replaced by remote endpoints when 
separated into multiple processes.

This mostly works except for the components depending on other 
modules/systems, e.g.:

(require '[com.stuartsierra.component :as cmp])

(defrecord X [x started] 
   cmp/Lifecycle 
   (start [this] (if started (println "Already started " x) (println 
"Starting " x " " this)) (assoc this :started true)) 
   (stop [this] (println "Stopping " x " " this) this))

(def sys1 (cmp/system-map :x (cmp/using (X. "depends on dep" nil) [:dep])))
(def sys2 (cmp/system-map :y (cmp/using (X. "depends on sys1" nil) 
[:sys1])))
(def hsys (cmp/system-map :sys1 (cmp/using sys1 [:dep]), :sys2 (cmp/using 
sys2 [:sys1]) :dep (X. "dependency" nil)))

(cmp/start hsys)

Starting  dependency   #user.X{:x dependency, :started nil}
Already started  dependency
Starting  depends on dep   #user.X{:x depends on dep, :started nil, :dep 
#user.X{:x dependency, :started true}}

clojure.lang.ExceptionInfo: Error in component :sys2 in system 
com.stuartsierra.component.SystemMap calling 
#'com.stuartsierra.component/start
clojure.lang.ExceptionInfo: Missing dependency :dep of clojure.lang.Keyword 
expected in system at :dep

This happens because of the following:
1. Dependency :*dep* of *sys1* is started in *hsys*
2. *sys1* is started (:*dep* is started again, so the start/stop should be 
idempotent)
3. Dependency :*sys1* of *sys2* is started in *hsys*
4. :*sys1* cannot be started as it depends on :*dep* which isn't present in 
*sys2*

This scenario could be supported by the Component library in several ways:

1. introduce an IdempotentLifecycle protocol which will be respected by the 
Component library. Implement the protocol for the SystemMap. 
IdempotentLifecycles will not be started or stopped for the second time, 
also their dependencies will not be updated if they are already started.
2. do not fail if a component already has a dependency under the specified 
key. This is a hack compared to the first solution, but I might go with it 
in the short term.

Stuart, what do you think about that? Would you consider a PR implementing 
the first proposal?

On Wednesday, March 18, 2015 at 10:18:36 AM UTC+1, Stuart Sierra wrote:
>
>
> On Tue, Mar 17, 2015 at 5:47 PM, James Gatannah <james.g...@gmail.com 
> <javascript:>> wrote:
>
>> FWIW, we've been using something that smells an awful lot like nested
>> systems for months now. I never realized we weren't supposed to.
>>
>
>
> It's not that nested systems *never* work, but from what I've seen they 
> cause more complications than they're worth. The 'component' model doesn't 
> forbid it, but it does not support dependencies between components in 
> different "subsystems."
>
> I've found it easier to keep system maps "flat" and use namespaced 
> keywords to distinguish "subsystem" groups, even in large systems with 30+ 
> components.
>
> –S
>
>

-- 
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