org.wisdom.executors.Task Maven / Gradle / Ivy
/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2015 Wisdom Framework
* %%
* 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.
* #L%
*/
package org.wisdom.executors;
import com.google.common.util.concurrent.*;
import org.wisdom.api.concurrent.ExecutionContext;
import org.wisdom.api.concurrent.ManagedFutureTask;
import java.util.concurrent.*;
/**
* Implementation of {@link org.wisdom.api.concurrent.ManagedFutureTask} to be
* used with {@link org.wisdom.executors.ManagedExecutorServiceImpl}.
*
* @param the type of the result computed by the task. {@link Void} for task not computing a result.
*/
public class Task extends FutureTask implements ListenableFuture, ManagedFutureTask {
private final ListeningExecutorService executor;
private final ExecutionContext executionContext;
protected final Callable callable;
protected ListenableFuture future;
private Throwable taskRunThrowable;
private final AbstractManagedExecutorService parent;
protected long submissionDate;
private long startDate;
private long completionDate;
private long hungTime;
protected Task(
ListeningExecutorService executor,
Runnable runnable,
V result,
ExecutionContext executionContext,
long hungTime,
AbstractManagedExecutorService parent) {
super(runnable, result);
this.callable = new EnhancedCallable(Executors.callable(runnable, result));
this.executor = executor;
this.executionContext = executionContext;
this.hungTime = hungTime;
this.parent = parent;
}
/**
* Creates a task.
*
* @param executor the executor service
* @param callable the callable object
* @param executionContext the execution context used to execute the task
* @param hungTime the hung time for the executor service
* @param parent the {@link AbstractManagedExecutorService} having created this task
*/
public Task(
ListeningExecutorService executor,
Callable callable,
ExecutionContext executionContext,
long hungTime,
AbstractManagedExecutorService parent) {
super(callable);
this.callable = new EnhancedCallable(callable);
this.executor = executor;
this.executionContext = executionContext;
this.hungTime = hungTime;
this.parent = parent;
}
protected Task execute() {
ListenableFuture future = executor.submit(callable);
submitted(future);
return this;
}
protected Task submitted(Future future) {
this.submissionDate = System.currentTimeMillis();
this.future = JdkFutureAdapters.listenInPoolThread(future);
return this;
}
/**
* Registers a listener on this task. The listener is invoked when the task is completed. The listener is executed
* the same executor as the task.
*
* @param listener the listener.
*/
public void addListener(Runnable listener) {
addListener(listener, executor);
}
@Override
public void addListener(Runnable listener, Executor exec) {
this.future.addListener(listener, exec);
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return this.future != null && this.future.cancel(mayInterruptIfRunning);
}
@Override
public V get() throws InterruptedException, ExecutionException {
return this.future.get();
}
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException, ExecutionException {
return this.future.get(timeout, unit);
}
@Override
public boolean isCancelled() {
return this.future.isCancelled();
}
@Override
public boolean isDone() {
return this.future.isDone();
}
/**
* @return the {@link Throwable} object that could have been thrown while executing this task. {@code null} if
* the task execution succeed.
*/
public Throwable cause() {
return taskRunThrowable;
}
@Override
protected void setException(Throwable throwable) {
taskRunThrowable = throwable;
}
@Override
public Task onSuccess(final SuccessCallback callback, Executor executor) {
Futures.addCallback(future, new FutureCallback() {
@Override
public void onSuccess(V v) {
callback.onSuccess(Task.this, v);
}
@Override
public void onFailure(Throwable throwable) {
// Do nothing.
}
}, executor);
return this;
}
@Override
public Task onSuccess(final SuccessCallback callback) {
return onSuccess(callback, executor);
}
@Override
public Task onFailure(final FailureCallback callback, Executor executor) {
Futures.addCallback(future, new FutureCallback() {
@Override
public void onSuccess(V v) {
// Do nothing
}
@Override
public void onFailure(Throwable throwable) {
callback.onFailure(Task.this, throwable);
}
}, executor);
return this;
}
@Override
public Task onFailure(final FailureCallback callback) {
return onFailure(callback, executor);
}
@Override
public boolean isTaskHang() {
// The task was completed.
return completionDate == 0 && System.currentTimeMillis() - submissionDate >= hungTime;
}
@Override
public boolean isShutdown() {
return executor.isShutdown();
}
@Override
public long getTaskStartTime() {
return startDate;
}
@Override
public long getTaskCompletionTime() {
return completionDate;
}
@Override
public long getTaskRunTime() {
if (startDate == 0) {
return 0;
}
if (completionDate == 0) {
return System.currentTimeMillis() - startDate;
}
return completionDate - startDate;
}
@Override
public long getHungTaskThreshold() {
return hungTime;
}
@Override
public ExecutionContext getExecutionContext() {
return executionContext;
}
class EnhancedCallable implements Callable {
private final Callable delegate;
private EnhancedCallable(Callable delegate) {
this.delegate = delegate;
}
@Override
public V call() throws Exception {
try {
if (executionContext != null) {
executionContext.apply();
}
startDate = System.currentTimeMillis();
return delegate.call();
} catch (Throwable e) { //NOSONAR
// We set the exception in the task.
setException(e);
throw e;
} finally {
completionDate = System.currentTimeMillis();
if (executionContext != null) {
executionContext.unapply();
}
parent.addToStatistics(Task.this);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy