FileDocCategorySizeDatePackage
InaccurateTimeoutWatchdog.javaAPI DocApache James 2.3.18438Fri Jan 12 12:56:34 GMT 2007org.apache.james.util.watchdog

InaccurateTimeoutWatchdog

public class InaccurateTimeoutWatchdog extends org.apache.avalon.framework.logger.AbstractLogEnabled implements org.apache.avalon.framework.activity.Disposable, Watchdog, Runnable
This class represents an watchdog process that serves to monitor a situation and triggers an action after a certain time has passed. This implementation is deliberately inaccurate, trading accuracy for minimal impact on reset. This should be used when the time of the Watchdog trigger is not critical, and a high number of resets are expected.

Fields Summary
private volatile boolean
isChecking
Whether the watchdog is currently checking the trigger condition
private volatile boolean
isReset
Whether the watchdog has been reset since the thread slept.
private final long
timeout
The number of milliseconds until the watchdog times out.
private volatile long
lastReset
The last time the internal timer was reset, as measured in milliseconds since January 1, 1970 00:00:00.000 GMT.
private WatchdogTarget
triggerTarget
The WatchdogTarget whose execute() method will be called upon triggering of the condition.
private Thread
watchdogThread
The thread that runs the watchdog.
private org.apache.excalibur.thread.ThreadPool
myThreadPool
The thread pool used to generate InaccurateTimeoutWatchdogs
Constructors Summary
public InaccurateTimeoutWatchdog(long timeout, WatchdogTarget target, org.apache.excalibur.thread.ThreadPool threadPool)
The sole constructor for the InaccurateTimeoutWatchdog

param
timeout the time (in msec) that it will take the Watchdog to timeout
param
target the WatchdogTarget to be executed when this Watchdog expires
param
threadPool the thread pool used to generate threads for this implementation.


                                                    
           
        if (target == null) {
            throw new IllegalArgumentException("The WatchdogTarget for this TimeoutWatchdog cannot be null.");
        }
        if (threadPool == null) {
            throw new IllegalArgumentException("The thread pool for this TimeoutWatchdog cannot be null.");
        }
        this.timeout = timeout;
        triggerTarget = target;
        myThreadPool = threadPool;
    
Methods Summary
public voiddispose()

see
org.apache.avalon.framework.activity.Disposable#dispose()

        synchronized(this) {
            isChecking = false;
            if (watchdogThread != null) {
                getLogger().debug("Calling disposeWatchdog() " + watchdogThread.getName());
            } else {
                getLogger().debug("Calling disposeWatchdog() for inactive watchdog");
            }
            if (watchdogThread != null) {
                watchdogThread = null;
                notifyAll();
            }
            ContainerUtil.dispose(triggerTarget);
            triggerTarget = null;
        }
    
public voidreset()
Reset this Watchdog. Tells the Watchdog thread to reset the timer when it next awakens.

        if (watchdogThread != null) {
            getLogger().debug("Calling reset() " + watchdogThread.getName());
        } else {
            getLogger().debug("Calling reset() for inactive watchdog");
        }
        isReset = true;
    
public voidrun()
Execute the body of the Watchdog, triggering as appropriate.


        try {
            watchdogThread = Thread.currentThread();

            while ((!(Thread.currentThread().interrupted())) && (watchdogThread != null)) {
                try {
                    if (!isChecking) {
                        if (getLogger().isDebugEnabled()) {
                            getLogger().debug("Watchdog " + Thread.currentThread().getName() + " is not active - going to exit.");
                        }
                        synchronized (this) {
                            if (!isChecking) {
                                watchdogThread = null;
                            }
                            continue;
                        }
                    } else {
                        long currentTime = System.currentTimeMillis();
                        if (isReset) {
                            isReset = false;
                            lastReset = currentTime;
                        }
                        long timeToSleep = lastReset + timeout - currentTime;
                        if (watchdogThread != null) {
                            getLogger().debug("Watchdog " + watchdogThread.getName() + " has time to sleep " + timeToSleep);
                        } else {
                            getLogger().debug("Watchdog has time to sleep " + timeToSleep);
                        }
                        if (timeToSleep <= 0) {
                            try {
                                synchronized (this) {
                                    if ((isChecking) && (triggerTarget != null)) {
                                        triggerTarget.execute();
                                    }
                                    watchdogThread = null;
                                }
                            } catch (Throwable t) {
                                getLogger().error("Encountered error while executing Watchdog target.", t);
                            }
                            isChecking = false;
                            continue;
                        } else {
                            synchronized(this) {
                                wait(timeToSleep);
                            }
                        }
                    }
                } catch (InterruptedException ie) {
                }
            }

            synchronized( this ) {
                watchdogThread = null;
            }
        } finally {
            // Ensure that the thread is in a non-interrupted state when it gets returned
            // to the pool.
            Thread.currentThread().interrupted();
        }
        getLogger().debug("Watchdog " + Thread.currentThread().getName() + " is exiting run().");
    
public voidstart()
Start this Watchdog, causing it to begin checking.

        getLogger().debug("Calling start()");
        lastReset = System.currentTimeMillis();
        isChecking = true;
        synchronized(this) {
            if ( watchdogThread == null) {
                myThreadPool.execute(this);
            }
        }
    
public voidstop()
Stop this Watchdog, causing the Watchdog to stop checking the trigger condition. The monitor can be restarted with a call to startWatchdog.

        if (watchdogThread != null) {
            getLogger().debug("Calling stop() " + watchdogThread.getName());
        } else {
            getLogger().debug("Calling stop() for inactive watchdog");
        }
        isChecking = false;