javascalautils.concurrent.ExecutorImpl Maven / Gradle / Ivy
/**
* Copyright 2015 Peter Nerg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package javascalautils.concurrent;
import static javascalautils.concurrent.PromiseCompanion.Promise;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
/**
* Implements the executor interface.
* Internally uses a Java concurrent executor to provide the thread execution mechanism.
*
* @author Peter Nerg
* @since 1.2
*/
final class ExecutorImpl implements Executor {
/** The internal Java concurrent executor to perform the actual work. */
private final java.util.concurrent.Executor executor;
/**
* Creates an instance using the provided SDK {@link java.util.concurrent.Executor} for thread management.
*
* @param executor
* @since 1.2
*/
ExecutorImpl(java.util.concurrent.Executor executor) {
this.executor = executor;
}
/*
* (non-Javadoc)
*
* @see com.ericsson.concurrent.Executor#execute(com.ericsson.concurrent.Executable)
*/
@Override
public Future execute(final Executable executable) {
final Promise promise = Promise();
return execute(promise, () -> {
try {
executable.execute(promise);
// if the implementation didn't respond to the Promise we mark it as a failure.
if (!promise.isCompleted()) {
promise.failure(new IllegalStateException("No response was provided by the Promise"));
}
} catch (Exception ex) {
promise.failure(ex);
}
});
}
/*
* (non-Javadoc)
*
* @see com.ericsson.concurrent.Executor#execute(java.util.concurrent.Callable)
*/
@Override
public Future execute(final Callable callable) {
final Promise promise = Promise();
return execute(promise, () -> {
try {
promise.success(callable.call());
} catch (Exception ex) {
promise.failure(ex);
}
});
}
/*
* (non-Javadoc)
*
* @see com.ericsson.concurrent.Executor#executeAll(com.ericsson.concurrent.Executable[])
*/
@Override
public List> executeAll(@SuppressWarnings("unchecked") Executable... executables) {
List> responses = new ArrayList>();
for (Executable executable : executables) {
responses.add(execute(executable));
}
return responses;
}
/*
* (non-Javadoc)
*
* @see com.ericsson.concurrent.Executor#executeAll(java.util.concurrent.Callable[])
*/
@Override
public List> executeAll(@SuppressWarnings("unchecked") Callable... callables) {
List> responses = new ArrayList>();
for (Callable callable : callables) {
responses.add(execute(callable));
}
return responses;
}
/**
* Executes the provided {@link Runnable} on the internal executor.
* Any issues related to the internal executor are reported to the provided {@link Promise}
*
* @param promise
* The promise to fulfill once the work is finished
* @param runnable
* The runnable to execute in the executor
* @return The Future holding the response-to-be
*/
private Future execute(Promise promise, Runnable runnable) {
try {
executor.execute(runnable);
} catch (RejectedExecutionException ex) {
// could be rejected due to resource starvation, report a failure
promise.failure(ex);
}
return promise.future();
}
/*
* (non-Javadoc)
*
* @see com.ericsson.concurrent.Executor#shutdown()
*/
@Override
public void shutdown() {
if (executor instanceof ExecutorService) {
((ExecutorService) executor).shutdown();
}
}
/*
* (non-Javadoc)
*
* @see com.ericsson.concurrent.Executor#awaitTermination(long, java.util.concurrent.TimeUnit)
*/
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
if (executor instanceof ExecutorService) {
return ((ExecutorService) executor).awaitTermination(timeout, unit);
}
return true;
}
}