Skip to content
This repository has been archived by the owner on Dec 5, 2022. It is now read-only.

Enhancement/gather statistics #40

Merged
merged 25 commits into from Nov 7, 2017
Merged

Conversation

MALPI
Copy link
Member

@MALPI MALPI commented Sep 27, 2017

Fixes #23

WIP
Extends Failsafe Actuator by the feature to provide failure/success metrics for the used Circuit Breakers.

Still open:

  • Add duration of a call
  • extend Readme.md.

@MALPI MALPI changed the base branch from master to release/0.5.0 September 27, 2017 06:57
private final Meter overallMeter;
private String identifier;

public FailsafeBreaker(final MetricRegistry metricRegistry, final String identifier) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking if we should provide an abstraction layer around the metrics registry that would allow the users to plugin a different metrics collector, eg. prometheus.

For doing so we would need to introduce apart from the registry interface a Meter interface as well which would encapsulate the meter than.

As the default I would propose to provide a DropWizard Metrics implementation.

WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spring supports PublicMetrics for this.

@MALPI MALPI mentioned this pull request Oct 5, 2017
public CircuitBreakerRegistry circuitBreakerRegistry() {
circuitBreakerRegistry = new CircuitBreakerRegistry();
circuitBreakerRegistry = new CircuitBreakerRegistry(this.metricRegistry);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't assign to instance variables here, but rather take metricsRegistry as a parameter.

}

@Override
public void recordResult(Object result) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be done with event listeners rather than subclassing.

Malte Pickhan added 2 commits October 6, 2017 20:59
@zalando zalando deleted a comment Oct 6, 2017
@zalando zalando deleted a comment Oct 6, 2017
@zalando zalando deleted a comment Oct 6, 2017
@zalando zalando deleted a comment Oct 6, 2017
@MALPI
Copy link
Member Author

MALPI commented Oct 11, 2017

Thanks for you input @whiskeysierra. Should all be considered in my last commits.

@@ -44,7 +46,12 @@
<scope>provided</scope>
<version>1.16.18</version>
</dependency>
<dependency>
<dependency>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you still need this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because Spring default metrics doesn't support Meter. But maybe you are right and we should rely on Spring defaults here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The less dependencies the better. Gives your clients more freedom.

@@ -31,12 +34,24 @@
private CircuitBreakerRegistry circuitBreakerRegistry;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, shouldn't be needed to have this assigned to an instance field.

public CircuitBreakerRegistry circuitBreakerRegistry() {
circuitBreakerRegistry = new CircuitBreakerRegistry();
return circuitBreakerRegistry;
}

@Bean
@DependsOn("metricRegistry")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed.

return new DropwizardMetric(metricRegistry, circuitBreakerRegistry);
}

@Bean
@DependsOn("circuitBreakerRegistry")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with parameter.

final Meter failureMeter = metricRegistry.meter(identifier + FAILURE);
metricMap.put(identifier, Arrays.asList(successMeter, failureMeter));
Failsafe.with(circuitBreakerRegistry.getConcurrentBreakerMap().get(identifier))
.with(new DropwizardListener(failureMeter, successMeter));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably won't work as expected.

@@ -34,9 +32,9 @@

@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misleading because your registry actually implements a singleton pattern. Couldn't you delegate all of this work to spring?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we could do this. But I would prefer to do this change in another PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #45

@zalando zalando deleted a comment Oct 23, 2017
@zalando zalando deleted a comment Oct 23, 2017
@MALPI MALPI force-pushed the enhancement/gather-statistics branch from a058618 to 3b6b530 Compare October 23, 2017 19:01
@zalando zalando deleted a comment Oct 23, 2017
@zalando zalando deleted a comment Oct 23, 2017
@MALPI
Copy link
Member Author

MALPI commented Oct 24, 2017

@whiskeysierra @coders-kitchen can you have another look?

pom.xml Outdated

<modelVersion>4.0.0</modelVersion>

<groupId>org.zalando</groupId>
<artifactId>failsafe-actuator</artifactId>
<version>0.4.1</version>
<version>0.5.1</version>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should a bump of the minor version set the patch back to 0, i.e. 0.5.0?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, will change that

@@ -1,29 +1,42 @@
/**
* The MIT License (MIT)
* Copyright (c) 2016 Zalando SE
* The MIT License (MIT) Copyright (c) 2016 Zalando SE
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe that you actually need to put the header in every file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, see #52

private CircuitBreakerRegistry circuitBreakerRegistry;
@Bean
@ConditionalOnMissingBean(MetricWriter.class)
public MetricWriter metricWriter() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't create those in here. The better approach would be to degrade and perform retries and manage circuit breakers without recording metrics.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 a noop implementation in this case makes more sense

});
} catch (RuntimeException e) {
.with(new CountingListener<>(counterService, breaker.value()))
.get(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work for methods that return a Future.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should file a new Issue for that since this logic wasn't introduced by this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #58

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @whiskeysierra now as I am looking into it, it's not really clear to me what you mean here. Could maybe explain a bit more in detail or extend the issue? Would be awesome!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two kinds of methods, sync and async. get is for synchronous methods. For something that returns a future, you should use future: https://github.com/jhalterman/failsafe#completablefuture-integration

Let's say you have a method that performs a remote request asynchronously and returns a Future<User>.

  • get would only retry the synchronous part of that, i.e. if anything failed during the creation of the future, but not during
  • future would be aware that the operation is asynchronous and it would correctly retry the asynchronous operation

try {
return methodInvocation.proceed();
} catch (final Throwable throwable) {
throw new FailsafeBreakerWrappedException(throwable);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this custom exception type needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coders-kitchen should know. Depending on the outcome we should also tackle this on a separate issue as already mentioned before.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to have explicit exceptions in cases like this, to make it clear what the cause in case anything unexpected happen.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coders-kitchen But you're deviating from the normal behaviour of failsafe. If a user would migrate from manually using failsafe to this annotation+advice, then he/she would experience a different behaviour. I believe it would be in the best interest of everybody if both ways are 100% compatible.

@MALPI
Copy link
Member Author

MALPI commented Oct 30, 2017

@whiskeysierra @coders-kitchen I would consider this PR as done. Any further feedback?

@coders-kitchen
Copy link

@MALPI Fine from my side

@MALPI
Copy link
Member Author

MALPI commented Nov 7, 2017

👍

@MALPI MALPI merged commit 7b606e0 into release/0.5.0 Nov 7, 2017
@MALPI MALPI deleted the enhancement/gather-statistics branch December 19, 2017 08:08
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants