Class ExecuteWatchdog

  • All Implemented Interfaces:
    java.util.function.Consumer<Watchdog>, TimeoutObserver

    public class ExecuteWatchdog
    extends java.lang.Object
    implements TimeoutObserver
    Destroys a process running for too long. For example:
     ExecuteWatchdog watchdog = ExecuteWatchdog.builder().setTimeout(Duration.ofSeconds(30)).get();
     Executor executor = DefaultExecutor.builder().setExecuteStreamHandler(new PumpStreamHandler()).get();
     executor.setWatchdog(watchdog);
     int exitValue = executor.execute(myCommandLine);
     if (executor.isFailure(exitValue) && watchdog.killedProcess()) {
         // it was killed on purpose by the watchdog
     }
     

    When starting an asynchronous process than 'ExecuteWatchdog' is the keeper of the process handle. In some cases it is useful not to define a timeout (and pass INFINITE_TIMEOUT_DURATION) and to kill the process explicitly using destroyProcess().

    Please note that ExecuteWatchdog is processed asynchronously, e.g. it might be still attached to a process even after the DefaultExecutor.execute(CommandLine) or a variation has returned.

    See Also:
    Executor, Watchdog
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  ExecuteWatchdog.Builder
      Builds ExecuteWatchdog instances.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.lang.Exception caught
      Exception that might be thrown during the process execution.
      private boolean hasWatchdog
      Is a user-supplied timeout in use.
      static long INFINITE_TIMEOUT
      The marker for an infinite timeout.
      static java.time.Duration INFINITE_TIMEOUT_DURATION
      The marker for an infinite timeout.
      private boolean killedProcess
      Say whether the process was killed due to running overtime.
      private java.lang.Process process
      The process to execute and watch for duration.
      private boolean processStarted
      Indicates that the process is verified as started
      private java.util.concurrent.ThreadFactory threadFactory
      The thread factory.
      private boolean watch
      Say whether the watchdog is currently monitoring a process.
      private Watchdog watchdog
      Will tell us whether timeout has occurred.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static ExecuteWatchdog.Builder builder()
      Creates a new builder.
      void checkException()
      This method will rethrow the exception that was possibly caught during the run of the process.
      protected void cleanUp()
      Resets the monitor flag and the process.
      void destroyProcess()
      Destroys the running process manually.
      private void ensureStarted()
      Ensures that the process is started or not already terminated so we do not race with asynch executionor hang forever.
      void failedToStart​(java.lang.Exception e)
      Notification that starting the process failed.
      (package private) Watchdog getWatchdog()
      Gets the watchdog.
      boolean isWatching()
      Tests whether the watchdog is still monitoring the process.
      boolean killedProcess()
      Tests whether the last process run was killed.
      (package private) void setProcessNotStarted()  
      void start​(java.lang.Process processToMonitor)
      Watches the given process and terminates it, if it runs for too long.
      void stop()
      Stops the watcher.
      void timeoutOccured​(Watchdog w)
      Called after watchdog has finished.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
      • Methods inherited from interface java.util.function.Consumer

        andThen
    • Field Detail

      • INFINITE_TIMEOUT

        public static final long INFINITE_TIMEOUT
        The marker for an infinite timeout.
        See Also:
        Constant Field Values
      • INFINITE_TIMEOUT_DURATION

        public static final java.time.Duration INFINITE_TIMEOUT_DURATION
        The marker for an infinite timeout.
      • caught

        private java.lang.Exception caught
        Exception that might be thrown during the process execution.
      • hasWatchdog

        private final boolean hasWatchdog
        Is a user-supplied timeout in use.
      • killedProcess

        private boolean killedProcess
        Say whether the process was killed due to running overtime.
      • process

        private java.lang.Process process
        The process to execute and watch for duration.
      • processStarted

        private volatile boolean processStarted
        Indicates that the process is verified as started
      • threadFactory

        private final java.util.concurrent.ThreadFactory threadFactory
        The thread factory.
      • watch

        private boolean watch
        Say whether the watchdog is currently monitoring a process.
      • watchdog

        private final Watchdog watchdog
        Will tell us whether timeout has occurred.
    • Constructor Detail

      • ExecuteWatchdog

        private ExecuteWatchdog​(ExecuteWatchdog.Builder builder)
        Creates a new watchdog with a given timeout.
        Parameters:
        threadFactory - the thread factory.
        timeout - the timeout Duration for the process. It must be greater than 0 or INFINITE_TIMEOUT_DURATION.
      • ExecuteWatchdog

        @Deprecated
        public ExecuteWatchdog​(long timeoutMillis)
        Creates a new watchdog with a given timeout.
        Parameters:
        timeoutMillis - the timeout for the process in milliseconds. It must be greater than 0 or INFINITE_TIMEOUT.
    • Method Detail

      • builder

        public static ExecuteWatchdog.Builder builder()
        Creates a new builder.
        Returns:
        a new builder.
        Since:
        1.4.0
      • checkException

        public void checkException()
                            throws java.lang.Exception
        This method will rethrow the exception that was possibly caught during the run of the process. It will only remain valid once the process has been terminated either by 'error', timeout or manual intervention. Information will be discarded once a new process is run.
        Throws:
        java.lang.Exception - a wrapped exception over the one that was silently swallowed and stored during the process run.
      • cleanUp

        protected void cleanUp()
        Resets the monitor flag and the process.
      • destroyProcess

        public void destroyProcess()
        Destroys the running process manually.
      • ensureStarted

        private void ensureStarted()
        Ensures that the process is started or not already terminated so we do not race with asynch executionor hang forever. The caller of this method must be holding the lock on this.
      • failedToStart

        public void failedToStart​(java.lang.Exception e)
        Notification that starting the process failed.
        Parameters:
        e - the offending exception.
      • getWatchdog

        Watchdog getWatchdog()
        Gets the watchdog.
        Returns:
        the watchdog.
      • isWatching

        public boolean isWatching()
        Tests whether the watchdog is still monitoring the process.
        Returns:
        true if the process is still running, otherwise false.
      • killedProcess

        public boolean killedProcess()
        Tests whether the last process run was killed.
        Returns:
        true if the process was killed false.
      • setProcessNotStarted

        void setProcessNotStarted()
      • start

        public void start​(java.lang.Process processToMonitor)
        Watches the given process and terminates it, if it runs for too long. All information from the previous run are reset.
        Parameters:
        processToMonitor - the process to monitor. It cannot be null.
        Throws:
        java.lang.IllegalStateException - if a process is still being monitored.
      • stop

        public void stop()
        Stops the watcher. It will notify all threads possibly waiting on this object.
      • timeoutOccured

        public void timeoutOccured​(Watchdog w)
        Called after watchdog has finished.
        Specified by:
        timeoutOccured in interface TimeoutObserver
        Parameters:
        w - the watchdog that timed out.