org.async.rmi.client.PendingRequests Maven / Gradle / Ivy
package org.async.rmi.client;
import org.async.rmi.Modules;
import org.async.rmi.TimeoutException;
import org.async.rmi.messages.InvokeRequest;
import org.async.rmi.messages.Response;
import org.async.rmi.net.ResponseFutureHolder;
import java.util.Iterator;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Created by Barak Bar Orion
* 11/2/14.
*/
public class PendingRequests {
private final ConcurrentLinkedQueue requests;
public PendingRequests() {
requests = new ConcurrentLinkedQueue<>();
}
public void add(ResponseFutureHolder responseFutureHolder) {
this.add(responseFutureHolder, System.currentTimeMillis());
}
/**
* Use for unit tests only.
*/
void add(ResponseFutureHolder responseFutureHolder, long currentTime) {
CompletableFuture future = responseFutureHolder.getResponseFuture();
PendingRequest pendingRequest = new PendingRequest(future, responseFutureHolder.getInvokeRequest(), currentTime);
requests.add(pendingRequest);
future.whenComplete((response, throwable) -> {
if (null == throwable || !(throwable instanceof TimeoutException)) {
requests.remove(pendingRequest);
}
});
}
/**
* Process the pending request and timeout all the unresolved request that are too old.
*/
public void process() {
process(System.currentTimeMillis());
}
void process(long currentTime) {
long timeout = Modules.getInstance().getConfiguration().getClientTimeout().asMilliseconds();
Iterator iterator = requests.iterator();
while (iterator.hasNext()) {
PendingRequest pendingRequest = iterator.next();
if (timeout <= currentTime - pendingRequest.requestTime) {
pendingRequest.future.completeExceptionally(new TimeoutException(String.valueOf(pendingRequest.getInvokeRequest())));
iterator.remove();
}else{
return;
}
}
}
/**
* Use for unit tests only.
*/
int size(){
return requests.size();
}
private static class PendingRequest {
public final CompletableFuture future;
private final InvokeRequest invokeRequest;
public final long requestTime;
public PendingRequest(CompletableFuture future, InvokeRequest invokeRequest, long requestTime) {
this.future = future;
this.invokeRequest = invokeRequest;
this.requestTime = requestTime;
}
public InvokeRequest getInvokeRequest() {
return invokeRequest;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PendingRequest that = (PendingRequest) o;
return requestTime == that.requestTime && future.equals(that.future);
}
@Override
public int hashCode() {
int result = future.hashCode();
result = 31 * result + (int) (requestTime ^ (requestTime >>> 32));
return result;
}
}
}