
goja.core.libs.Promise Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2013-2014 sagyf Yang. The Four Group.
*/
package goja.core.libs;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* .
*
* @author sagyf yang
* @version 1.0 2014-09-11 13:19
* @since JDK 1.6
*/
@SuppressWarnings("unchecked")
public class Promise implements Future, Action {
final CountDownLatch taskLock = new CountDownLatch(1);
boolean invoked = false;
List>> callbacks = Lists.newArrayList();
V result = null;
Throwable exception = null;
public static Promise> waitAll(final Promise... promises) {
return waitAll(Arrays.asList(promises));
}
public static Promise> waitAll(final Collection> promises) {
final CountDownLatch waitAllLock = new CountDownLatch(promises.size());
final Promise> result = new Promise>() {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
boolean r = true;
for (Promise f : promises) {
r = r & f.cancel(mayInterruptIfRunning);
}
return r;
}
@Override
public boolean isCancelled() {
boolean r = true;
for (Promise f : promises) {
r = r & f.isCancelled();
}
return r;
}
@Override
public boolean isDone() {
boolean r = true;
for (Promise f : promises) {
r = r & f.isDone();
}
return r;
}
@Override
public List get() throws InterruptedException, ExecutionException {
waitAllLock.await();
List r = new ArrayList();
for (Promise f : promises) {
r.add(f.get());
}
return r;
}
@Override
public List get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
waitAllLock.await(timeout, unit);
return get();
}
};
final Action> action = new Action>() {
public void invoke(Promise completed) {
waitAllLock.countDown();
if (waitAllLock.getCount() == 0) {
try {
result.invoke(result.get());
} catch (Exception e) {
result.invokeWithException(e);
}
}
}
};
for (Promise f : promises) {
f.onRedeem(action);
}
if (promises.isEmpty()) {
result.invoke(Collections.emptyList());
}
return result;
}
public static Promise waitAny(final Promise... futures) {
final Promise result = new Promise();
final Action> action = new Action>() {
public void invoke(Promise completed) {
synchronized (this) {
if (result.isDone()) {
return;
}
}
T resultOrNull = completed.getOrNull();
if (resultOrNull != null) {
result.invoke(resultOrNull);
} else {
result.invokeWithException(completed.exception);
}
}
};
for (Promise f : futures) {
f.onRedeem(action);
}
return result;
}
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
public boolean isCancelled() {
return false;
}
public boolean isDone() {
return invoked;
}
public V getOrNull() {
return result;
}
public V get() throws InterruptedException, ExecutionException {
taskLock.await();
if (exception != null) {
// The result of the promise is an exception - throw it
throw new ExecutionException(exception);
}
return result;
}
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
taskLock.await(timeout, unit);
if (exception != null) {
// The result of the promise is an exception - throw it
throw new ExecutionException(exception);
}
return result;
}
public void invoke(V result) {
invokeWithResultOrException(result, null);
}
public void invokeWithException(Throwable t) {
invokeWithResultOrException(null, t);
}
protected void invokeWithResultOrException(V result, Throwable t) {
synchronized (this) {
if (!invoked) {
invoked = true;
this.result = result;
this.exception = t;
taskLock.countDown();
} else {
return;
}
}
for (Action> callback : callbacks) {
callback.invoke(this);
}
}
public void onRedeem(Action> callback) {
synchronized (this) {
if (!invoked) {
callbacks.add(callback);
}
}
if (invoked) {
callback.invoke(this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy