package org.infinispan.remoting.transport.jgroups;
import java.util.Collection;
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.infinispan.util.concurrent.TimeoutException;
import org.jgroups.Address;
import org.jgroups.blocks.GroupRequest;
import org.jgroups.util.RspList;
/**
* @author Dan Berindei
* @since 8.0
*/
public class RspListFuture extends CompletableFuture<Responses>
implements Callable<Void>, BiConsumer<RspList<Response>, Throwable> {
private final Collection<Address> addresses;
private final GroupRequest<Response> request;
private volatile Future<?> timeoutFuture = null;
RspListFuture(Collection<Address> addresses, GroupRequest<Response> request) {
this.addresses = addresses;
this.request = request;
request.whenComplete(this);
}
public void setTimeoutFuture(Future<?> timeoutFuture) {
this.timeoutFuture = timeoutFuture;
if (isDone()) {
timeoutFuture.cancel(false);
}
}
@Override
public Void call() throws Exception {
// The request timed out
completeExceptionally(new TimeoutException("Timed out waiting for responses"));
request.cancel(true);
return null;
}
@Override
public void accept(RspList<Response> rsps, Throwable throwable) {
requestDone(rsps, throwable);
}
private void requestDone(RspList<Response> rsps, Throwable throwable) {
if (throwable == null) {
complete(new Responses(addresses, rsps));
} else {
completeExceptionally(throwable);
}
if (timeoutFuture != null) {
timeoutFuture.cancel(false);
}
}
}