stuartsierra / component

Managed lifecycle of stateful objects in Clojure

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Init within start, entry point & env/context

GetContented opened this issue · comments

Hi,

entry point
My system uses an entry point component. I use that to determine and refer to the component the system-starter (ie me mostly) has started the system up from. So, perhaps today it's the webserver (lein ring server), perhaps tomorrow it's the repl/console (lein repl). The entry point matters because when I start the system from webserver, I don't want to start the webserver component. However... I still may need the webserver component there, because there is a webserver component.

init vs start
So, I was wondering... would you consider splitting the system slightly so that there are init and start functions on the protocol? Start should include a call to the (hopefully idempotent) init function. I ask, because in the start-from-webserver context above, I'd like the WS loaded, and in the dependency hierarchy, becuse it may be needed by the other parts of the system (for its state; to find the port, for example), but not like to call start on it, because it's already started... (perhaps we need to be able to tell components which one was the entry point if necessary).

Another context this separation is useful in, is testing different points than the entry points... so I might only want to start up the lower part of my system (just the DB, for example) so I can run a few things on it.

We may also need an init-inverse "destroy" method which is currently kind of conceptually part of the stop method at this point.

env

The other thing, which is fine as it is but could potentially be better, is context. If I'm in a dev context, I want certain components running, but if I'm in a test context, I want other components running. The dependency hierarchy stays the same between these, though. This concern might be overkill for your "just enough structure" constraint. I'm not sure.

What I'd like to be able to do, though, is to have several named envs that I can start up. The obvious two for web dev would be "production" and "dev". The test context would most likely be a bit different because there you want to be able to call a constructor with the set of systems you want to start (see above... where I only really want to start up a chunk of the system, or I might want to mock out certain parts of the hexagonal structure).

thanks!

I've been using component for a week or so, and I gotta say I LOVE it. It's such a nice way to build apps. Proper separation of concerns, and for one of the first times in my 20+ year dev career, I feel like I'm in full control of where I put things, and it's really nice. So, a hearty thankyou is in order. <3

Thanks for the experience report. I have considered most of these things at various times. A second lifecycle protocol (init & destroy) may become a thing at some point; until then it's easy enough to add your own and extend it to SystemMap. I believe the other suggestions here can be addressed by writing your own system constructors that assoc in different components for different environments or entry points. I find that this kind of configuration tends to be highly-specific to both the application and the deployment setting, so I don't want to mandate any particular style in the library.

Cool. :) Thanks stuart! Might be worth adding a FAQ for these things? :)

I have to say I've had a terrible time of getting a nice workflow going where I don't have a constantly breaking system I just have to reload all the time. (Kind of defeats the purpose!) I'm not sure, but if you had the time and interest, I'd love to hear more about how your workflow works and some really in depth details with a real world web-app example would be awesome. I understand that it's a lot of work.