Оформлена ли функция возврата Retry threadsafe?

У меня есть класс, который отправляет сообщение на удаленный сервис, как показано ниже. Я использую resilience4j-retry, чтобы повторить сетевой вызов. Поскольку экземпляр retry является потокобезопасным в соответствии с документацией, я создаю его на уровне класса и повторно использую его.

public class RemoteMessageService {

    Retry retry = Retry.of("RemoteMessageService", RetryConfig.custom()
        .maxAttempts(5)
        .retryExceptions(ProcessingException.class)
        .intervalFunction(IntervalFunction.ofExponentialBackoff())
        .build());    

    public void postMessageWithRetry(final String message){

        Function<Integer, Void> postMessageFunction = Retry.decorateFunction(retry, this::postMessage);

        try {
            postMessageFunction.apply(message)
        } catch (final ProcessingException e) {
            LOG.warn("Got processing exception: {}", e.getMessage());
        } catch (final Exception e) {
            LOG.error("Got unknown exception: {}", e.getMessage());
        }
    }

    private Void postMessage(final String message){
        // Do a network call to send the message to a rest service
        // throw ProcessingException in case of timeout
        return null;
    }

}

Мой вопрос, если декорированная функция возвращается Retry.decorateFunction(retry, this::postMessage); также потокобезопасен?

В этом случае я мог бы переместить это на уровень класса вместо того, чтобы повторять это каждый раз, когда вызывается функция postMessageWithRetry.

1 ответ

Решение

После просмотра в resilience4j-retry код, я обнаружил, что декорированная функция на самом деле является потокобезопасной; до тех пор, пока функция, которую мы украшаем, в первую очередь является поточно-ориентированной.

Так что я могу переписать код, как показано ниже postMessage функция является поточно-ориентированной, и поэтому postMessageFunction функция также поточно-ориентированная.

public class RemoteMessageService {

    private final Retry retry = Retry.of("RemoteMessageService", RetryConfig.custom()
        .maxAttempts(5)
        .retryExceptions(ProcessingException.class)
        .intervalFunction(IntervalFunction.ofExponentialBackoff())
        .build());    

    private final Function<Integer, Void> postMessageFunction = Retry.decorateFunction(retry, this::postMessage);

    public void postMessageWithRetry(final String message) {

        try {
            postMessageFunction.apply(message)
        } catch (final ProcessingException e) {
            LOG.warn("Got processing exception: {}", e.getMessage());
        } catch (final Exception e) {
            LOG.error("Got unknown exception: {}", e.getMessage());
        }
    }

    private Void postMessage(final String message) {
        // Do a network call to send the message to a rest service
        // throw ProcessingException in case of timeout
        return null;
    }

}    
Другие вопросы по тегам