【发布时间】:2016-07-10 18:51:23
【问题描述】:
我的应用程序通常必须做两件事:
- 同时只接受一个网络请求
- 请求失败时重试
我就是这样实现的:
public class RequestsLocker {
private volatile boolean isLocked;
public <T> Observable.Transformer<T, T> applyLocker() {
if(!isLocked()) {
return observable -> observable
.doOnSubscribe(() -> {
lockChannel();
})
.doOnUnsubscribe(() -> {
freeChannel();
});
} else {
return observable -> Observable.error(new ChannelBusyException("Channel is busy now."));
}
}
private void lockChannel() {
isLocked = true;
}
private void freeChannel() {
isLocked = false;
}
public boolean isLocked() {
return isLocked;
}
}
看起来不错。
现在我的retryWhen 实现:
public static Observable<?> retryWhenAnyIoExceptionWithDelay(Observable<? extends Throwable> observable) {
return observable.flatMap(error -> {
// For IOExceptions, we retry
if (error instanceof IOException) {
return Observable.timer(2, TimeUnit.SECONDS);
}
// For anything else, don't retry
return Observable.error(error);
});
}
这是我的使用方法:
public Observable<List<QueueCarItem>> finishService(int id, PaymentType paymentType, String notes) {
return carsQueueApi.finishService(id, new FinishCarServiceRequest(paymentType.getName(), notes))
.compose(requestsLocker.applyLocker(RequestsLocker.RequestChannel.CHANGE));
}
...
public void finishCarService(QueueCarItem carItem, PaymentType paymentType,
String notes, Subscriber<List<QueueCarItem>> subscriber) {
queueApiMediator.finishService(carItem.getId(), paymentType, notes)
.subscribeOn(ioScheduler)
.observeOn(uiScheduler)
.doOnError(this::handleError)
.retryWhen(RxOperatorsHelpers::retryWhenAnyIoExceptionWithDelay)
.subscribe(subscriber);
}
doOnUnsubscribe() 调用任何错误的主要问题,然后储物柜对任何新请求都是打开的,直到计时器到期并再次发生重新订阅。那就是问题所在。当计时器计时,用户可以发出另一个请求。
我该如何解决?
【问题讨论】:
-
您能否发布一些代码,展示您如何实际使用
applyLocker转换器和retryWhenAnyIoExceptionWithDelay?
标签: android rx-java reactive-programming rx-android reactivex