com.tapstream.sdk.SettableApiFuture Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tapstream-core Show documentation
Show all versions of tapstream-core Show documentation
This library contains the building blocks for a Tapstream Java SDK
package com.tapstream.sdk;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class SettableApiFuture implements ApiFuture {
T obj;
Throwable error;
Callback callback;
Future> propagateCancellationTo;
int state = STATE_INITIAL;
private static final int STATE_INITIAL = 0;
private static final int STATE_CANCELLED = 1;
private static final int STATE_DONE = 2;
private static final int STATE_ERROR = 3;
@Override
synchronized public boolean cancel(boolean mayInterruptIfRunning) {
if (state != STATE_INITIAL)
return false;
state = STATE_CANCELLED;
if (propagateCancellationTo != null)
propagateCancellationTo.cancel(mayInterruptIfRunning);
this.notifyAll();
return true;
}
synchronized public boolean isError() {
return state == STATE_ERROR;
}
@Override
synchronized public boolean isCancelled() {
return state == STATE_CANCELLED;
}
@Override
synchronized public boolean isDone() {
return state == STATE_CANCELLED
|| state == STATE_DONE
|| state == STATE_ERROR;
}
synchronized public boolean set(T obj){
if (state != STATE_INITIAL)
return false;
state = STATE_DONE;
this.obj = obj;
this.notifyAll();
safeCallbackSuccess(callback, obj);
return true;
}
synchronized public boolean setException(Throwable t){
if (state != STATE_INITIAL)
return false;
state = STATE_ERROR;
this.error = t;
this.notifyAll();
safeCallbackError(callback, t);
return true;
}
synchronized public void propagateCancellationTo(Future> future){
this.propagateCancellationTo = future;
}
private static void safeCallbackSuccess(Callback callback, T obj){
if (callback != null){
try {
callback.success(obj);
} catch (Exception e){
Logging.log(Logging.WARN, "Failed to execute callback success: " + e.toString());
}
}
}
private static void safeCallbackError(Callback callback, Throwable error){
if (callback != null){
try {
callback.error(error);
} catch (Exception e){
Logging.log(Logging.WARN, "Failed to execute callback error: " + e.toString());
}
}
}
@Override
synchronized public void setCallback(Callback callback){
switch (state) {
case STATE_INITIAL:
this.callback = callback;
break;
case STATE_ERROR:
safeCallbackError(callback, error);
break;
case STATE_DONE:
safeCallbackSuccess(callback, obj);
break;
case STATE_CANCELLED:
safeCallbackError(callback, new CancellationException());
break;
}
}
@Override
synchronized public T get() throws InterruptedException, ExecutionException {
while (true) {
switch (state) {
case STATE_DONE:
return obj;
case STATE_ERROR:
throw new ExecutionException(error);
case STATE_CANCELLED:
throw new CancellationException();
default:
this.wait();
}
}
}
@Override
synchronized public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
long start = System.currentTimeMillis();
long timeoutMillis = unit.toMillis(timeout);
while (true) {
switch (state) {
case STATE_DONE:
return obj;
case STATE_ERROR:
throw new ExecutionException(error);
case STATE_CANCELLED:
throw new CancellationException();
default:
long timeDelta = System.currentTimeMillis() - start;
long timeRemaining = timeoutMillis - timeDelta;
if (timeRemaining > 0){
this.wait(timeRemaining);
} else {
throw new TimeoutException();
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy