Fork me on GitHub
#polylith
<
2022-03-21
>
pavlosmelissinos07:03:05

I'm watching "around the campfire with polylith architecture". I like how well thought it is 🙂. It does capture a lot of the pains of software development and the essence of polylith.

👍 1
pavlosmelissinos07:03:20

One thing that I don't believe is really explained in the video is (at the end of the decouple vs glue slides, right before going into what polylith is about) how coupling is a problem within the same src directory but not if you use separate src directories per service. I mean you can put them under the same deps.edn. If the components' APIs/interfaces are clean, how would that make reusing a service harder?

james08:03:34

That part of the video explains how when we use namespaces, we “glue” together our code. Because each namespace becomes a tangle of incoming and outgoing dependencies to other namespaces. Which makes namespaces hard to extract, or reuse. Polylith solves this problem by abstracting namespaces into a larger, and more modular, unit of code; components. Each component’s (not service, which is perhaps where you’re getting confused) code lives in a separate src folder. This is part of what gives them their modularity (the other being their interfaces). Assembling a Polylith service is as simple as pointing its project’s deps.edn to a collection of components (and adding a base).

🙏 1
pavlosmelissinos13:03:28

I used the term "service" because that's what was used in the video: "used by other services" (bricks aren't introduced yet at that point) but yeah, I'm actually talking about components! My question is why does putting the component code in a separate src directory offer better decoupling than putting it in a separate directory within the same project (and following the same rules)?

pavlosmelissinos13:03:44

I understand that having namespaces without any structure is an issue because you end up with an intricate web of dependencies/code use that's really hard to refactor but how is there still a problem if you introduce a convention, e.g. of having separate namespaces for interface and implementation, like polylith does but under the same src directory?

pavlosmelissinos13:03:01

I can think of a couple of reasons: 1. it's easier to enforce conventions if the namespaces are under different deps.edn files 2. Your dependencies are more focused (you don't have a huge deps.edn file for everything, you only define what you need in each brick) but shouldn't these be part of the problem statement and mentioned before polylith is even introduced?

tengstrand14:03:06

In a Polylith workspace you can have two or more components living in the same namespace. That’s not possible if they live under the same src directory. But the most important problem it solves is to allow different components to be shared across projects, by letting each component live in its own directory, which wouldn’t be possible if the code lived inside a single src directory.

🙏 1
pavlosmelissinos15:03:55

> you can have two or more components living in the same namespace. That’s not possible if they live under the same src directory. Oh, that's right... I actually knew that but forgot it was possible facepalm, thanks. > allow different components to be shared across projects, by letting each component live in its own directory, which wouldn’t be possible if the code lived inside a single src directory I don't think I understand this completely. Assuming the components are in different namespaces, there wouldn't be any clashes, so they could be in different namespaces and still be reused by different projects. Sure, each project would have to bring in all of the bricks as a dependency, not just a single component and that is definitely not ideal but I think this is different from the decoupling problem that is described in the video. Without a doubt, polylith helps you make smaller artifacts and improve your security (because you bring in fewer dependencies to each artifact), compared to a monolith. I believe there's some room to make this clearer in future presentations. 🙂 I understand that it's hard to do so in 10-15 minutes of introduction but I think a lot of the reluctance people show comes from them not understanding exactly what problems polylith solves. Analogies can be great to get through to a crowd but have you considered replacing some of them with real-life examples to showcase some of the problems?

pavlosmelissinos15:03:05

(Sorry for reviving a 9-day-old thread but this is a follow-up to that conversation) > In a Polylith workspace you can have two or more components living in the same namespace However, if component-a and component-b both define the namespace org.company.some-ns, that means that they can't be loaded at the same time in the same REPL, isn't that right? So how would you include two components with the same namespace in the development project? :thinking_face:

tengstrand16:03:08

The component share the same namespace, but you can only include one of them in each project. The two components live in different src directories, but if you look into the source, you will find that they “live” in the same namespace.

seancorfield16:03:32

Profiles let you start a REPL with your choice of implementations for such components. At work, we have two HTTP client implementations so our default profile selects the one we use in most projects. If I need to dev/debug on the other projects, I start a separate REPL with a different profile.

👍 1
seancorfield16:03:24

(the same namespace in different parts of the classpath is a general Clojure issue because it is essentially a Java issue -- namespaces compile to Java classes and you can only have one class instance for any given name loaded and accessible -- so this is not really a Polylith issue)

