重试线程安全返回装饰函数吗?

时间:2019-05-17 15:15:45

标签: resilience4j

我有一个将消息发送到远程服务的类,如下所示。 我正在使用resilience4j-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 个答案:

答案 0 :(得分:0)

查看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;
    }

}