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); } } }