👍 1
pavlosmelissinos16:03:06

> you can only include one of them in each project. That's what I thought, thanks. However, I was under the impression that the development project is meant to contain all bricks but that was probably a misunderstanding on my part. 🙂 Furthermore, that means that the following refactoring isn't possible:

;;Original
old-component-a (with org.company.some-ns) - component-c 
                                                  \
                                                    base-a
                                                  /
old-component-a (with org.company.some-ns) - component-d

;; Interim step
new-component-a  (with org.company.some-ns) - component-c 
                                                  \
                                                    base-a
                                                  /
old-component-a (with org.company.some-ns) - component-d

;; Final step
new-component-a (with org.company.some-ns) - component-c 
                                                  \
                                                    base-a
                                                  /
new-component-a (with org.company.some-ns) - component-d 
So because of that, the option of gradually replacing the implementation of a component, brick by brick across your monorepo, goes out of the window. I understand that this is not a polylith issue but it's still a bummer 😞

Hukka06:03:24

I'm not sure I understand the problem… If the interface stays the same with just different implementation, wouldn't it be possible to switch implementations repo wide in a single step? And alternatively, if the interface does change, then it would feel logical to put it in a new namespace, and then switch dependent components to use the new version one at a time.

Hukka06:03:19

In the first case, Polylith would allow keeping the old version around for easy regression checks whenever a bug is found, or perhaps because the test suite is still evolving and it makes sense to check that everything works the same with both versions

pavlosmelissinos07:03:22

> switch implementations repo wide in a single step Some changes require manual QA before they're deployed everywhere. This need might be more prevalent in data science applications where you don't get immediate feedback (test coverage is hard to get right). Being able to say "ok, I want to deploy this new algorithm in some parts of the codebase before I switch to the new version everywhere" would be great. You can always use different namespaces in the new component but then you can't just swap implementations in the code that uses it as easily.

tengstrand07:03:47

We often say that we put all components in the development project, which is almost true, but if you have more than one component implementing the same interface, you have to choose which one to use (by using profiles, where the component(s) in the default profile are the active ones by default).

👍 1
pavlosmelissinos07:03:32

Yes, I get that now, thanks 🙂

👍 1
Hukka08:03:02

> Some changes require manual QA before they're deployed everywhere. Sounds like the only way forward would be either hardcoding the choice in the source code as different ns require, deploying multiple artefacts, each built with different choices, or making a new layer that will switch implementations based on configuration flag

pavlosmelissinos08:03:21

Exactly and none of these options is as elegant as just renaming a dependency 🙂 It's not a huge issue but it would have been amazing if possible.

imre14:03:18

Hey folks, is there any guide available on developing the poly tool itself? I'm trying to see if I can create a proper connection between it and kaocha.

👀 1
tengstrand15:03:47

I think the best way forward is to add support some sort of pluggable integration with the test command. We discuss it a bit in https://github.com/polyfy/polylith/issues/126 issue, but it could also maybe be supported by the https://github.com/polyfy/polylith/issues/113 issue, that I’m currently working on. To answer your question, no, we don’t have any guide available around developing the poly tool. Where you thinking of creating a PR?

imre15:03:38

Thank you, I'm aware of #126 and that's the direction I'm trying to poke at. Let me first see if I can make this work in an ugly way. If I succeed I'll try to make it acceptable from an architecture pow, at which point I'd be happy to submit a PR to see if we can get to a state where you'd consider merging it.

tengstrand15:03:26

Okay, cool. Just contact me if you have any questions.

imre15:03:38

Will do, thanks!

👍 1
imre12:03:20

https://github.com/polyfy/polylith/pull/194 largely unrelated but found while hacking

imre12:03:41

More precisely, it was kaocha that found them, I managed to hack together a crude integration

tengstrand12:03:53

Interesting, I found them too, but in a branch that I’m working in now!

imre14:03:30

pushed a few more commits there with another test case that had problems

imre14:03:14

I will definitely have questions with regards to the kaocha integration, how would you prefer I contact you about them?

pavlosmelissinos15:03:05

(Sorry for reviving a 9-day-old thread but this is a follow-up to that conversation) > In a Polylith workspace you can have two or more components living in the same namespace However, if component-a and component-b both define the namespace org.company.some-ns, that means that they can't be loaded at the same time in the same REPL, isn't that right? So how would you include two components with the same namespace in the development project? :thinking_face: