component

olfal 2017-02-28T03:31:44.000054Z

Hello! I’m new to components and would need a hand to understand some concepts. Given a database component like this one :

olfal 2017-02-28T03:33:39.000056Z

if the start method is returning the component itself associated with the new connection and db, will my component have its new connection and db fields when the system stops all components ?

2017-02-28T03:39:36.000058Z

Yes, it will have connection and db fields with nil as their value. Is that answer your question?

olfal 2017-02-28T03:41:41.000059Z

Almost! 🙂 The thing is, when I start my component, I add the connection and db fields (line 12) but when I try to stop the component, I get a null pointer on line 16 when trying to disconnect the database because the :connection field is apparently nil

olfal 2017-02-28T03:43:01.000060Z

When starting the component, I can see that the component returned by the start method has a not nil connection and db field, but both of them are nil when using the stop method, so I was wondering how the whole system is updating the component with the value returned by start

2017-02-28T03:45:06.000061Z

I’m not fully understand how it work. I kind of had the same issue the other day. For me, adding connnection as a second argument on line 9 fixed the issue. You might want to give that a try.

olfal 2017-02-28T03:45:42.000063Z

alright, I will it a try!

2017-02-28T03:46:17.000064Z

No. Sorry line 6

olfal 2017-02-28T03:47:08.000065Z

👍

seancorfield 2017-02-28T03:49:17.000066Z

@olfal Show us how you are creating and starting / stopping the component.

seancorfield 2017-02-28T03:49:59.000067Z

It sounds like you are passing the original (unstarted) component into the stop function?

seancorfield 2017-02-28T03:51:10.000068Z

(let [db (new-database-component my-url)]
      started-db (component/start db)]
  ;; do stuff with started-db
  (component/stop started-db)) ; make sure you pass the _result_ of the start call here!

olfal 2017-02-28T03:52:27.000069Z

@seancorfield exactly. It seems that the “auto-magical” system component is not updating the database component with the output of the start method

seancorfield 2017-02-28T03:52:47.000070Z

Clojure has immutable data structures. They don’t “update”.

olfal 2017-02-28T03:53:10.000071Z

absolutely

olfal 2017-02-28T03:54:27.000072Z

By looking at the doc of the component library, it seemed to me that the underlying component system is reusing the output of the start functions to update (maybe like an atom?) the component so the new fields are available when stopping

seancorfield 2017-02-28T03:54:35.000073Z

No.

seancorfield 2017-02-28T03:55:53.000074Z

If you put your component in a global Var and use alter-var-root then you are mutating it (but that’s meant to be a REPL convenience only and now how to use Component in a program).

olfal 2017-02-28T03:56:29.000075Z

oh right!

seancorfield 2017-02-28T03:57:39.000076Z

In a REPL session, I’ll do something like

user=> (def system (make-my-system {:some “config”}))
user=> (alter-var-root #‘system component/start)
;; do a bunch of stuff
user=> (alter-var-root #‘system component/stop)

seancorfield 2017-02-28T03:58:20.000078Z

and that’s using #‘user/system as a mutable global Var

olfal 2017-02-28T03:59:17.000079Z

that makes absolute sense! I was inferring too much magic 🙂

seancorfield 2017-02-28T03:59:33.000080Z

Clojure is already magic 🙂

olfal 2017-02-28T03:59:44.000081Z

thanks for your help

seancorfield 2017-02-28T04:03:47.000082Z

Any time!

2017-02-28T17:14:33.000083Z

it seems like people infer that there are things in component, or that component does things it just doesn't do, so I wrote a minimal re-implementation of component to show just how little there is https://gist.github.com/hiredman/075b45eaeb01e4b526ce6f8854685487