com.sas.util
Class TimedCommand

com.sas.util.TimedCommand
All Implemented Interfaces:
com.sas.util.SimpleCommand, ThreadedCommand, TimedCommandInterface

public class TimedCommand
implements TimedCommandInterface, ThreadedCommand

TimedCommand executes a command, with a timeout. If the command does not complete when the timeout expires, the operation is aborted (it's thread is interrupted or stopped) and a TimedOutException is thrown.

For example, a potentially long-lived operation, such as generating an ad-hoc SQL query, could be done in a TimedCommand. If no response is received after a fixed time out, the command is interrupted.

Interrupting Threads

In Java 2, the Thread.stop() method is deprecated. The clean way to halt a running thread is to interrupt it. TimedCommand will try to interrupt threads instead of stopping them. However, some command threads are not designed to be interrupted. Perhaps thay have a tight loop that never yields, never does I/O, or never checks the current Thread.interrupted() status. If your command object is of this form, then using interrupt won't work and you must use Thread.stop(). TimedCommand has a constructor argument, as well as an explicit useStop(boolean) method, to specify that it should use Thread.interrupted() for these cases.

However, if you wish the command to continue executing even after the timeout, you may use setMaxWaitTime(int) to specify how long the TimedCommand wll wait for the command to respond afer interrupting it. If the command does not complete after interval, it is assumed to be a runaway comand and the TimedCommand will throw a TimedOutException. However, the command will continue to execute and any registered cleanup command will run when the command completes.

Since:
1.2
See Also:
CommandProgress

Field Summary
protected  java.lang.Object cleanupArg
          The argument to pass to the cleanup command.
protected  com.sas.util.SimpleCommand cleanupCommand
          A command to execute if the command finishes abnormally
protected  com.sas.util.SimpleCommand command
          The command which executes under the timeout constraint.
protected  boolean finishOnCompletion
          If true, the thread dies when done, rather than be reused.
protected  int maxWaitInNanos
          The maximum amount of time, in nanoseconds, the TimedCommand will Object.wait(long, int) after interrupting the command.
protected  java.lang.Thread thread
          This object's thread.
protected  long timeoutInMillis
          the timeout constraint
protected  com.sas.util.TimedCommand.TimedCommandThread tThread
          The thread in which the command executes.
protected  boolean useStop
          If true, use Thread.stop() instead of Thread.interrupt() See Interrupting Threads above.
 
Constructor Summary
TimedCommand()
          Create a TimedCommand which will execute a command timing out after a period of time.
TimedCommand(com.sas.util.SimpleCommand command, long timeoutInMillis, boolean finishOnCompletion, com.sas.util.SimpleCommand cleanupCommand)
          Create a TimedCommand which will execute a command, timing out after a period of time.
TimedCommand(com.sas.util.SimpleCommand command, long timeoutInMillis, boolean finishOnCompletion, com.sas.util.SimpleCommand cleanupCommand, boolean useStop)
          Deprecated. Since Thread.stop() is deprecated in Java 2, It is best to use a command that can be stopped by Thread.interrupt(). See Interrupting Threads above.
 
Method Summary
protected  void cleanup(java.lang.Object arg)
          Perform cleanup by executing the cleanup command, passing the argument.
 void configure(com.sas.util.SimpleCommand command, long timeoutInMillis, boolean finishOnCompletion, com.sas.util.SimpleCommand cleanupCommand)
          Configure a TimedCommand which will execute a command, timing out after a period of time.
 void configure(com.sas.util.SimpleCommand command, long timeoutInMillis, boolean finishOnCompletion, com.sas.util.SimpleCommand cleanupCommand, boolean useStop)
          Deprecated. Since Thread.stop() is deprecated in Java 2, It is best to use a command that can be stopped by Thread.interrupt(). See Interrupting Threads above.
 void execute(java.lang.Object arg)
          Starts a thread to execute the command's TimedCommandInterface.run(Object) method (if the command is a TimedCommandInterface), or it's execute(Object) method if the command is just a SimpleCommand.
 void finalize()
          Finalize the object during garbage collection.
 com.sas.util.SimpleCommand getCleanupCommand()
          Return the command that executes if the command times out or is interrupted.
 com.sas.util.SimpleCommand getCommand()
          Return the command which this TimedCommand executes under a timeout constraint.
 boolean getFinishOnCompletion()
           
 int getMaxWaitTime()
          Return the maximum amount of time, in nanoseconds, the TimedCommand will Object.wait(long, int) after interrupting the command.
 long getTimeout()
          Return the timout duration (in milliseconds).
 void interrupt()
          Interrupt (or stop) the command, if it is alive.
 void interrupt(java.lang.Object arg)
          Interrupt the command, if it is alive.
protected  void interruptCommandThread()
          Interrupt the running TimedCommandThread thread, if it is running.
protected  boolean isRunning()
          Test if the inner thread is running
 void run(java.lang.Object arg)
          Starts a new thread in order to execute the command's TimedCommandInterface.run(Object) method (if the command is a TimedCommandInterface), or it's execute(Object) method if the command is just a SimpleCommand.
 void setCleanupCommand(com.sas.util.SimpleCommand cleanupCommand)
          Set the command to execute if the command is interrupted, throws an exception, or if it times out before completing.
 void setCommand(com.sas.util.SimpleCommand command)
          Set the command which this object executes with a timeout.
 void setFinishOnCompletion(boolean state)
          If state is true, then when the command thread completes, it is allowed to terminate, rather than go idle to be reused.
 void setMaxWaitTime(int maxWaitTime)
          Set the maximum time, in nanoseconds, that this TimedComand will wait for the command to stop after interrupting it.
 void setTimeout(long timeoutInMillis)
          Set the timeout.
 java.lang.String toString()
           
 boolean useStop()
          Indicate if this TimedCommand will attempt to Thread.stop() the internal command execution thread upon timeouts or abnormal command completion.
 void useStop(boolean useStop)
          If useStop is true, this TimedCommand will attempt to Thread.stop() the internal command execution thread upon timeouts or abnormal command completion.
protected  void waitFor(long timeOut)
          Start the command and wait for it to finish or for abnormal termination.
 

Field Detail

command

protected com.sas.util.SimpleCommand command
The command which executes under the timeout constraint.


cleanupCommand

protected com.sas.util.SimpleCommand cleanupCommand
A command to execute if the command finishes abnormally


timeoutInMillis

protected long timeoutInMillis
the timeout constraint


maxWaitInNanos

protected int maxWaitInNanos
The maximum amount of time, in nanoseconds, the TimedCommand will Object.wait(long, int) after interrupting the command. If 0, then Object.wait(). indefinitely.

Normally, a command can be interrupted and will stop execution. However, some commands invoke foreign operations which may not check for a thread interrupt. If this is the case, you should set the max wait time so that the TimedCommand does not block indefinitely waiting for the command to finish after interrupting it. If the command is still running after this amount of time, it is considered a runaway command and the TimedCommand will throw a TimedOutEXception even though the command may still be running. The command's clean up routine, if any, will be called when it finishes.

This integer does not have to be in the range [0,999999] as required by Object.wait(long,int). Instead, this value is ued to perform a wait(maxWaitTime/1000000, maxWaitTime % 1000000). For example, to wait for 50 microseconds, use setMaxWaitTime(50000). To wait for 2 milliseconds, use setMaxWaitTime(2000000)


tThread

protected transient com.sas.util.TimedCommand.TimedCommandThread tThread
The thread in which the command executes.


useStop

protected boolean useStop
If true, use Thread.stop() instead of Thread.interrupt() See Interrupting Threads above.


finishOnCompletion

protected boolean finishOnCompletion
If true, the thread dies when done, rather than be reused.


thread

protected transient java.lang.Thread thread
This object's thread.


cleanupArg

protected java.lang.Object cleanupArg
The argument to pass to the cleanup command. This is normally the same argument passed to the run(Object) method, but interrupt(Object) may be used to interrupt the command and specify a different argument to pass to the cleanupCommand.

Constructor Detail

TimedCommand

public TimedCommand()
Create a TimedCommand which will execute a command timing out after a period of time.


TimedCommand

public TimedCommand(com.sas.util.SimpleCommand command,
                    long timeoutInMillis,
                    boolean finishOnCompletion,
                    com.sas.util.SimpleCommand cleanupCommand)
Create a TimedCommand which will execute a command, timing out after a period of time.

Parameters:
timeoutInMillis - how long the command will be allowed to run before being interrupted.
finishOnCompletion - see setFinishOnCompletion(boolean)
cleanupCommand - a command to execute if the original command times out, is interrupted, or throws an exception.

TimedCommand

public TimedCommand(com.sas.util.SimpleCommand command,
                    long timeoutInMillis,
                    boolean finishOnCompletion,
                    com.sas.util.SimpleCommand cleanupCommand,
                    boolean useStop)
Deprecated. Since Thread.stop() is deprecated in Java 2, It is best to use a command that can be stopped by Thread.interrupt(). See Interrupting Threads above.

Create a TimedCommand which will execute a command, timing out after a period of time.

Parameters:
timeoutInMillis - how long the command will be allowed to run before being interrupted.
finishOnCompletion - see setFinishOnCompletion(boolean)
cleanupCommand - a command to execute if the original command times out, is interrupted, or throws an exception.
useStop - if true, use Thread.stop() instead of Thread.interrupt(). This is inherently dangerous; note that Thread.stop() is deprecated in Java 2.
Method Detail

configure

public void configure(com.sas.util.SimpleCommand command,
                      long timeoutInMillis,
                      boolean finishOnCompletion,
                      com.sas.util.SimpleCommand cleanupCommand)
Configure a TimedCommand which will execute a command, timing out after a period of time.

Parameters:
timeoutInMillis - how long the command will be allowed to run before being interrupted.
finishOnCompletion - see setFinishOnCompletion(boolean)
cleanupCommand - a command to execute if the original command times out, is interrupted, or throws an exception.

configure

public void configure(com.sas.util.SimpleCommand command,
                      long timeoutInMillis,
                      boolean finishOnCompletion,
                      com.sas.util.SimpleCommand cleanupCommand,
                      boolean useStop)
Deprecated. Since Thread.stop() is deprecated in Java 2, It is best to use a command that can be stopped by Thread.interrupt(). See Interrupting Threads above.

Create a TimedCommand which will execute a command, timing out after a period of time.

Parameters:
timeoutInMillis - how long the command will be allowed to run before being interrupted.
finishOnCompletion - see setFinishOnCompletion(boolean)
cleanupCommand - a command to execute if the original command times out, is interrupted, or throws an exception.
useStop - if true, use Thread.stop() instead of Thread.interrupt(). This is inherently dangerous; note that Thread.stop() is deprecated in Java 2.

setCommand

public void setCommand(com.sas.util.SimpleCommand command)
Set the command which this object executes with a timeout. If the command implements TimedCommandInterface, then this TimedCommand will interrupt it if it times out and also process any exceptions it's run method throws.

Parameters:
command - timed command.

getCommand

public com.sas.util.SimpleCommand getCommand()
Return the command which this TimedCommand executes under a timeout constraint.

Returns:
the timed command

setCleanupCommand

public void setCleanupCommand(com.sas.util.SimpleCommand cleanupCommand)
Set the command to execute if the command is interrupted, throws an exception, or if it times out before completing.

Parameters:
cleanupCommand - the cleanup command

getCleanupCommand

public com.sas.util.SimpleCommand getCleanupCommand()
Return the command that executes if the command times out or is interrupted.

Returns:
the cleanup command

setTimeout

public void setTimeout(long timeoutInMillis)
Set the timeout. When executing the command, if it does not complete after timeoutInMillis milliseconds, it is aborted.

Parameters:
timeoutInMillis - the timeout

getTimeout

public long getTimeout()
Return the timout duration (in milliseconds).

Returns:
the timeout

setMaxWaitTime

public void setMaxWaitTime(int maxWaitTime)
Set the maximum time, in nanoseconds, that this TimedComand will wait for the command to stop after interrupting it.

Normally, a command can be interrupted and will stop execution. However, some commands invoke foreign operations which may not check for a thread interrupt. If this is the case, you should set the max wait time so that the TimedCommand does not block indefinitely waiting for the command to finish after interrupting it. If the command is still running after this amount of time, it is considered a runaway command and the TimedCommand will throw a TimedOutEXception even though the command may still be running. The command's clean up routine, if any, will be called when it finishes.

Parameters:
maxWaitTime - The maximum amount of time, in nanoseconds, the TimedCommand will Object.wait(long, int) after interrupting the command. If 0, then Object.wait() indefinitely. This integer does not have to be in the range [0,999999] as required by Object.wait(long,int). Instead, this value is ued to perform a wait(maxWaitTime/1000000, maxWaitTime % 1000000). For example, to wait for 50 microseconds, use setMaxWaitTime(50000). To wait for 2 milliseconds, use setMaxWaitTime(2000000)

getMaxWaitTime

public int getMaxWaitTime()
Return the maximum amount of time, in nanoseconds, the TimedCommand will Object.wait(long, int) after interrupting the command. If 0, then Object.wait() indefinitely.


useStop

public boolean useStop()
Indicate if this TimedCommand will attempt to Thread.stop() the internal command execution thread upon timeouts or abnormal command completion. Stopping threads is not recommended but in some cases the command does not support interrupt() in any useful manner. See Interrupting Threads above.


useStop

public void useStop(boolean useStop)
If useStop is true, this TimedCommand will attempt to Thread.stop() the internal command execution thread upon timeouts or abnormal command completion. Stopping threads is not recommended but in some cases the command does not support interrupt() in any useful manner.

Parameters:
useStop - if true, use Thread.stop() to interrupt a command that has run too long. If false, use Thread.interrupt() See Interrupting Threads above.

setFinishOnCompletion

public void setFinishOnCompletion(boolean state)
If state is true, then when the command thread completes, it is allowed to terminate, rather than go idle to be reused. The default is false.


getFinishOnCompletion

public boolean getFinishOnCompletion()

execute

public void execute(java.lang.Object arg)
Starts a thread to execute the command's TimedCommandInterface.run(Object) method (if the command is a TimedCommandInterface), or it's execute(Object) method if the command is just a SimpleCommand. If the execution of the command takes longer than the timeout, the thread is interrupted or stopped. This method simply calls run(Object) and catches and ignores any exceptions.

Specified by:
execute in interface com.sas.util.SimpleCommand
Parameters:
arg - the value to pass to getCommand().run(arg).

run

public void run(java.lang.Object arg)
         throws java.lang.InterruptedException,
                java.lang.reflect.InvocationTargetException,
                TimedOutException
Starts a new thread in order to execute the command's TimedCommandInterface.run(Object) method (if the command is a TimedCommandInterface), or it's execute(Object) method if the command is just a SimpleCommand. If the execution of the command takes longer than the timeout, the thread is interrupted or stopped. If the command throws an exception, it is rethrown.

Specified by:
run in interface TimedCommandInterface
Parameters:
arg - the value to pass to getCommand().run(arg).
Throws:
java.lang.InterruptedException - if the command was interrupted via interrupt()
TimedOutException - if the command did not complete normally after the timeout ocurred.
java.lang.reflect.InvocationTargetException - if the command execution throws some other exception

waitFor

protected void waitFor(long timeOut)
                throws java.lang.InterruptedException,
                       java.lang.reflect.InvocationTargetException,
                       TimedOutException
Start the command and wait for it to finish or for abnormal termination.

Parameters:
timeOut - the amount of time to wait for the command, in milliseconds
Throws:
java.lang.InterruptedException
java.lang.reflect.InvocationTargetException
TimedOutException

interrupt

public void interrupt(java.lang.Object arg)
Interrupt the command, if it is alive.


interrupt

public void interrupt()
Interrupt (or stop) the command, if it is alive. If useStop() returns true, then the command thread is stopped via Thread.stop(), else it is simply interrupted. See Interrupting Threads above.

Specified by:
interrupt in interface ThreadedCommand

interruptCommandThread

protected void interruptCommandThread()
Interrupt the running TimedCommandThread thread, if it is running. This happens when it takes to long to complete, or if this TimedCommand is interrupted from another thread, such as a CommandProgress dialog.


isRunning

protected boolean isRunning()
Test if the inner thread is running


cleanup

protected void cleanup(java.lang.Object arg)
Perform cleanup by executing the cleanup command, passing the argument. Also, if finishOnCompletion is true, set the reference to the TimedCommandThread to null.

Parameters:
arg - the argument to pass to the cleanup command. This is normally the same value passed to the run(Object) or execute(Object) method, but if this TimedCommand was interrupted, it is the argument passed to interrupt(Object)

finalize

public void finalize()
              throws java.lang.Throwable
Finalize the object during garbage collection.

Overrides:
finalize in class java.lang.Object
Throws:
java.lang.Throwable

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object



Copyright © 2009 SAS Institute Inc. All Rights Reserved.