component

souenzzo 2020-02-19T21:43:30.001600Z

Hello I have a system

(let [system (-> (component/system-map
                   ::rest1 (->Http)
                   ::db1 (->Sql))
                 (component/system-using
                   {::rest1 {:db ::db1}}))]
  (component/start-system system [::rest1]))
When I call it, it start rest1 without db Is it expected? There is some way to "resolve deps" before start?

seancorfield 2020-02-19T21:52:08.002400Z

@souenzzo Why are you calling that helper function (`start-system`)? All the examples/documentation show to call component/start instead.

seancorfield 2020-02-19T21:53:40.003Z

That aside, How is your Http component defined?

seancorfield 2020-02-19T21:54:14.003800Z

It looks a little odd to me to see a mix of qualified and unqualified keys here...

2020-02-19T21:54:43.004300Z

start-system without any component names is a a synonym for calling components/start on a system

2020-02-19T21:54:59.004800Z

but with component names it only starts the components you named

seancorfield 2020-02-19T21:55:07.005200Z

Yeah, just looked at the source -- I'd never seen anyone calling start-system or stop-system directly.

2020-02-19T21:55:50.006Z

so by passing in component names you are overriding the automatic dependency starting logic

seancorfield 2020-02-19T21:58:09.009100Z

Makes sense. Only the whole system knows about the dependency from ::rest1 to :db right? Could you do (component/using (->Http) {:db ::db1}) instead of (->Http) to be able to start ::rest1 on its own with ::db1 started and injected?

2020-02-19T21:58:33.009800Z

no

souenzzo 2020-02-19T21:58:52.010500Z

I thought that component has "lazy" capabilities to handle cases like

(let [system (-> (component/system-map
                   ::rest1 (->Http)
                   ::db1 (->Sql)
                   ::rest2 (->Http))
                 (component/system-using
                   {::rest1 {:db ::db1}
                    ::rest2 {:db ::db1}}))]
  (component/start-system system [::rest1]))
Where when I ask ::rest1 it will start just what it really need But okay. Already Implement it at my side 🙂 May PR?

seancorfield 2020-02-19T21:59:28.011400Z

Use component/start on the whole system and it will work.

souenzzo 2020-02-19T21:59:33.011600Z

(PR with another signature, sure)

2020-02-19T22:00:14.012300Z

the way start-system works is it sorts the set of names (defaulting to all the names) according to dependency order and then starts each thing

2020-02-19T22:00:29.012700Z

and component/start on a system calls start-system

2020-02-19T22:00:57.013300Z

so if you don't give it a name, it will not be in the list regardless of the dependency information, and will not be started

2020-02-19T22:01:49.013700Z

there is a function component/dependencies you can use

2020-02-19T22:02:09.014Z

you need the transitive closure of it

2020-02-19T22:08:45.014400Z

so something like

(component/start-system
 sys
 ((fn f [sys name]
    (cons name
          (for [[_ n] (component/dependencies (get sys name))
                i (f sys n)]
            i)))
  system
  ::rest1))

2020-02-19T22:08:59.014600Z

err

2020-02-19T22:09:41.015Z

it may need a distinct around it too

souenzzo 2020-02-19T22:30:06.015100Z

Maybe I will do a ubercomponent lib

(let [system (-> (component/system-map
                   ::rest1 (my-comp {::id :rest1})
                   ::rest2 (my-comp {::id :rest2})
                   ::gql (my-comp {::id :gql})
                   ::db1 (my-comp {::id :db1})
                   ::db2 (my-comp {::id :db2}))
                 (component/system-using
                   {::rest1 {:db ::db1}
                    ::rest2 {:db ::db2}
                    ::db2   {:db ::db1}
                    ::gql   {:db1 ::db1
                             :db2 ::db2}}))
      inits (for [[from component] system
                  :let [edges (component/dependencies component)]
                  [label to] edges
                  inits [[from {:label (pr-str from)}]
                         [to {:label (pr-str to)}]
                         [from
                          to
                          {:label (pr-str label)}]]]
              inits)]
  (-> (apply uber/digraph inits)
      (doto (uber/viz-graph))
      (uber.alg/topsort ::rest2)))