-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Introduce HealthIndicatorRegistry with support for invocation of HealthIndicators #4954
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
|
healths.put(entry.getKey(), entry.getValue().get()); | ||
} | ||
catch (Exception e) { | ||
e.printStackTrace(); |
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.
Shouldn't this use a logger instead?
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.
Ugh, don't know how I managed to miss this - thanks!
Looks like a really nice enhancement. I look forward to being able to use it - especially health checks run in parallel. 👍 |
Thanks for the PR, @vpavic. To safely support registration at runtime, the registry needs to be thread-safe and the current implementation isn't. I suspect that plain old synchronization, rather than something like a read-write lock, will probably be sufficient. |
public class DefaultHealthIndicatorRegistry implements HealthIndicatorRegistry { | ||
|
||
private final Map<String, HealthIndicator> healthIndicators = | ||
new HashMap<String, HealthIndicator>(); |
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.
@wilkinsona Would simply making this a ConcurrentHashMap
alleviate the thread safety concerns regarding registration at runtime?
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.
Maybe :) It depends on the desired semantics. Using a concurrent hash map could result in an indicator being called after it's been removed from the registry. Similarly, the contract of getRegisteredNames
needs to be tightened up. Is it intended as a view of keys that may change, or as a snapshot taken at the time of the call?
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.
getRegisteredNames
is intended as a current snapshot.
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.
The current implementation provides a view onto the keys of the underlying map so its contents may change if an indicator is (un)registered.
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 see - I forgot to wrap key set into a new set.
@vpavic Looking at this some more, two further thoughts have occurred to me:
|
@wilkinsona I'd say the answer to both questions is yes. Regarding registration by name, IMO registry should maintain a name, or key, for each of managed Invocation of indicator does make it two responsibilites, but it also seems somewhat natural, doesn't it? Having invocation service separated from the registry IMO seems more complicated for the users. Do you see any downsides of this approach? |
This commit introduces HealthIndicatorRegistry which handles registration and invocation of HealthIndicator instances. Registering new HealthIndicator instances is now possible in runtime. The default implementation offers the option to run the registered health indicators in parallel.
42b92f8
to
7ea8402
Compare
@wilkinsona, @shakuzen, thanks for your feedback, I've updated the PR accordingly. |
|
||
@Override | ||
public Set<String> getRegisteredNames() { | ||
return Collections.unmodifiableSet(new HashSet<String>(this.healthIndicators.keySet())); |
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 isn't thread-safe
Not to me. We already have a class, |
@wilkinsona Also, how does a user gets a reference to a "service" that invokes health indicator(s)? IMO there should be a dedicated interface which I could use within my app to invoke all |
I'm not necessarily disagreeing with this, but I do disagree with the registry performing this role. What happens if I want to get hold of all of the indicators and call them in a different way? The current API is cumbersome at best for accessing all of the registered indicators. It appears to be designed with the assumption that the way in which it calls all of the indicators will suit everyone. |
Here's a proposal for the registry API:
I'm not 100% sure on the return type for |
This is fine when considering
OK, so it might be good thing to explore the possibilites of separate API for invocation of indicators, with something like invocation strategy to define the way indicators are invoked (sequentially, in parallel, partially etc.). WDYT? The updated API looks concise. A |
Me too. |
Got you. I agree that it should be possible to invoke all the indicators and access the individual results.
This is definitely worth exploring, although I'm not yet convinced that it's necessary. Let's sketch something out (either in a separate PR or in comments on #2652) and then take it from there. I think the best thing to do with this PR is to close it as we should tackle the registry and the parallel invocation separately. I'll add some comments to #4894 for the registry API design. |
This PR introduces
HealthIndicatorRegistry
which handles registration and invocation ofHealthIndicator
instances. Registering newHealthIndicator
instances (as well as unregistering) is now possible in runtime (see #4894).The default implementation offers the option to run the registered health indicators in parallel therefore improving the performance of
HealthEndpoint
invocations in scenarios with multiple expensiveHealthIndicators
(see #2652).