-
Notifications
You must be signed in to change notification settings - Fork 21
feat: Add Monix and ZIO bundles, Micrometer and PureConfig interop #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the plan is to have a single micrometer module that will implement metrics for various other modules?
It doesn't necessarily must be like that but yes. This can be seen in the |
Maybe it would be better to start with README, so we could see your intents earlier? |
pureconfig/src/main/scala/com/avast/sst/pureconfig/implicits/Http4sBlazeClient.scala
Outdated
Show resolved
Hide resolved
...er/src/main/scala/com/avast/sst/micrometer/interop/MicrometerHttp4sServerMetricsModule.scala
Outdated
Show resolved
Hide resolved
micrometer/src/main/scala/com/avast/sst/micrometer/interop/Http4sServerMetrics.scala
Outdated
Show resolved
Hide resolved
pureconfig/src/main/scala/com/avast/sst/pureconfig/implicits/Http4sBlazeServer.scala
Outdated
Show resolved
Hide resolved
micrometer-jmx/src/main/scala/com/avast/sst/micrometer/jmx/TypeScopeNameObjectNameFactory.scala
Outdated
Show resolved
Hide resolved
micrometer-jmx/src/main/scala/com/avast/sst/micrometer/jmx/TypeScopeNameObjectNameFactory.scala
Outdated
Show resolved
Hide resolved
micrometer-jmx/src/main/scala/com/avast/sst/micrometer/jmx/TypeScopeNameObjectNameFactory.scala
Show resolved
Hide resolved
@sideeffffect I've updated the code according to your comments. @augi Yes, I guess I need to do that though I wanted to avoid that in case you would shred it to pieces :) If I could describe it in few sentences the point is that we have module per dependency (e.g. |
I'll work on this tomorrow to add some documentation and examples. I'll make it a proper full-blown PR which you can evaluate. |
So my take on this is to avoid optional dependencies and make many small modules instead. First of all, I believe that creating a new module is fairly easy and does not really take much time. And lastly, this solution is quite scaleable as you should only integrate only two libraries together. |
I kind of agree because that was my original intent and the most "pure" solution. However the situation is a bit different with this library. What you refer to is a single library interoperating with N external libraries which results in N SBT modules. What we have is M SBT submodules interoperating with N external libraries which results in theory in M times N SBT submodules. Right now we have PureConfig interoperating with 5 other libraries so we would have to create 5 other submodules. For example we'd have to create two submodules for Micrometer - one for JMX and one for StatsD implementation. Now imagine that in a year we'll replace or add (more probable) new configuration library "FutureConfig"... you have to double the number of submodules immediately. And it gets worse, we now support single implementation of http4s but I can very easily imagine adding support for different implementations, e.g. supporting HTTP client implemented using Apache. So yeah, creating a submodule is easy but having tens of modules with usually only single file seems quite extreme. Thoughts? |
I'm afraid I don't see how Micrometer is related configuration library. Say I have http4s. I would expect following modules:
For me this is very straight forward, clean and manageable. My point is that optional dependencies is just an excuse for our laziness that will hurt us in the future. BTW we already tried something like this before with |
Can you maybe try to explain more what was the problem you encountered? I get what you propose and again I kind of agree. But we do have Also I think that you have the naming in reverse. So this is what we would need now (if I am not forgetting something):
And just by adding new Micrometer implementation (StatsD) and possibly new http4s implementation (Apache) you can immediately add like another 8 or maybe 10 submodules. To me it seems like it's not scalable at all and will get out of hand quite quickly. The problem is that our library does not provide anything new, it's just a mix of other libraries so dependencies might be the biggest problem we're dealing with. That's why I also think that copying others is not the best argument. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about my opinion TBH. As a librarian I went through miscellaneous paths in solving problem like this (even though it was never potentially so big as it is now) so I know how all those solutions suck.
On the other hand, we have to choose some, I'm afraid. So here is my opinion on proposed:
- N times M modules - on will go crazy creating and maintaining (!) huge number of modules and I'm not really sure "users" will really appreciate it
- modules (micrometer, pureconfig, ...) with optional dependencies - this could work, but there's big but. Once we want to avoid
NoClassDeffFoundError
and similar beauties, it's necessary to have the module written in a way user cannot make a mistake. It means, something like this is very bad/sad: "Do not forget to have a dependency on thesst-micrometer-jmx
module in your project" (or it will explode in runtime).
I don't know right now how to solve it, but the idea is to have these things used only in case the user has the right dependency. I have an example - if you consider having animplicit val readerServer: Reader[Server]
whereServer
is something from optional dependency, and it will be used only implicitly, it's kind of clear that compiler will use this val only whenServer
is really present on classpath (because why would it require an instance of some typeclass for it otherwise?). It's not 100% anyway, but IMHO better then the state proposed in current PR.
micrometer-jmx/src/main/scala/com/avast/sst/micrometer/jmx/MicrometerJmxModule.scala
Show resolved
Hide resolved
micrometer-jmx/src/main/scala/com/avast/sst/micrometer/jmx/MicrometerJmxModule.scala
Outdated
Show resolved
Hide resolved
Jenda points out an important fact. If I make all the PureConfig reader definitions Micrometer module is a bit different but I think I do what Augi told me on Slack which is that I require some class from the dependency which again prevents you from the runtime exception because your code wouldn't compile. Please consider that because I think it makes the optional dependencies more digestible ;) |
Could you please be more specific what I'm supposed to look at? I still don't see why would you need two modules for http4s and micrometer integration. Just define metrics trait in a module (or reuse
Well, that's subjective:) But I don't really care about this as long as it's consistent.
But then we won't really fulfill one of our goals: to have small building blocks. We will end up with a few big ones. And if I take into extreme, we can have single module only. |
I don't think that would be very practical. You usually ask yourself "How can I improve my |
@hanny24 I have to think about your message so I'll respond later. @jveselka Get it but that leads directly to the "excessive number of submodules" state so in a way the reverse naming (though probably less natural) could work better. Let me ask you this. Is there anyone who thinks optional dependencies are a viable/better/simpler/whatever solution? (it seems like Jenda thinks so but if everyone else is against it I guess there's no point in discussing this more) We could also try to help us and make less granular submodules. For example I wonder whether |
I'm ok with merge modules as long as all of them require same set of dependencies. It the merged module turns out to be big, we can always split it later. |
So for me if the goal is to have unopinionated library for composing small pieces together into a backend, multiple small modules is the way to. Now we should discuss whether unopinionated is really a way to go. The tradeoffs are: Optional dependencies
Modules
Neither of those choices is very appealing. Which makes me question whether having unopinionated toolbox is a way to go. Btw https://git.int.avast.com/skyline/backend-common can be used as example of what library with many small modules looks like - it's up to you to decide whether it's worth it to have it structured this way (and our approach is much more opinionated that this library is going to be). |
my 2 haléře:
|
Thank you everyone for your comments. I've decided to get rid of optional dependencies and reworked it into multiple smaller modules (on the other hand I merged all the |
refactor: Minor PR improvements
Could you please split it into multiple smaller PRs? It's way to big. |
Sorry but I cannot spend more time on redoing this. I know there's a lot of changes and I will do better next time but as it's all inter-related it would be quite difficult to commit the changes one-by-one and not spend another day or two on this. Please bear with me and try to have a look at it. The most important is whether the artifact names, package names and the way implicits are imported (PureConfig) makes sense to you. Other changes are usually just cosmetic or moving of files from the past. I also added Micrometer monitoring but you've also seen that in the past and last is two bundles for Monix and ZIO which just add |
This reverts commit 4b79398.
I've added some tests, comments, documentation and most importantly fixed the build (caused by case-sensitivity of the file system on Travis). This PR is ready to be merged from my PoV. |
...-client-blaze-pureconfig/src/main/scala/com/avast/sst/http4s/client/pureconfig/package.scala
Outdated
Show resolved
Hide resolved
...src/main/scala/com/avast/sst/http4s/server/micrometer/MicrometerHttp4sMetricsOpsModule.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
object with implicits should be called implicits
, no?
so where do you @jakubjanecek want that green thumb exactly? |
No description provided.