0

I have simple retryable method annotated with

@Retryable(label = "myLabel")

According to documentation, it should be

A unique label for statistics reporting

Is this label accessible inside RetryListener? How can i use it?

hendrix
  • 3,364
  • 8
  • 31
  • 46

1 Answers1

4

The label is available in the RetryContext.NAME attribute in the context.

@Component
class Foo {

    private static final Logger log = LoggerFactory.getLogger(Foo.class);

    @Retryable(label = "myLabel")
    public void retriable() {
        log.info("Here with label: " + RetrySynchronizationManager.getContext().getAttribute(RetryContext.NAME));
        throw new RuntimeException("test");
    }

    @Recover
    public void recover(Exception e) {
        log.info("Recovered");
    }

}

The context is available in the listener methods.

There's a new feature in 1.3.

1.3 is not released yet but there is a snapshot 1.3.0.BUILD-SNAPSHOT in the spring snapshots repo https://repo.spring.io/snapshot.

This also gives you access to the method invocation.

@Component
class MyRetryListener extends MethodInvocationRetryListenerSupport {

    private static final Logger log = LoggerFactory.getLogger(MyRetryListener.class);

    @Override
    protected <T, E extends Throwable> boolean doOpen(RetryContext context,
            MethodInvocationRetryCallback<T, E> callback) {

        log.info("Invocation of method: " + callback.getInvocation().getMethod().toGenericString()
                + " with label: " + callback.getLabel());
        return super.doOpen(context, callback);
    }

}

@Component
class Foo {

    private static final Logger log = LoggerFactory.getLogger(Foo.class);

    @Retryable(label = "myLabel")
    public void retriable() {
        log.info("Here");
        throw new RuntimeException("test");
    }

    @Recover
    public void recover(Exception e) {
        log.info("Recovered");
    }

}
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Correction there's a simpler approach; the label is in the retry context; edited. – Gary Russell Mar 24 '20 at 18:21
  • Thanx. Too bad label property is apparently also exclusive with interceptor (although i dont see any good reason for it - i think label should work with interceptor). For now, i will parse method name from RetryContext.NAME (which has default value like 'public void ... (...)', even when label is not set) – hendrix Mar 25 '20 at 19:00
  • ?? All other properties are ignored when using `interceptor` - per the javadocs. You can set the label on the interceptor instead `StatelessRetryInterceptorBuilder.stateless().label("myLabel").build();`. – Gary Russell Mar 25 '20 at 19:12
  • Yes, i know. But what i find useful about interceptor is that i can easily reuse complex retry configuration for multiple @Retryable methods and having single label for all of them is useless. Anyway, once 1.3 is released i will solve it with MethodInvocationRetryCallback – hendrix Mar 25 '20 at 22:23