-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Make Archaius a soft dependency through reflection and improve plugin… #1083
Conversation
NetflixOSS » Hystrix » Hystrix-pull-requests #340 SUCCESS |
Thanks for the PR, @agentgt . Very good timing, as I was just working on this. Will review and leave comments. |
Thanks @mattrjacobs . I can cleanup the code and add Javadoc tomorrow. The only downside to this implementation is that if you really really do not want Archaius you will have to manually exclude the dependency (since if we make the dependency optional it will break existing users). But even if it is in the classpath one could provide another This is also fairly hard to unit test with out creating dummy projects but I have done something similar in the past to test something like this (apologies for no unit test). I'll see if I can add a unit test later. |
I took a first pass through this and it looks like it does what I think it should. I will set up a couple projects in hystrix-examples to get some more experience with it before I merge. Another problem that I'd like to solve is the actual compile dependency on Archaius. I'd like to drop that and make a new contrib module Once I get some examples, with and without Archaius, working, I'll layer those on top of this PR. Thanks for this! |
@mattrjacobs I thought about making a The other reason I didn't do it was that I was hoping not to have to wait till version 2.0 for this to be released. @benjchristensen had alluded that making sweeping changes in the config loading (and existing interfaces in general) would have to wait till 2.0 (something my company can't really wait for albeit we can just for fork for now). I'm not sure if the same applies for unit tests but I rather be safe and have a more incremental process (ie release more). Speaking of which I'll be adding unit tests shortly to test the ServiceLoader part :) (the reflection is already heavily hit with the existing tests). |
NetflixOSS » Hystrix » Hystrix-pull-requests #341 SUCCESS |
NetflixOSS » Hystrix » Hystrix-pull-requests #343 FAILURE |
@mattrjacobs I have finished adding Unit tests and Javadoc. The only thing I noticed/changed is how the HystrixPlugin is loaded as a singleton eagerly. //We should not load unless we are requested to. This avoids accidental initialization. @agentgt
//See https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom
private static class LazyHolder { private static final HystrixPlugins INSTANCE = HystrixPlugins.create(); } I prefer lazy loading so you don't accidentally kick off loading by just importing Let me know if and when you want me to squash the commits. |
This change is already backwards incompatible with 1.4/1.5, due to the type hierarchy change. When I swapped out hystrix-core-1.4.23.jar with a jar built from this branch, I got a
Changing the type hierarchy is not permissible. So it's already looking like this might have to go to 2.0. |
@mattrjacobs If that is the case we should probably rename that class since its no longer tied to Archaius and make the other classes in there ( For now my company can just roll and release our own in our private repo. |
@mattrjacobs I think I can fix the hierarchy change easily (well somewhat) by just creating another I'll update the PR with this change shortly. |
NetflixOSS » Hystrix » Hystrix-pull-requests #345 FAILURE |
NetflixOSS » Hystrix » Hystrix-pull-requests #346 SUCCESS |
NetflixOSS » Hystrix » Hystrix-pull-requests #347 SUCCESS |
@mattrjacobs I tested the latest in isolation without Archaius in the classpath and it now seems to work fine. When you get a chance can you test on your end as I can't test the verify hierarchy issue you had (n.b. I accidentally amended some commits and force pushed). The only change I want to make is perhaps simplify |
NetflixOSS » Hystrix » Hystrix-pull-requests #348 FAILURE |
@agentgt I talked to @elandau (owner of Archaius) and got some more clarity on where things stand. Let me know if the following plans make sense for you:
Then, add in Let me know if this makes sense. |
NetflixOSS » Hystrix » Hystrix-pull-requests #349 SUCCESS |
Thanks @mattrjacobs for the followup! As for the ServiceLoader it does have some rather undeserved criticism on some stackoverflow post (that I can't seem to find) but the fact is its used heavily in the Java world during bootstrapping and thus the class is generally already loaded. In fact the logging library logback uses the ServiceLoader (I would know because I put it in 😃 ) . You could certainly load using a System property but I believe this causes more issues and is not canonical. The service loader also has the advance benefit if you just put a jar with the right META-INF registration it will load it.. ie plugins on demand based on dependencies. As for Archaius 2.0 I really hope it does well but I found it still to be rather buggy (I'm in fact surprised there is now a 2.0 tag... and it has been released). I'm really hoping Archaius becomes the slf4j for configuration. I wrote my own configfacade lib for my company because there are so many libs/frameworks now that used a mixture of configuration formats/sources and I need an abstraction. When we figure out the 1.5 stuff I'll continue to help port the code and/or fix all the unit tests that reference Archaius (directly or indirectly). |
@agentgt I've just confirmed that this version is binary-compatible with 1.4.x. Thanks for getting that done! I'll take another pass through your changes to see if anything else requires review. I've only tested the case in which Archaius is provided, and verified that this still works. Have you tested that excluding Archaius drops back to static configuration? |
@mattrjacobs Yes I have manually tested with Archaius not in the classpath and it works (it uses the system properties). I'm thinking of checking a system property to disable loading archaius even if it is on the classpath so that we can at least have unit test coverage for that execution path of falling back to system properties (I already have a test for the service loader path). That should be my last change. |
…s Helper more private.
NetflixOSS » Hystrix » Hystrix-pull-requests #354 FAILURE |
@mattrjacobs I added some more unit tests and way to load the HystrixDynamicProperties via a system property ( This made unit testing a little easier as well as providing an option to completely avoid the service loader for those that might be concerned about the performance of initial resource checking (ie cmdline I don't think I have any more changes. Thank you! |
Thanks, @agentgt . Reviewing now... |
/** | ||
* This class should not be imported from any class in core or else Archaius will be loaded. | ||
* @author agentgt | ||
* @see HystrixArchaiusHelper |
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.
This doesn't resolve. Can you add the {@link XXX} syntax and either import HystrixArchaiusHelper
or use the fully-qualified class name?
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 will remove the line altogether. HystrixArchaiusHelper now is private and internal anyway (hence why I moved it to the same package as HystrixPlugin
).
I'm going to try to summarize the changes to make sure I understand them. Please correct me if I got any of the details wrong.
Because of that loading algorithm and the use of lazy loading, Archaius is not referenced until you've had a chance to override it. And not finding it still allows the System properties to work as an implementation of For command/threadpool/collapser/timer-threadpool properties, these are all instances of This all makes sense to me, and I think is a valuable addition. I left a couple of line-level comments as well, but wanted to make sure I reviewed the changeset as a whole somewhere (and that I understand how it hangs together). Thanks for the contribution! |
|
||
|
||
|
||
private static HystrixDynamicProperties resolveDynamicProperties(ClassLoader classLoader) { |
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.
IMO, I think it's valuable to add a logger.info call here on each possible return. This will aid debugging as users can understand where the HystrixDynamicProperties
instance is getting loaded from.
Something like :
`logger.info("Created HystrixDynamicProperties instance from System property named "hystrix.plugin.HystrixDynamicProperties.implementation");
or
logger.info("Created HystrixDynamicProperties instance by loading from ServiceLoader. Using class : " + hp.getClass().getSimpleName()");
As examples of verbosity.
What do you think?
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.
See my other line comment on logging. We have to be very careful about when we kick off logging. It needs to be after whatever configuration framework has loaded (HystrixDynamicProperties
) because the configuration framework may want to participate in configuring logging. This is a long going chicken/egg problem with java config and logging. This appears to be after so we can probably do it but we cannot statically call getLogger
or else we load the logging framework too early. I'll see if I can put in a safe change.
NetflixOSS » Hystrix » Hystrix-pull-requests #355 FAILURE |
@mattrjacobs I added logging (safely) and fixed the javadoc issue. Let me know what you think. |
Any reason for mixing debug/info level logging? My preference would be for all to be at info. |
I just tested this again in an Archaius environment, and that worked as expected, including the new logging |
Backward compatibility. Existing users might not like the noise... ie we are adding an info statement that didn't happen before. I made the system properties one info because its almost at warning state (hence the exclamation mark instead of a period). Feel free to change it. I took my best guess and what I think I would have liked but I can see an argument made for any case. |
OK, works for me. Thanks for all your work getting this done. I'll merge and cut RC3 shortly. I'd love any validation you could do on that. |
Make Archaius a soft dependency through reflection and improve plugin…
Released in 1.5.0-rc.3 now. |
See #970 #129 #252
This change does a couple of things to
hystrix-core
that should be fairly safe and backward compatibilityHystrixDynamicProperties
due to the whole nasty coupling withHystrixPropertiesChainedArchaiusProperty
andPropertyWrapper
. Thus you don't have to replace everyXXXStrategy
if you only want to change configuration source.HystrixDynamicProperties
can only be loaded through aServiceLoader
(cause you got not properties to resolve it :) ). ThusHystrixPlugin
must load with some plugin implementation and thus isfinal
. If no implementation is found an implementation that uses theSystem.properties
is used ( we could instead fail). This would only happen if you didn't have Archaius in your classpath and no other implementation available (ie serviceloader).I need these changes because right now my company cannot use Archaius and thus we have our own nasty circruitbreaker stuff that I would love to get rid of.
I know @mattrjacobs was working on this as well. This is mainly to invoke discussion. I'm also not so sure what the coding style is or should be (I saw tabs but used spaces...). Advance apologies.