component

2020-06-09T14:58:24.019900Z

@ho0man has joined the channel

2020-06-09T15:04:00.025Z

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

seancorfield 2020-06-09T17:00:35.026200Z

@ho0man I'm not really sure what you're asking here...?

2020-06-10T03:49:59.036500Z

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 .

2020-06-10T03:51:52.038600Z

How could I make it easier for clients of this library to use and maintain their code using my components?

seancorfield 2020-06-10T03:52:53.038900Z

But every use could be injecting a different thing for the state-component

2020-06-10T04:05:31.046900Z

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.

seancorfield 2020-06-10T04:09:04.052600Z

The dependencies have to be computed before you start the overall system.

2020-06-10T04:09:28.052900Z

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)

seancorfield 2020-06-10T04:09:57.053100Z

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.

seancorfield 2020-06-10T04:11:01.054200Z

Or you need to abstract over the things that can vary.

👍 1
seancorfield 2020-06-10T04:11:50.054700Z

Do you have the exact same API over Hazelcast that you have over the Redis/PostgreSQL combo?

2020-06-10T04:12:32.055900Z

Hmm no they’re different There are two separate very different implementations for those

seancorfield 2020-06-10T04:12:48.056200Z

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.

seancorfield 2020-06-10T04:14:03.056400Z

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?

👏 1
2020-06-10T04:18:27.059700Z

Yeah you’re totally right That seems a lot better Thanks a lot @seancorfield

seancorfield 2020-06-09T17:02:57.027400Z

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

2020-06-10T03:40:40.028700Z

Yeah you’re right sorry It git removed when I was trying to remove unnecessary code