A possible implementation for the idea expressed in the previous post - 
https://github.com/stuartsierra/component/pull/25


On Wednesday, March 18, 2015 at 2:41:46 PM UTC+1, platon...@gmail.com wrote:
>
> 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> 
>> 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