-
Notifications
You must be signed in to change notification settings - Fork 315
Resilience4j 2+ #9525
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
Merged
Merged
Resilience4j 2+ #9525
Changes from 90 commits
Commits
Show all changes
96 commits
Select commit
Hold shift + click to select a range
bccd0fd
Minimal viable instrumentation example with a test
ygree 54affc6
Add latestDepTest
ygree e585701
Instrument decorateCheckedSupplier
ygree 39d8d5d
Do not create resilience4j span if it already exist
ygree f5c160c
Instrument decorateCompletionStage
ygree 76e196c
Fix the asynchronous test to ensure proper testing
ygree 4f486f2
Extract DDContext
ygree b77dd6e
Start RetryInstrumentation
ygree b8a0fa0
Implemented a very minimal initial Retry CompletionStage instrumentat…
ygree 8e7ec5b
Instrument Retry decorateCheckedSupplier and decorateSupplier.
ygree d1ca290
Span per decorator layer
ygree 20ddcfd
Change instrumentation approach to only wrap top-level decorators.
ygree e970d72
Wrap resulting completionStage to finish a decorator span properly
ygree f71d32f
Wrap the inbound async supplier for scope handling and the outbound f…
ygree b2db626
Only wrap outbound decorator for both sync and async decorators.
ygree 92be261
Fallback test scenarios
ygree 2a46b25
Rename AbstractResilience4jInstrumentation
ygree 9acbf73
Fallback supplier instrumentation
ygree ab60ef0
Supplier Fallback instrumentation
ygree a2ed779
Introduce FallbackCompletionStageInstrumentation
ygree e6e46e3
Add StackedDecoratorsTest
ygree e39a5af
Use a single span for the entire R4J decorator.
ygree 512bf97
Use a single span for the entire R4J decorator.
ygree bc88b5f
Use a single span for the entire R4J decorator.
ygree 4903361
Move out all context handling logic into DecoratorWithContext
ygree 154b985
Move out all wrappers into the DecoratorWithContext
ygree bb43357
PoC span decorators
ygree 04d4ff1
PoC reactor resilience4j circuit breaker instrumentation
ygree cf2e2d0
Simplify core r4j scope management. Rely on execution active span ins…
ygree d149cb0
Extract ActiveResilience4jSpan
ygree 65d0163
Rename ActiveResilience4jSpan methods
ygree 9f3bbe1
PoC Reactor Flux R4j instrumentation and R4j parameterized span decor…
ygree 4b3e0fa
Split r4j core and reactor modules
ygree fd15ebf
Add RetryOperatorInstrumentation
ygree 9e41b6e
Finish span whenComplete
ygree 97b0d8c
Call span decorator
ygree d20c14e
Rework r4j reactor instrumentation. Using reactor-core-3.1's dd.span …
ygree 3b5c590
FallbackOperatorInstrumentation WIP
ygree 6b3de3c
WIP
ygree 635649e
Start a separate span for each r4j decorator for easier debugging
ygree d61eafe
Introduce TraceCapturingTest
ygree 8223f57
Introduce TraceCapturingTest
ygree c9940b6
Add FallbackTest with Fallback and Retry Mono support
ygree 0091150
Collapse resilience4j spans into a single span.
ygree bdb4807
Extract scheduleSpanFinish
ygree f9ef6f7
Do not finish unowned span
ygree e32263f
test circuit-breaker state reporting
ygree b84cbea
Span decorators
ygree fb3fed1
Span decorators
ygree b6d6b5b
Span decorators
ygree 5aa67be
Retry and Circuit Breaker decorators and tests
ygree 520a67b
Clean up
ygree 4149141
Support Function Decorators
ygree 150157e
Shorten Retry metric tags
ygree a42fdfd
CheckedRunnable
ygree 6ce6230
Callable
ygree 5f758d6
Consumer CircuitBreaker decorator
ygree baf1d87
CheckedFunction CircuitBreaker decorator
ygree 9189da8
CheckedFunction Retry decorator
ygree 4d2a087
CircuitBreaker.decorateCheckedConsumer
ygree 0fc35a4
CircuitBreaker.decorateRunnable
ygree 745e0ed
Use instrumented static methods direcly in the tests
ygree 6a9e38a
Reorder CircuitBreaker tests:
ygree 1b49173
Instrument Retry.decorateRunnable
ygree ee7fdd6
Remove FallbackDecorator
ygree 93573dc
Rename ContextHolder to WrapperWithContext. Get rid of explicit Objec…
ygree 545c432
Implement FallbackCallable
ygree 584510a
Add missing test cases for ofCompletionStage
ygree 705e2b0
FallbackCheckedSupplierInstrumentation
ygree ffba62a
Instrument withFallback decorators directly
ygree e242e7c
Rename resilience4j-core-2 to resilience4j-2
ygree 8883777
Fix and enable inverse muzzle check
ygree 999e9af
Clean up
ygree b87bc50
Decorator clean up
ygree db8fea9
Support CircuitBreaker.decorateFuture
ygree 6d75de1
Clean up and rearrange r4j-reactor tests
ygree df434f8
Fix muzzle check for resilience4j-reactor
ygree 179888a
Merge branch 'master' into ygree/resilience4j
ygree e081b7d
Follow up fix after the rebase
ygree 5f30062
clean r4j-reactor
ygree b9a29ff
r4j clean up
ygree c3f3aa4
Merge branch 'master' into ygree/resilience4j
ygree 41ca01d
Add configs for measured and tag metrics
ygree d10d1b3
Merge branch 'master' into ygree/resilience4j
ygree 403280d
Move out forked tests
ygree d22f53c
test r4j configs
ygree 771023a
Merge branch 'master' into ygree/resilience4j
ygree c1e228d
Merge branch 'master' into ygree/resilience4j
ygree b66ba46
fix tests
ygree 86a6aba
generated lockfiles
ygree e9ea535
rename modules to the new schema to include minor verion
ygree 5b2e1ab
Reorg instrumentations to be aligned with the new standard
ygree b4b558f
compare SPAN_NAME properly
ygree 77efe3d
Improve r4j span name comparison
ygree 78ef2c5
Fix circuit breaker tag names
ygree ad6f7af
Add Reactor Mono retry test
ygree File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
dd-java-agent/instrumentation/resilience4j/resilience4j-2/build.gradle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| ext { | ||
| minJavaVersionForTests = JavaVersion.VERSION_17 | ||
| } | ||
|
|
||
| apply from: "$rootDir/gradle/java.gradle" | ||
| apply plugin: 'idea' | ||
|
|
||
| muzzle { | ||
| pass { | ||
| group = 'io.github.resilience4j' | ||
| module = 'resilience4j-all' | ||
| versions = '[2.0.0,)' | ||
| assertInverse = true | ||
| javaVersion = "17" | ||
| } | ||
| } | ||
|
|
||
| idea { | ||
| module { | ||
| jdkName = '17' | ||
| } | ||
| } | ||
|
|
||
| // Set all compile tasks to use JDK17 but let instrumentation code target 1.8 compatibility | ||
| project.tasks.withType(AbstractCompile).configureEach { | ||
| setJavaVersion(it, 17) | ||
| } | ||
| compileJava.configure { | ||
| sourceCompatibility = JavaVersion.VERSION_1_8 | ||
| targetCompatibility = JavaVersion.VERSION_1_8 | ||
| } | ||
|
|
||
| addTestSuiteForDir('latestDepTest', 'test') | ||
|
|
||
| dependencies { | ||
| compileOnly group: 'io.github.resilience4j', name: 'resilience4j-all', version: '2.0.0' | ||
|
|
||
| testImplementation group: 'io.github.resilience4j', name: 'resilience4j-all', version: '2.0.0' | ||
| latestDepTestImplementation group: 'io.github.resilience4j', name: 'resilience4j-all', version: '2.+' | ||
| } | ||
|
|
189 changes: 189 additions & 0 deletions
189
dd-java-agent/instrumentation/resilience4j/resilience4j-2/gradle.lockfile
Large diffs are not rendered by default.
Oops, something went wrong.
34 changes: 34 additions & 0 deletions
34
...j-2/src/main/java/datadog/trace/instrumentation/resilience4j/CircuitBreakerDecorator.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package datadog.trace.instrumentation.resilience4j; | ||
|
|
||
| import datadog.trace.api.Config; | ||
| import datadog.trace.bootstrap.instrumentation.api.AgentSpan; | ||
| import io.github.resilience4j.circuitbreaker.CircuitBreaker; | ||
|
|
||
| public final class CircuitBreakerDecorator extends Resilience4jSpanDecorator<CircuitBreaker> { | ||
| public static final CircuitBreakerDecorator DECORATE = new CircuitBreakerDecorator(); | ||
| public static final String TAG_PREFIX = "resilience4j.circuit-breaker."; | ||
| public static final String TAG_METRICS_PREFIX = TAG_PREFIX + "metrics."; | ||
|
|
||
| private CircuitBreakerDecorator() { | ||
| super(); | ||
| } | ||
|
|
||
| @Override | ||
| public void decorate(AgentSpan span, CircuitBreaker data) { | ||
| span.setTag("resilience4j.circuit_breaker.name", data.getName()); | ||
| span.setTag("resilience4j.circuit_breaker.state", data.getState().toString()); | ||
| if (Config.get().isResilience4jTagMetricsEnabled()) { | ||
| CircuitBreaker.Metrics ms = data.getMetrics(); | ||
| span.setTag(TAG_METRICS_PREFIX + "failure_rate", ms.getFailureRate()); | ||
| span.setTag(TAG_METRICS_PREFIX + "slow_call_rate", ms.getSlowCallRate()); | ||
| span.setTag(TAG_METRICS_PREFIX + "slow_calls", ms.getNumberOfSlowCalls()); | ||
| span.setTag( | ||
| TAG_METRICS_PREFIX + "slow_successful_calls", ms.getNumberOfSlowSuccessfulCalls()); | ||
| span.setTag(TAG_METRICS_PREFIX + "slow_failed_calls", ms.getNumberOfSlowFailedCalls()); | ||
| span.setTag(TAG_METRICS_PREFIX + "buffered_calls", ms.getNumberOfBufferedCalls()); | ||
| span.setTag(TAG_METRICS_PREFIX + "failed_calls", ms.getNumberOfFailedCalls()); | ||
| span.setTag(TAG_METRICS_PREFIX + "not_permitted_calls", ms.getNumberOfNotPermittedCalls()); | ||
| span.setTag(TAG_METRICS_PREFIX + "successful_calls", ms.getNumberOfSuccessfulCalls()); | ||
| } | ||
| } | ||
| } |
242 changes: 242 additions & 0 deletions
242
...c/main/java/datadog/trace/instrumentation/resilience4j/CircuitBreakerInstrumentation.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,242 @@ | ||
| package datadog.trace.instrumentation.resilience4j; | ||
|
|
||
| import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; | ||
| import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||
| import static net.bytebuddy.matcher.ElementMatchers.isStatic; | ||
| import static net.bytebuddy.matcher.ElementMatchers.returns; | ||
| import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
|
||
| import com.google.auto.service.AutoService; | ||
| import datadog.trace.agent.tooling.InstrumenterModule; | ||
| import io.github.resilience4j.circuitbreaker.CircuitBreaker; | ||
| import io.github.resilience4j.core.functions.CheckedConsumer; | ||
| import io.github.resilience4j.core.functions.CheckedFunction; | ||
| import io.github.resilience4j.core.functions.CheckedRunnable; | ||
| import io.github.resilience4j.core.functions.CheckedSupplier; | ||
| import java.util.concurrent.Callable; | ||
| import java.util.concurrent.CompletionStage; | ||
| import java.util.concurrent.Future; | ||
| import java.util.function.Consumer; | ||
| import java.util.function.Function; | ||
| import java.util.function.Supplier; | ||
| import net.bytebuddy.asm.Advice; | ||
|
|
||
| @AutoService(InstrumenterModule.class) | ||
| public final class CircuitBreakerInstrumentation extends Resilience4jInstrumentation { | ||
|
|
||
| private static final String CIRCUIT_BREAKER_FQCN = | ||
| "io.github.resilience4j.circuitbreaker.CircuitBreaker"; | ||
|
|
||
| private static final String THIS_CLASS = CircuitBreakerInstrumentation.class.getName(); | ||
|
|
||
| public CircuitBreakerInstrumentation() { | ||
| super("resilience4j-circuitbreaker"); | ||
| } | ||
|
|
||
| @Override | ||
| public String instrumentedType() { | ||
| return CIRCUIT_BREAKER_FQCN; | ||
| } | ||
|
|
||
| @Override | ||
| public void methodAdvice(MethodTransformer transformer) { | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateCheckedSupplier")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(CHECKED_SUPPLIER_FQCN))), | ||
| THIS_CLASS + "$CheckedSupplierAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateCheckedFunction")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(CHECKED_FUNCTION_FQCN))), | ||
| THIS_CLASS + "$CheckedFunctionAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateCheckedConsumer")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(CHECKED_CONSUMER_FQCN))), | ||
| THIS_CLASS + "$CheckedConsumerAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateCompletionStage")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(SUPPLIER_FQCN))), | ||
| THIS_CLASS + "$CompletionStageAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateFuture")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(SUPPLIER_FQCN))), | ||
| THIS_CLASS + "$FutureAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateConsumer")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(CONSUMER_FQCN))), | ||
| THIS_CLASS + "$ConsumerAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateCheckedRunnable")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(CHECKED_RUNNABLE_FQCN))), | ||
| THIS_CLASS + "$CheckedRunnableAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateCallable")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(CALLABLE_FQCN))), | ||
| THIS_CLASS + "$CallableAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateRunnable")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(RUNNABLE_FQCN))), | ||
| THIS_CLASS + "$RunnableAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateSupplier")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(SUPPLIER_FQCN))), | ||
| THIS_CLASS + "$SupplierAdvice"); | ||
| transformer.applyAdvice( | ||
| isMethod() | ||
| .and(isStatic()) | ||
| .and(named("decorateFunction")) | ||
| .and(takesArgument(0, named(CIRCUIT_BREAKER_FQCN))) | ||
| .and(returns(named(FUNCTION_FQCN))), | ||
| THIS_CLASS + "$FunctionAdvice"); | ||
| } | ||
|
|
||
| public static class SupplierAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) Supplier<?> result) { | ||
| result = | ||
| new WrapperWithContext.SupplierWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class CallableAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) Callable<?> result) { | ||
| result = | ||
| new WrapperWithContext.CallableWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class RunnableAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) Runnable result) { | ||
| result = | ||
| new WrapperWithContext.RunnableWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class FunctionAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) Function<?, ?> result) { | ||
| result = | ||
| new WrapperWithContext.FunctionWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class CheckedSupplierAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) CheckedSupplier<?> result) { | ||
| result = | ||
| new WrapperWithContext.CheckedSupplierWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class CheckedFunctionAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) CheckedFunction<?, ?> result) { | ||
| result = | ||
| new WrapperWithContext.CheckedFunctionWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class CheckedConsumerAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) CheckedConsumer<?> result) { | ||
| result = | ||
| new WrapperWithContext.CheckedConsumerWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class CheckedRunnableAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) CheckedRunnable result) { | ||
| result = | ||
| new WrapperWithContext.CheckedRunnableWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class ConsumerAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) Consumer<?> result) { | ||
| result = | ||
| new WrapperWithContext.ConsumerWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class CompletionStageAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) Supplier<CompletionStage<?>> result) { | ||
| result = | ||
| new WrapperWithContext.SupplierOfCompletionStageWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
|
|
||
| public static class FutureAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.Argument(value = 0) CircuitBreaker circuitBreaker, | ||
| @Advice.Return(readOnly = false) Supplier<Future<?>> result) { | ||
| result = | ||
| new WrapperWithContext.SupplierOfFutureWithContext<>( | ||
| result, CircuitBreakerDecorator.DECORATE, circuitBreaker); | ||
| } | ||
| } | ||
| } | ||
44 changes: 44 additions & 0 deletions
44
...main/java/datadog/trace/instrumentation/resilience4j/FallbackCallableInstrumentation.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package datadog.trace.instrumentation.resilience4j; | ||
|
|
||
| import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; | ||
| import static net.bytebuddy.matcher.ElementMatchers.isMethod; | ||
|
|
||
| import com.google.auto.service.AutoService; | ||
| import datadog.trace.agent.tooling.InstrumenterModule; | ||
| import io.github.resilience4j.core.functions.CheckedSupplier; | ||
| import java.util.concurrent.Callable; | ||
| import net.bytebuddy.asm.Advice; | ||
|
|
||
| @AutoService(InstrumenterModule.class) | ||
| public class FallbackCallableInstrumentation extends Resilience4jInstrumentation { | ||
| public FallbackCallableInstrumentation() { | ||
| super("resilience4j-fallback"); | ||
| } | ||
|
|
||
| @Override | ||
| public String instrumentedType() { | ||
| return "io.github.resilience4j.decorators.Decorators$DecorateCallable"; | ||
| } | ||
|
|
||
| @Override | ||
| public void methodAdvice(MethodTransformer transformer) { | ||
| transformer.applyAdvice( | ||
| isMethod().and(named("withFallback")), | ||
| FallbackCallableInstrumentation.class.getName() + "$CallableAdvice"); | ||
| } | ||
|
|
||
| public static class CallableAdvice { | ||
| @Advice.OnMethodExit(suppress = Throwable.class) | ||
| public static void afterExecute( | ||
| @Advice.FieldValue(value = "callable", readOnly = false) Callable<?> callable) { | ||
| callable = | ||
| new WrapperWithContext.CallableWithContext<>( | ||
| callable, Resilience4jSpanDecorator.DECORATE, null); | ||
| } | ||
|
|
||
| // 2.0.0+ | ||
| public static void muzzleCheck(CheckedSupplier<?> cs) throws Throwable { | ||
| cs.get(); | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.