tonva / pojo-mbean

Automatically exported from code.google.com/p/pojo-mbean
0 stars 0 forks source link

Add pause() functionality to ProcessingMBean sample #25

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Let the MBean control a "paused" attribute, and supply helper methods to 
sleepWhilePaused().

Allow a timeout to allow the caller to log that it is currently paused.

Original issue reported on code.google.com by morten.h...@gmail.com on 13 Jul 2011 at 10:52

GoogleCodeExporter commented 9 years ago
Sample MBean implementation:

    /**
     * Used as a pause flag as well as a monitor that threads may wait for and receive notification
     * whenever a transition occurs (in any direction)
     */
    private final AtomicBoolean paused = new AtomicBoolean(false);

    @ManagedAttribute
    public boolean isPaused() {
        return paused.get();
    }

    @ManagedAttribute
    @Description("Pause status. If true, this indicates that no further processing should be undertaken")
    public void setPaused(boolean paused) {
        synchronized(this.paused) {
            if (this.paused.compareAndSet(!paused, paused)) {
                // a transition occured. Notify anyone waiting for a transition
                this.paused.notifyAll();
            }
        }
    }

    /**
     * If the paused attribute is true, the thread will be put to sleep until it paused becomes false (set by another thread).<p>
     * See {@link #sleepWhilePaused()} for a sample implementation that sleeps until pause property becomes true
     * @param time maximum number of {@code unit} to sleep 
     * @param unit the unit of measure for {@code time}
     * @return the status of the paused flag at the time of exit.
     * If {@code true} is returned, the caller should immediately initiate a new sleep, possibly after logging some status information.<br>
     * Note that it is NOT guaranteed that the thread will sleep for the entire {@code unit/time} period, even if the pause flag remains true.
     * @throws InterruptedException if the thread is interrupted while sleeping
     */
    public boolean sleepIfPaused(long time, TimeUnit unit) throws InterruptedException {
        synchronized(paused) {
            boolean sleep = paused.get();
            if (sleep) {
                // pause for up to time/unit, releases synchronization lock while waiting for notification
                paused.wait(unit.toMillis(time));
            }
            return sleep;
        }
    }

    /**
     * Sample implementation of a "sleep while paused", which logs messages on {@code System.out} when paused/unpaused,
     * and a warning on {@code System.err} every minute, while paused
     * @throws InterruptedException
     */
    public void sleepWhilePaused() throws InterruptedException {
        if (isPaused()) {
            System.out.println("Paused by MBean");
        }
        while (sleepIfPaused(60, TimeUnit.SECONDS)) {
            if (isPaused()) {
                // We have slept for one period, and are required to go to sleep again
                System.err.println("Still paused by MBean");
            } else {
                System.out.println("Unpaused by MBean");
            }
        }
    }

Original comment by morten.h...@gmail.com on 13 Jul 2011 at 11:51

GoogleCodeExporter commented 9 years ago

Original comment by morten.h...@gmail.com on 13 Jul 2011 at 11:52

GoogleCodeExporter commented 9 years ago

Original comment by morten.h...@gmail.com on 13 Jul 2011 at 11:52

GoogleCodeExporter commented 9 years ago

Original comment by morten.h...@gmail.com on 13 Jul 2011 at 11:53

GoogleCodeExporter commented 9 years ago
In addition to pause(), we should support a wider range of running states, e.g.:
NEW, STARTED, RUNNING, PAUSED, STOPPED, FAILED, TERMINATED

... and provide @ManagedOperation for state transition and @ManagedAttribute 
for the current state.

Also, state transition should be controlled, in addition to moving "forward" 
along the above states, the following transitions would be permitted:
PAUSED -> RUNNING [resume() or run()]
STOPPED -> RUNNING [run()]
FAILED -> RUNNING [run()]

Only an error would allow a transition from RUNNING to FAILED

Not all beans may support all states.

Original comment by morten.h...@gmail.com on 14 Jul 2011 at 10:28