in deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/DefaultFutureableStrategy.java [109:223]
public Object execute(final InvocationContext ic) throws Exception
{
final CallKey invocationKey;
if (IS_WELD1)
{
invocationKey = new CallKey(ic);
{ // weld1 workaround
final LinkedList<CallKey> stack = STACK.get();
if (!stack.isEmpty() && stack.getLast().equals(invocationKey))
{
try
{
return ic.proceed();
}
finally
{
if (stack.isEmpty())
{
STACK.remove();
}
}
}
}
}
else
{
invocationKey = null;
}
// validate usage
final Class<?> returnType = ic.getMethod().getReturnType();
if (!Future.class.isAssignableFrom(returnType) &&
!void.class.isAssignableFrom(returnType) &&
(COMPLETION_STAGE == null || !COMPLETION_STAGE.isAssignableFrom(returnType)))
{
throw new IllegalArgumentException("Return type should be a CompletableStage, Future or void");
}
if (configByMethod == null)
{
synchronized (this)
{
if (configByMethod == null)
{
configByMethod = new ConcurrentHashMap<Method, ExecutorService>();
}
}
}
// running < j8 we cant have cancellation
//final AtomicReference<Callable<?>> cancelHook = new AtomicReference<Callable<?>>();
final Callable<Object> invocation = new Callable<Object>()
{
@Override
public Object call() throws Exception
{
final LinkedList<CallKey> callStack;
if (IS_WELD1)
{
callStack = STACK.get();
callStack.add(invocationKey);
}
else
{
callStack = null;
}
try
{
final Object proceed = ic.proceed();
final Future<?> future = COMPLETION_STAGE == null || !COMPLETION_STAGE.isInstance(proceed) ?
Future.class.cast(proceed) :
Future.class.cast(COMPLETABLE_STAGE_TO_FUTURE.invoke(proceed));
return future.get();
}
catch (final InvocationTargetException e)
{
throw ExceptionUtils.throwAsRuntimeException(e.getCause());
}
catch (final Exception e)
{
throw ExceptionUtils.throwAsRuntimeException(e);
}
finally
{
if (IS_WELD1)
{
callStack.removeLast();
if (callStack.isEmpty())
{
STACK.remove();
}
}
}
}
};
final ExecutorService pool = getOrCreatePool(ic);
if (void.class.isAssignableFrom(returnType))
{
pool.submit(invocation);
return null;
}
if (COMPLETABLE_FUTURE == null) // not on java 8 can only be a future
{
return pool.submit(invocation);
}
// java 8, use CompletableFuture, it impl CompletionStage and Future so everyone is happy
final Object completableFuture = COMPLETABLE_FUTURE.newInstance();
pool.submit(new J8PromiseCompanionTask(completableFuture, invocation));
// TODO: handle cancel
return completableFuture;
}