Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add a possibility to use listener per @Retryable method instead of global listeners #485

Open
yura-arab4uk opened this issue Feb 8, 2025 · 5 comments

Comments

@yura-arab4uk
Copy link

yura-arab4uk commented Feb 8, 2025

In my project I wanted to add a listener and use it along with @Retryable annotation.
But when I add a listener, it's automatically considered by Spring Retry as global one, meaning it will be applied at least to every method marked with @Retryable annotation, which prevents me from creating listener, because I don't want to impact an existing code.

Example:
@Retryable(retryFor = SomeException.class, maxAttempts = 5, listeners = "myListenerBean")

When I create myListenerBean, it will be automatically applied to all existing methods with @Retryable annotation, which is not desired behavior.
The only way to prevent this is to either specify an empty string on existing code, which is not always possible to modify an existing code

@Retryable(listeners = "")

or use interceptor attribute which cannot be used with any other attributes and which requires interceptor bean along with all retry configurations code:

@Retryable(interceptor = "myInterceptorBean")

As a result instead of using neat single line:
@Retryable(retryFor = SomeException.class, maxAttempts = 5, listeners = "myListenerBean")

I'm forced to use:
@Retryable(interceptor = "myInterceptorBean")

along with whole retry configuration, for example:

@Slf4j
@Configuration
@RequiredArgsConstructor
public class ConnectionErrorRetryConfig {
    public static final String CONNECTION_ERROR_RETRY_INTERCEPTOR = "connectionErrorRetryInterceptor";

    @Value("${request.max-attempts:5}")
    private int maxAttempts;

    private final MyService myService;

    @Bean(CONNECTION_ERROR_RETRY_INTERCEPTOR)
    public RetryOperationsInterceptor connectionErrorRetryInterceptor() {
        SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
        simpleRetryPolicy.setMaxAttempts(maxAttempts);

        RetryTemplate retryTemplate = RetryTemplate.builder()
            .customPolicy(simpleRetryPolicy)
            .retryOn(SomeException.class)
            // forced to create a new RetryListener here as NOT a bean, because bean is impacting globally every @Retryable method
            .withListener(new RetryListener() {
                @Override
                public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable)
                {
                    if (throwable instanceof SomeException someException)
                    {
                        myService.doImportantAction(someException);
                    }

                    RetryListener.super.onError(context, callback, throwable);
                }
            })
            .build();

        return RetryInterceptorBuilder.stateless()
            .retryOperations(retryTemplate)
            .recoverer(new ConnectionErrorRecoverer())
            .build();
    }
}

As it's been already discussed here, we could think of any alternative, for example deprecating existing listeners attribute and/or providing some other attribute(s) etc. in order to not use global listeners.

Thanks.

@yura-arab4uk
Copy link
Author

yura-arab4uk commented Feb 8, 2025

By @artembilan we can solve this in the future:
#484 (reply in thread)

@artembilan
Copy link
Member

Thank you, Yuriy!
Please, take into account that words starting with @ have to be present as a code (wrapped into back-ticks), otherwise GitHub treats it as a user mention.

I mean that gas to be like:

methods with @Retryable annotation.

@yura-arab4uk
Copy link
Author

@artembilan sure, corrected, thx

@artembilan
Copy link
Member

It doesn’t matter now in this post: a notification has already been sent to that GH user 😅.

@yura-arab4uk
Copy link
Author

yura-arab4uk commented Feb 10, 2025

Good for that user : ), if such user exists then will learn about this issue 😅

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants