This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-09
Channels
- # babashka (63)
- # beginners (97)
- # biff (11)
- # chlorine-clover (5)
- # cider (46)
- # clara (2)
- # clj-kondo (34)
- # clojure (65)
- # clojure-austin (1)
- # clojure-europe (9)
- # clojure-france (10)
- # clojure-italy (11)
- # clojure-nl (3)
- # clojure-spec (29)
- # clojure-uk (5)
- # clojuredesign-podcast (1)
- # clojurescript (56)
- # clr (6)
- # component (17)
- # conjure (5)
- # core-typed (5)
- # cursive (23)
- # data-science (5)
- # datahike (3)
- # dirac (3)
- # emacs (20)
- # fulcro (17)
- # graalvm (10)
- # graphql (8)
- # helix (99)
- # honeysql (7)
- # jobs-discuss (9)
- # juxt (9)
- # leiningen (14)
- # malli (3)
- # meander (6)
- # off-topic (77)
- # pathom (7)
- # re-frame (12)
- # reagent (8)
- # reitit (10)
- # restql (1)
- # shadow-cljs (22)
- # spacemacs (10)
Hi everyone, I wanted to find out what's the most idiomatic way to use component library. I have defined one component in a namespace
(defrecord IM-Proto-0
[status config state-component]
im.access/Access
component/Lifecycle
(start [component]
(-> component
(assoc :status :active)))
(stop [component]
(-> component
(assoc :status :deactive))))
(defmethod im.access/create
Type-ID
[config]
(-> {:config config}
(map->IM-Proto-0)))
And then in another where I am constructing the system I use the component this way - the im.access
for example is the namespace of the component record :
(defn create-system'
[{:keys [im-config
om-config
state-config]
:as master-config}]
(component/system-map
:im (-> (im.access/create im-config)
(component/using {:state-component :state}))
:om (-> (om.access/create om-config)
(component/using {:state-component :state}))
:state (-> (state.access/create state-config))))
I don't know if I am being too picky about this but the problem is this way it is not clear form where I want to construct the system that which components use which dependencies - let alone the fact that we actually might import this whole artifact somewhere else and allow for systems to be composed this way.
Is there a more idiomatic way to write components ? or am I being too picky about this ?
Thanks in advance@ho0man I'm not really sure what you're asking here...?
The thing is that the dependency on state-component
is specified in the defrecord for IM-Proto-0
and then everywhere else - specially where this code is included as a library- I’m creating a system that has a IM-Proto-0
component I should supply the dependency using component/using
.
How could I make it easier for clients of this library to use and maintain their code using my components?
But every use could be injecting a different thing for the state-component
Yeah you’re right but the thing is how should they know that there is a state-component
dependency at all?
I think I didn’t explain the problem well.
We wanted the im.access/create
multimethod to hide implementation details of a component whose different versions may have different component dependencies. For instance one implementation uses only a Hazelcast client component and another uses Redis in conjuction with a Postgres. Which is determined dynamically by their configurations.
The dependencies have to be computed before you start
the overall system.
In some of our projects we used to construct a system map at each component level and put the component/using
there and merge these subsystem at top level (we followed an article on best practices of using component library) but that also made the code not exportable as a library since we were limiting the users of the components in their injection (they had to name the dependency exactly what we had set for the component)
If the dependencies are derived from the configuration, then you need to load the configuration first, then use it to build the using
dependency map.
Do you have the exact same API over Hazelcast that you have over the Redis/PostgreSQL combo?
Hmm no they’re different There are two separate very different implementations for those
Either way, you're going to need to process the configuration first, use that to drive the construction of the components and/or the using dependency map, and then start
it.
So it might be that you need a component, based on configuration, that when it start
's up produces your actual system component with all its dependencies, and then you start
that?
Yeah you’re totally right That seems a lot better Thanks a lot @U04V70XH6
I'm also a bit confused about your IM-Proto-0
component since it has status
and state-component
fields but in your create
"constructor" function, you're passing in config
which isn't mentioned in IM-Proto-0
...