static int runGnuplot(final HttpQuery query,
                        final String basepath,
                        final Plot plot) throws IOException {
    final int nplotted = plot.dumpToFiles(basepath);
    final long start_time = System.nanoTime();
    final Process gnuplot = new ProcessBuilder(GNUPLOT,
      basepath + ".out", basepath + ".err", basepath + ".gnuplot").start();
    final int rv;
    try {
      rv = gnuplot.waitFor();  // Couldn't find how to do this asynchronously.
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();  // Restore the interrupted status.
      throw new IOException("interrupted", e);  // I hate checked exceptions.
    } finally {
      // We need to always destroy() the Process, otherwise we "leak" file
      // descriptors and pipes.  Unless I'm blind, this isn't actually
      // documented in the Javadoc of the !@#$%^ JDK, and in Java 6 there's no
      // way to ask the stupid-ass ProcessBuilder to not create fucking pipes.
      // I think when the GC kicks in the JVM may run some kind of a finalizer
      // that closes the pipes, because I've never seen this issue on long
      // running TSDs, except where ulimit -n was low (the default, 1024).
      gnuplot.destroy();
    }
    gnuplotlatency.add((int) ((System.nanoTime() - start_time) / 1000000));
    if (rv != 0) {
      final byte[] stderr = readFile(query, new File(basepath + ".err"),
                                     4096);
      // Sometimes Gnuplot will error out but still create the file.
      new File(basepath + ".png").delete();
      if (stderr == null) {
        throw new GnuplotException(rv);
      }
      throw new GnuplotException(new String(stderr));
    }
    // Remove the files for stderr/stdout if they're empty.
    deleteFileIfEmpty(basepath + ".out");
    deleteFileIfEmpty(basepath + ".err");
    return nplotted;
  }
static int runGnuplot ( final HttpQuery query , final String basepath , final Plot plot ) throws IOException { final int nplotted = plot . dumpToFiles ( basepath ) ; final long start_time = System . nanoTime ( ) ; final Process gnuplot = new ProcessBuilder ( GNUPLOT , basepath + ".out" , basepath + ".err" , basepath + ".gnuplot" ) . start ( ) ; final int rv ; try { rv = gnuplot . waitFor ( ) ; } catch ( InterruptedException e ) { Thread . currentThread ( ) . interrupt ( ) ; throw new IOException ( "interrupted" , e ) ; } finally { gnuplot . destroy ( ) ; } gnuplotlatency . add ( ( int ) ( ( System . nanoTime ( ) - start_time ) / 1000000 ) ) ; if ( rv != 0 ) { final byte [ ] stderr = readFile ( query , new File ( basepath + ".err" ) , 4096 ) ; new File ( basepath + ".png" ) . delete ( ) ; if ( stderr == null ) { throw new GnuplotException ( rv ) ; } throw new GnuplotException ( new String ( stderr ) ) ; } deleteFileIfEmpty ( basepath + ".out" ) ; deleteFileIfEmpty ( basepath + ".err" ) ; return nplotted ; }
Runs Gnuplot in a subprocess to generate the graph.
<strong>This function will block</strong> while Gnuplot is running.
@param query The query being handled (for logging purposes).
@param basepath The base path used for the Gnuplot files.
@param plot The plot object to generate Gnuplot's input files.
@return The number of points plotted by Gnuplot (0 or more).
@throws IOException if the Gnuplot files can't be written, or
the Gnuplot subprocess fails to start, or we can't read the
graph from the file it produces, or if we have been interrupted.
@throws GnuplotException if Gnuplot returns non-zero.