package org.infinispan.remoting.transport.jgroups;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.BiConsumer;
import org.infinispan.remoting.responses.Response;
import org.jgroups.SuspectedException;
import org.jgroups.util.Rsp;
/**
* @author Dan Berindei
* @since 8.0
*/
public class SingleResponseFuture extends CompletableFuture<Rsp<Response>>
implements BiConsumer<Response, Throwable>, Callable<Void> {
private final CompletableFuture<Response> request;
private volatile Future<?> timeoutFuture = null;
SingleResponseFuture(CompletableFuture<Response> request) {
this.request = request;
request.whenComplete(this);
}
private void requestDone(Response response, Throwable throwable) {
if (throwable == null) {
complete(new Rsp<>(response));
} else if (throwable instanceof SuspectedException) {
Rsp<Response> rsp = new Rsp<>();
rsp.setSuspected();
complete(rsp);
} else {
complete(new Rsp<>(throwable));
}
if (timeoutFuture != null) {
timeoutFuture.cancel(false);
}
}
public void setTimeoutFuture(Future<?> timeoutFuture) {
this.timeoutFuture = timeoutFuture;
if (isDone()) {
timeoutFuture.cancel(false);
}
}
@Override
public Void call() throws Exception {
// The request timed out
complete(new Rsp<>());
request.cancel(false);
return null;
}
@Override
public void accept(Response response, Throwable throwable) {
requestDone(response, throwable);
}
}