Revision: 18181
http://sourceforge.net/p/gate/code/18181
Author: markagreenwood
Date: 2014-07-14 18:09:01 +0000 (Mon, 14 Jul 2014)
Log Message:
-----------
it is now possible to start a process and keep feeding data to stdin, which
should allow you to keep using a process over numerous execute calls for a
single PR, which when a tool loads a large model should be a serious time gain
-- needs proper testing though, but fortunately I know just the man for the job
:)
Modified Paths:
--------------
gate/trunk/src/main/gate/util/ProcessManager.java
Modified: gate/trunk/src/main/gate/util/ProcessManager.java
===================================================================
--- gate/trunk/src/main/gate/util/ProcessManager.java 2014-07-14 01:19:32 UTC
(rev 18180)
+++ gate/trunk/src/main/gate/util/ProcessManager.java 2014-07-14 18:09:01 UTC
(rev 18181)
@@ -1,7 +1,10 @@
package gate.util;
-import java.io.*;
-import gate.util.GateRuntimeException;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
/**
* Class that supports running an external process and either silently
@@ -30,6 +33,8 @@
* StreamGobbler thread for standard error.
*/
private StreamGobbler stderr;
+
+ private Process proc;
/**
* Construct a ProcessManager object and start the gobbler threads.
@@ -45,8 +50,110 @@
t.setDaemon(true);
t.start();
}
+
+ public synchronized boolean isProcessRunning() {
+ if (proc == null) return false;
+
+ try {
+ proc.exitValue();
+ return false;
+ }
+ catch (IllegalThreadStateException e) {
+ return true;
+ }
+ }
+
+ /**
+ * If a process is currently running then this method destroys it so
+ * that the ProcessManager instance can be used to start another
+ * process
+ */
+ public synchronized void destroyProcess() throws IOException {
+ if(isProcessRunning()) proc.destroy();
+ // wait for the gobblers to finish their jobs
+ while(!stderr.isDone() || !stdout.isDone()) {
+ try {
+ if(DEBUG) {
+ System.err.println("Gobblers not done, waiting...");
+ }
+ this.wait();
+ } catch(InterruptedException ie) {
+ // if interrupted, try waiting again
+ }
+ }
+
+ // make it really obvious the process has finished
+ proc = null;
+
+ // reset the gobblers
+ if(DEBUG) {
+ System.err.println("Gobblers done - resetting");
+ }
+ stdout.reset();
+ stderr.reset();
+
+ // if there was an exception during running, throw that
+ Exception ex = null;
+ if(stdout.hasException()) {
+ ex = stdout.getException();
+ stderr.getException(); // to reset exception cache
+ } else if(stderr.hasException()) {
+ ex = stderr.getException();
+ }
+
+ if(ex != null) {
+ if(DEBUG) {
+ System.err.println("Rethrowing exception");
+ }
+ if(ex instanceof IOException) {
+ throw (IOException)ex;
+ } else if(ex instanceof RuntimeException) {
+ throw (RuntimeException)ex;
+ } else throw new GateRuntimeException(ex);
+ }
+ }
+
/**
+ * Sometimes you want to start an external process and pass data to it
+ * at different intervals. A good example is a tool with large startup
+ * time where you can feed it one sentence at a time and get a
+ * response. If you keep the process running you can use it over
+ * multiple documents.
+ */
+ public synchronized OutputStream startProcess(String[] argv, File dir,
+ OutputStream out, OutputStream err) throws IOException {
+
+ if(isProcessRunning())
+ throw new IOException("The previous process is still running");
+
+ // Start the process. This may throw an exception
+ if(DEBUG) {
+ System.err.println("Starting process");
+ }
+
+ proc = Runtime.getRuntime().exec(argv, null, dir);
+
+ // set up the stream gobblers for stdout and stderr
+ if(DEBUG) {
+ System.err.println("Configuring gobblers");
+ }
+ stdout.setInputStream(proc.getInputStream());
+ stdout.setOutputStream(out);
+
+ stderr.setInputStream(proc.getErrorStream());
+ stderr.setOutputStream(err);
+
+ // start the gobblers
+ if(DEBUG) {
+ System.err.println("Waking up gobblers");
+ }
+ this.notifyAll();
+
+ return proc.getOutputStream();
+ }
+
+ /**
* Run the given external process. If an exception results from starting the
* process, or while reading the output from the process, it will be thrown.
* Otherwise, the exit value from the process is returned.
@@ -76,13 +183,16 @@
*/
public synchronized int runProcess(String[] argv, File dir, OutputStream
out, OutputStream err)
throws IOException {
- // Start the process. This may throw an exception
+
+ if (isProcessRunning()) throw new IOException("The previous process is
still running");
+
+ // Start the process. This may throw an exception
if(DEBUG) {
System.err.println("Starting process");
}
- Process proc = Runtime.getRuntime().exec(argv, null, dir);
-
+ proc = Runtime.getRuntime().exec(argv, null, dir);
+
// set up the stream gobblers for stdout and stderr
if(DEBUG) {
System.err.println("Configuring gobblers");
@@ -123,6 +233,9 @@
}
}
+ // make it really obvious the process has finished
+ proc = null;
+
// reset the gobblers
if(DEBUG) {
System.err.println("Gobblers done - resetting");
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Want fast and easy access to all the code in your enterprise? Index and
search up to 200,000 lines of code with a free copy of Black Duck®
Code Sight™ - the same software that powers the world's largest code
search on Ohloh, the Black Duck Open Hub! Try it now.
http://p.sf.net/sfu/bds
_______________________________________________
GATE-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gate-cvs