Merge "Issue #2041 Improve exception handling for concurrent python. Change-Id: I36bf449af216feb45ea3a2464da5096f94d02d47" into development
Former-commit-id:725adab244
[formerly725adab244
[formerly 3d70e1866b618991ed0f8decb4925c794222c7ad]] Former-commit-id:4bfba7d6c6
Former-commit-id:07b1854308
This commit is contained in:
commit
27a4a99771
8 changed files with 181 additions and 29 deletions
|
@ -5,5 +5,6 @@ Bundle-SymbolicName: com.raytheon.uf.common.python.concurrent
|
||||||
Bundle-Version: 1.0.0.qualifier
|
Bundle-Version: 1.0.0.qualifier
|
||||||
Bundle-Vendor: RAYTHEON
|
Bundle-Vendor: RAYTHEON
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Require-Bundle: com.raytheon.uf.common.python;bundle-version="1.12.1174"
|
Require-Bundle: com.raytheon.uf.common.python;bundle-version="1.12.1174",
|
||||||
|
org.jep;bundle-version="1.0.0"
|
||||||
Export-Package: com.raytheon.uf.common.python.concurrent
|
Export-Package: com.raytheon.uf.common.python.concurrent
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.common.python.concurrent;
|
package com.raytheon.uf.common.python.concurrent;
|
||||||
|
|
||||||
|
import jep.JepException;
|
||||||
|
|
||||||
import com.raytheon.uf.common.python.PythonInterpreter;
|
import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,7 +34,9 @@ import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Feb 5, 2013 mnash Initial creation
|
* Feb 05, 2013 mnash Initial creation
|
||||||
|
* Jun 04, 2013 2041 bsteffen Improve exception handling for concurrent
|
||||||
|
* python.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -52,7 +56,7 @@ public abstract class AbstractPythonScriptFactory<P extends PythonInterpreter> {
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public abstract P createPythonScript();
|
public abstract P createPythonScript() throws JepException;
|
||||||
|
|
||||||
public AbstractPythonScriptFactory(String name, int maxThreads) {
|
public AbstractPythonScriptFactory(String name, int maxThreads) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.common.python.concurrent;
|
package com.raytheon.uf.common.python.concurrent;
|
||||||
|
|
||||||
|
import jep.JepException;
|
||||||
|
|
||||||
import com.raytheon.uf.common.python.PythonInterpreter;
|
import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,7 +33,9 @@ import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Feb 5, 2013 mnash Initial creation
|
* Feb 05, 2013 mnash Initial creation
|
||||||
|
* Jun 04, 2013 2041 bsteffen Improve exception handling for concurrent
|
||||||
|
* python.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -47,5 +51,5 @@ public interface IPythonExecutor<P extends PythonInterpreter, R extends Object>
|
||||||
* @param script
|
* @param script
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public abstract R execute(P script);
|
public abstract R execute(P script) throws JepException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ package com.raytheon.uf.common.python.concurrent;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import jep.JepException;
|
||||||
|
|
||||||
import com.raytheon.uf.common.python.PythonInterpreter;
|
import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,7 +34,9 @@ import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jan 31, 2013 mnash Initial creation
|
* Jan 31, 2013 mnash Initial creation
|
||||||
|
* Jun 04, 2013 2041 bsteffen Improve exception handling for concurrent
|
||||||
|
* python.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -69,17 +73,21 @@ public class PythonJob<P extends PythonInterpreter, R extends Object>
|
||||||
public R call() {
|
public R call() {
|
||||||
P script = threadPython.get();
|
P script = threadPython.get();
|
||||||
R result = null;
|
R result = null;
|
||||||
try {
|
if (listener == null) {
|
||||||
result = executor.execute(script);
|
try {
|
||||||
} catch (Throwable t) {
|
result = executor.execute(script);
|
||||||
if (listener != null) {
|
} catch (JepException e) {
|
||||||
listener.jobFailed(t);
|
throw new PythonJobFailedException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
result = executor.execute(script);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
listener.jobFailed(t);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fire listener to alert the original caller that we are done
|
// fire listener to alert the original caller that we are done
|
||||||
if (listener != null) {
|
|
||||||
listener.jobFinished(result);
|
listener.jobFinished(result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -26,6 +26,8 @@ import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import jep.JepException;
|
||||||
|
|
||||||
import com.raytheon.uf.common.python.PythonInterpreter;
|
import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +45,7 @@ import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
* IPythonExecutor<PythonInterpreter, Object> executor = new CAVEExecutor(
|
* IPythonExecutor<PythonInterpreter, Object> executor = new CAVEExecutor(
|
||||||
* args);
|
* args);
|
||||||
* try {
|
* try {
|
||||||
* coordinator.submitJob(executor, listener);
|
* coordinator.submitAsyncJob(executor, listener);
|
||||||
* } catch (Exception e) {
|
* } catch (Exception e) {
|
||||||
* e.printStackTrace();
|
* e.printStackTrace();
|
||||||
* }
|
* }
|
||||||
|
@ -54,7 +56,9 @@ import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jan 31, 2013 mnash Initial creation
|
* Jan 31, 2013 mnash Initial creation
|
||||||
|
* Jun 04, 2013 2041 bsteffen Improve exception handling for concurrent
|
||||||
|
* python.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -70,13 +74,17 @@ public class PythonJobCoordinator<P extends PythonInterpreter> {
|
||||||
private static Map<String, PythonJobCoordinator<? extends PythonInterpreter>> pools = new ConcurrentHashMap<String, PythonJobCoordinator<? extends PythonInterpreter>>();
|
private static Map<String, PythonJobCoordinator<? extends PythonInterpreter>> pools = new ConcurrentHashMap<String, PythonJobCoordinator<? extends PythonInterpreter>>();
|
||||||
|
|
||||||
private PythonJobCoordinator(final AbstractPythonScriptFactory<P> factory) {
|
private PythonJobCoordinator(final AbstractPythonScriptFactory<P> factory) {
|
||||||
execService = Executors.newFixedThreadPool(factory.getMaxThreads(),
|
|
||||||
new PythonThreadFactory(factory.getName()));
|
|
||||||
threadLocal = new ThreadLocal<P>() {
|
threadLocal = new ThreadLocal<P>() {
|
||||||
protected P initialValue() {
|
protected P initialValue() {
|
||||||
return factory.createPythonScript();
|
try {
|
||||||
|
return factory.createPythonScript();
|
||||||
|
} catch (JepException e) {
|
||||||
|
throw new ScriptCreationException(e);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
execService = Executors.newFixedThreadPool(factory.getMaxThreads(),
|
||||||
|
new PythonThreadFactory(threadLocal, factory.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,11 +93,11 @@ public class PythonJobCoordinator<P extends PythonInterpreter> {
|
||||||
* @param name
|
* @param name
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static PythonJobCoordinator<? extends PythonInterpreter> getInstance(
|
public static <S extends PythonInterpreter> PythonJobCoordinator<S> getInstance(
|
||||||
String name) {
|
String name) {
|
||||||
synchronized (pools) {
|
synchronized (pools) {
|
||||||
if (pools.containsKey(name)) {
|
if (pools.containsKey(name)) {
|
||||||
return pools.get(name);
|
return (PythonJobCoordinator<S>) pools.get(name);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"Unable to find instance of PythonJobCoordinator named "
|
"Unable to find instance of PythonJobCoordinator named "
|
||||||
|
@ -167,10 +175,11 @@ public class PythonJobCoordinator<P extends PythonInterpreter> {
|
||||||
*
|
*
|
||||||
* @param name
|
* @param name
|
||||||
*/
|
*/
|
||||||
public void shutdownCoordinator(String name) {
|
public void shutdown() {
|
||||||
/*
|
synchronized (pools) {
|
||||||
* TODO need to add for future functionality
|
pools.remove(this);
|
||||||
*/
|
}
|
||||||
|
execService.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.python.concurrent;
|
||||||
|
|
||||||
|
import jep.JepException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception is thrown by the PythonJobCoordinator when the
|
||||||
|
* AbstractPythonScriptFactory fails to execute a Job.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jun 04, 2013 2041 bsteffen Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bsteffen
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PythonJobFailedException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -6716989387583873621L;
|
||||||
|
|
||||||
|
public PythonJobFailedException(JepException cause) {
|
||||||
|
super(cause.getMessage(), cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,6 +22,8 @@ package com.raytheon.uf.common.python.concurrent;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.python.PythonInterpreter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new threads named according to what python task they were created
|
* Creates new threads named according to what python task they were created
|
||||||
* for. Based nearly identically off of {@link ThreadFactory}
|
* for. Based nearly identically off of {@link ThreadFactory}
|
||||||
|
@ -32,7 +34,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jan 31, 2013 mnash Initial creation
|
* Jan 31, 2013 mnash Initial creation
|
||||||
|
* Jun 04, 2013 2041 bsteffen Improve exception handling for concurrent
|
||||||
|
* python.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -49,7 +53,11 @@ public class PythonThreadFactory implements ThreadFactory {
|
||||||
|
|
||||||
private final String namePrefix;
|
private final String namePrefix;
|
||||||
|
|
||||||
public PythonThreadFactory(String name) {
|
private final ThreadLocal<? extends PythonInterpreter> threadLocal;
|
||||||
|
|
||||||
|
public PythonThreadFactory(
|
||||||
|
ThreadLocal<? extends PythonInterpreter> threadLocal, String name) {
|
||||||
|
this.threadLocal = threadLocal;
|
||||||
SecurityManager s = System.getSecurityManager();
|
SecurityManager s = System.getSecurityManager();
|
||||||
group = (s != null) ? s.getThreadGroup() : Thread.currentThread()
|
group = (s != null) ? s.getThreadGroup() : Thread.currentThread()
|
||||||
.getThreadGroup();
|
.getThreadGroup();
|
||||||
|
@ -58,7 +66,7 @@ public class PythonThreadFactory implements ThreadFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Thread newThread(Runnable r) {
|
public Thread newThread(Runnable r) {
|
||||||
Thread t = new Thread(group, r, namePrefix
|
Thread t = new PythonThread(group, r, namePrefix
|
||||||
+ threadNumber.getAndIncrement(), 0);
|
+ threadNumber.getAndIncrement(), 0);
|
||||||
if (t.isDaemon()) {
|
if (t.isDaemon()) {
|
||||||
t.setDaemon(false);
|
t.setDaemon(false);
|
||||||
|
@ -68,4 +76,22 @@ public class PythonThreadFactory implements ThreadFactory {
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class PythonThread extends Thread {
|
||||||
|
|
||||||
|
public PythonThread(ThreadGroup group, Runnable target, String name,
|
||||||
|
long stackSize) {
|
||||||
|
super(group, target, name, stackSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
super.run();
|
||||||
|
} finally {
|
||||||
|
threadLocal.get().dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.python.concurrent;
|
||||||
|
|
||||||
|
import jep.JepException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception is thrown by the PythonJobCoordinator when a
|
||||||
|
* AbstractPythonScriptFactory has Jep problems.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jun 04, 2013 2041 bsteffen Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bsteffen
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ScriptCreationException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 6443312895295667778L;
|
||||||
|
|
||||||
|
public ScriptCreationException(JepException cause) {
|
||||||
|
super(cause.getMessage(), cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue