001/* 002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Florent Guillaume 016 */ 017package org.nuxeo.ecm.core.work; 018 019import java.util.concurrent.CountDownLatch; 020 021/** 022 * Simple work that just sleeps, mostly used for tests. 023 */ 024public class SleepWork extends AbstractWork { 025 026 private static final long serialVersionUID = 1L; 027 028 protected long durationMillis; 029 030 protected String category; 031 032 /** used for debug. */ 033 protected static transient boolean debug; 034 035 /** used for debug. */ 036 protected static CountDownLatch readyLatch = new CountDownLatch(1); 037 038 /** used for debug. */ 039 protected static CountDownLatch doneLatch = new CountDownLatch(1); 040 041 /** used for debug. */ 042 protected static CountDownLatch startLatch = new CountDownLatch(1); 043 044 /** used for debug. */ 045 protected static CountDownLatch finishLatch = new CountDownLatch(1); 046 047 /** 048 * Creates a work instance that does nothing but sleep. 049 * 050 * @param durationMillis the sleep duration 051 */ 052 public SleepWork(long durationMillis) { 053 this(durationMillis, "SleepWork", false); 054 } 055 056 /** 057 * If debug is true, then the various debug* methods must be called in the proper order for the work to start and 058 * stop: {@link #debugStart}, {@link #debugFinish}. 059 * 060 * @param durationMillis the sleep duration 061 * @param debug {@code true} for debug 062 */ 063 public SleepWork(long durationMillis, boolean debug) { 064 this(durationMillis, "SleepWork", debug); 065 } 066 067 public SleepWork(long durationMillis, boolean debug, String id) { 068 this(durationMillis, "SleepWork", debug, id); 069 } 070 071 public SleepWork(long durationMillis, String category, boolean debug) { 072 super(); 073 init(durationMillis, category, debug); 074 } 075 076 public SleepWork(long durationMillis, String category, boolean debug, String id) { 077 super(id); 078 init(durationMillis, category, debug); 079 } 080 081 private void init(long durationMillis, String category, boolean debug) { 082 this.durationMillis = durationMillis; 083 this.category = category; 084 SleepWork.debug = debug; 085 setProgress(Progress.PROGRESS_0_PC); 086 } 087 088 @Override 089 public String getCategory() { 090 return category; 091 } 092 093 @Override 094 public String getTitle() { 095 return "Sleep " + durationMillis + " ms"; 096 } 097 098 @Override 099 public void work() { 100 try { 101 doWork(); 102 } catch (InterruptedException e) { 103 // restore interrupted status 104 Thread.currentThread().interrupt(); 105 throw new RuntimeException(e); 106 } 107 } 108 109 protected void doWork() throws InterruptedException { 110 if (debug) { 111 setStatus("Starting sleep work"); 112 readyLatch.countDown(); 113 startLatch.await(); 114 setStatus("Running sleep work"); 115 } 116 117 for (;;) { 118 long elapsed = System.currentTimeMillis() - getStartTime(); 119 if (elapsed > durationMillis) { 120 break; 121 } 122 setProgress(new Progress(100F * elapsed / durationMillis)); 123 124 if (isSuspending()) { 125 durationMillis -= elapsed; // save state 126 suspended(); 127 if (debug) { 128 doneLatch.countDown(); 129 finishLatch.await(); 130 } 131 return; 132 } 133 134 Thread.sleep(10); 135 } 136 137 if (debug) { 138 setStatus("Completed sleep work"); 139 setProgress(Progress.PROGRESS_100_PC); 140 doneLatch.countDown(); 141 finishLatch.await(); 142 } 143 } 144 145 @Override 146 public String toString() { 147 return getClass().getSimpleName() + "(" + (getId().length() > 10 ? "" : (getId() + ", ")) + durationMillis 148 + "ms, " + getProgress() + ")"; 149 } 150 151 public void debugWaitReady() throws InterruptedException { 152 readyLatch.await(); 153 } 154 155 public void debugWaitDone() throws InterruptedException { 156 doneLatch.await(); 157 } 158 159 public void debugStart() { 160 startLatch.countDown(); 161 } 162 163 public void debugFinish() { 164 finishLatch.countDown(); 165 } 166 167}