/*
* (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Contributors:
* Florent Guillaume
*/
package org.nuxeo.ecm.core.work;
import java.util.concurrent.CountDownLatch;
/**
* Simple work that just sleeps, mostly used for tests.
*/
public class SleepWork extends AbstractWork {
private static final long serialVersionUID = 1L;
protected long durationMillis;
protected String category;
/** used for debug. */
protected transient boolean debug;
/** used for debug. */
protected transient CountDownLatch readyLatch = new CountDownLatch(1);
/** used for debug. */
protected transient CountDownLatch doneLatch = new CountDownLatch(1);
/** used for debug. */
protected transient CountDownLatch startLatch = new CountDownLatch(1);
/** used for debug. */
protected transient CountDownLatch finishLatch = new CountDownLatch(1);
/**
* Creates a work instance that does nothing but sleep.
*
* @param durationMillis the sleep duration
*/
public SleepWork(long durationMillis) {
this(durationMillis, "SleepWork", false);
}
/**
* If debug is true, then the various debug* methods must be called in the
* proper order for the work to start and stop: {@link #debugStart},
* {@link #debugFinish}.
*
* @param durationMillis the sleep duration
* @param debug {@code true} for debug
*/
public SleepWork(long durationMillis, boolean debug) {
this(durationMillis, "SleepWork", debug);
}
public SleepWork(long durationMillis, boolean debug, String id) {
this(durationMillis, "SleepWork", debug, id);
}
public SleepWork(long durationMillis, String category, boolean debug) {
super();
init(durationMillis, category, debug);
}
public SleepWork(long durationMillis, String category, boolean debug, String id) {
super(id);
init(durationMillis, category, debug);
}
private void init(long durationMillis, String category, boolean debug) {
this.durationMillis = durationMillis;
this.category = category;
this.debug = debug;
setProgress(Progress.PROGRESS_0_PC);
}
@Override
public String getCategory() {
return category;
}
@Override
public String getTitle() {
return "Sleep " + durationMillis + " ms";
}
@Override
public void work() throws InterruptedException {
if (debug) {
setStatus("Starting sleep work");
readyLatch.countDown();
startLatch.await();
setStatus("Running sleep work");
}
for (;;) {
long elapsed = System.currentTimeMillis() - getStartTime();
if (elapsed > durationMillis) {
break;
}
setProgress(new Progress(100F * elapsed / durationMillis));
if (isSuspending()) {
durationMillis -= elapsed; // save state
suspended();
if (debug) {
doneLatch.countDown();
finishLatch.await();
}
return;
}
Thread.sleep(10);
}
if (debug) {
setStatus("Completed sleep work");
setProgress(Progress.PROGRESS_100_PC);
doneLatch.countDown();
finishLatch.await();
}
}
@Override
public String toString() {
return getClass().getSimpleName() + "("
+ (getId().length() > 10 ? "" : (getId() + ", "))
+ durationMillis + "ms, " + getProgress() + ")";
}
public void debugWaitReady() throws InterruptedException {
readyLatch.await();
}
public void debugWaitDone() throws InterruptedException {
doneLatch.await();
}
public void debugStart() {
startLatch.countDown();
}
public void debugFinish() {
finishLatch.countDown();
}
}