![](/img/trans.png)
[英]Android/RxJava How to chain network requests and retry when it fails
[英]How to retry an operation when it fails
我有以下合同的单身客户
public interface MQPublisher {
void publish(String message) throws ClientConnectionException, ClientErrorException;
void start() throws ClientException;
void stop();
}
使用此发布者的类如下:
public class MessagePublisher {
@Autowired
private MQPublisher publisher;
private AtomicBoolean isPublisherRunning;
public void startPublisher() {
if (!isPublisherRunning.get()) {
publisher.start();
isPublisherRunning.compareAndSet(false, true);
}
}
@Retry(RETRY_MSG_UPLOAD)
public void sendMessage(String msg) {
try {
startPublisher();
publisher.publish(msg); // when multiple requests fail with the same exception, what will happen??
} catch (Exception e) {
log.error("Exception while publishing message : {}", msg, e);
publisher.stop();
isPublisherRunning.compareAndSet(true, false);
throw e;
}
}
我们正在使用resilience4j 重试功能来重试sendMessage 方法。 这在单个请求的情况下工作正常。 考虑并行处理多个请求并且所有请求都失败并出现异常的情况。 在这种情况下,这些请求将被重试,并且有可能一个线程将启动发布者,而另一个线程将停止它并再次抛出异常。 如何以更清洁的方式处理这种情况?
目前尚不清楚为什么在失败的情况下应该停止整个发布者。 不过,如果有真正的原因,我会更改 stop 方法以使用原子计时器,该计时器将在每次发送消息时重新启动,并且仅在至少 5 秒(或成功发送消息所需的时间)后停止发布者) 已通过消息发送。 像这样的东西:
@Slf4j
public class MessagePublisher {
private static final int RETRY_MSG_UPLOAD = 10;
@Autowired
private MQPublisher publisher;
private AtomicBoolean isPublisherRunning;
private AtomicLong publishStart;
public void startPublisher() {
if (!isPublisherRunning.get()) {
publisher.start();
isPublisherRunning.compareAndSet(false, true);
}
}
@Retryable(maxAttempts = RETRY_MSG_UPLOAD)
public void sendMessage(String msg) throws InterruptedException {
try {
startPublisher();
publishStart.set(System.nanoTime());
publisher.publish(msg); // when multiple requests fail with the same exception, what will happen??
} catch (Exception e) {
log.error("Exception while publishing message : {}", msg, e);
while (System.nanoTime() < publishStart.get() + 5000000000L) {
Thread.sleep(1000);
}
publisher.stop();
isPublisherRunning.compareAndSet(true, false);
throw e;
}
}
}
我认为重要的是(正如您刚才所做的那样)这是一个糟糕的设计,并且此类计算应该由发布者实现者而不是调用者来完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.