/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.dqp.internal.process;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import javax.resource.spi.work.Work;
import org.teiid.dqp.internal.process.DQPCore.CompletionListener;
import org.teiid.dqp.internal.process.ThreadReuseExecutor.PrioritizedRunnable;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
public final class FutureWork<T> extends FutureTask<T> implements PrioritizedRunnable, Work {
private int priority;
private long creationTime = System.currentTimeMillis();
private DQPWorkContext workContext = DQPWorkContext.getWorkContext();
private List<CompletionListener<T>> completionListeners = new LinkedList<CompletionListener<T>>();
private String parentName;
private String requestId;
public FutureWork(final Callable<T> processor, int priority) {
super(processor);
this.parentName = Thread.currentThread().getName();
this.priority = priority;
}
public FutureWork(final Runnable processor, T result, int priority) {
super(processor, result);
this.priority = priority;
}
public void setRequestId(String requestId) {
this.requestId = requestId;
}
@Override
public void run() {
LogManager.logDetail(LogConstants.CTX_DQP, "Running task for parent thread", parentName); //$NON-NLS-1$
LogManager.putMdc(RequestWorkItem.REQUEST_KEY, requestId);
try {
super.run();
} finally {
LogManager.removeMdc(RequestWorkItem.REQUEST_KEY);
}
}
@Override
public int getPriority() {
return priority;
}
@Override
public long getCreationTime() {
return creationTime;
}
@Override
public DQPWorkContext getDqpWorkContext() {
return workContext;
}
@Override
public void release() {
}
synchronized void addCompletionListener(CompletionListener<T> completionListener) {
if (this.isDone()) {
completionListener.onCompletion(this);
return;
}
this.completionListeners.add(completionListener);
}
@Override
protected synchronized void done() {
for (CompletionListener<T> listener : this.completionListeners) {
try {
listener.onCompletion(this);
} catch (Throwable t) {
LogManager.logError(LogConstants.CTX_DQP, t, "Uncaught throwable from completion listener"); //$NON-NLS-1$
}
}
completionListeners.clear();
}
}