Fork me on GitHub
#polylith
<
2022-05-31
>
tengstrand12:05:38

Hi everyone! I few big issues have gone into master recently (https://github.com/polyfy/polylith/issues/206 https://github.com/polyfy/polylith/issues/217 https://github.com/polyfy/polylith/issues/227) where 206 and 217 are about the same issue, that we now read code from the source directories specified in each deps.edn file instead of having them hard coded to src , test and resources (resources will still be used as before). Please check it out adf957cc055ba1ceaca25e6119915b4d3ad77b48!

👍 2
1
imre16:05:15

pulled this in and saw no issues so far

👍 1
imre16:05:35

Thank you for the fix. One question: did alias support make it in? https://github.com/polyfy/polylith/issues/206#issuecomment-1128016277

tengstrand19:05:01

No, I forgot to implement it in issue 206, so I created issue https://github.com/polyfy/polylith/issues/230 instead!

1
greg14:05:42

Have you tried using Integrant within Polylith project? Are there any existing examples?

tengstrand14:05:00

@U2BDZ9JG3 uses Mount and @U04V70XH6 uses Components. If you search this Slack workspace, then you will find that @U0295UQ75FG uses Integrant. I have no experience myself with Integrant unfortunately.

imre14:05:34

subscribing here in case someone else chimes in

seancorfield16:05:16

I wouldn't expect Integrant to be that different from Component in terms of how you use Polylith. We tend to have a component for each of the Components, and the impl has the definition of the lifecycle, depending on other components as needed. Then we generally assemble the "system" in a base and that depends on all the components (Components) that make up the system, so all the lifecycles are loaded (defined). With Component, you need a "constructor" function, which we put in the interface of the component to create the hash map (or record or, in some cases, return a metadata-bearing function). We tend to call that system.

seancorfield16:05:54

Of the three main "system" libraries, I prefer Component because it is simpler -- just start and stop -- and the lifecycle definition is localized so it's easy to see the whole thing in one block of code. I find Integrant too "fragmented" and I also feel it is unnecessarily complex so people try to do "too much" with it. I don't like Mount because it basically uses global state in namespaces which makes it hard to do certain things (e.g., at work we have tests where we build up to three distinct "systems" in one test so we can verify their interaction -- a mini-distributed system -- and it's also very easy to mock out parts of the "system" with Component). Even Integrant relies on global side-effects (because that's what multimethods are).

greg17:05:30

Well, I usually use integrant for state & lifecycle management. I thought about exposing such start/create & stop/destroy methods from relevant components, while wrapping up base config and all of the integrant boilerplate (small but still) in another component named system, and as you said using it from bases. That way, in theory, the integrant should not spread into all of the components and could be replaced or even ignored by some of the bases. What do you think about such an approach? @U04V70XH6

Hukka17:05:11

We migrated from integrant to nothing, and didn't need to touch components. For example our DB instance has a .close method that integrant was calling, and now it's called just without. I think that is often a good way since it works well with with-open too

Hukka17:05:37

So for example we can wrap our tests in with-opens with everything that the test needs

seancorfield17:05:39

I would not recommend exposing lifecycle methods in the interface of a component -- that sounds very brittle to me. The only places that know about Component in our code are the components impl when the Component is declared (with its lifecycle) and the base that assembles the complete system and starts it. And even there we have a "common" application-level system reused across multiple projects that encapsulates most of that building so the base's -main pretty much just calls a function that does (component/start (app/system opts)) -- so it would be fairly easy for us to switch to a different library or a homegrown solution if we wanted.

greg15:05:43

Am I correct that if use a library in one of components, I should: • add an entry in :extra-deps of component's deps.edn, and • I should duplicate the same entry in top level deps.edn under dev alias Correct?

furkan3ayraktar15:05:58

Component’s deps.edn should include the library in the root :deps map, not in the extra-deps, unless it’s a test dependency. You only need to duplicate the library in the development project’s deps.edn (top level) if you are using Cursive IDE. Otherwise, you can refer to the components and bases with :local/root so that you do not need duplication.

imre16:05:27

we're working to have a proposal that's acceptable by Colin there 😛

🙌 3
seancorfield16:05:27

Nice updates on that issue. This is definitely not a Polylith-specific issue -- this is a problem with IntelliJ's model of "source" vs "library" and, unfortunately, tools.deps.alpha and deps.edn concepts just don't quite map cleanly onto IntelliJ's world. Great to see a non-Polylith example in that issue to demonstrate that!

1
polylith 1