001/*
002 * (C) Copyright 2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Florent Guillaume
018 */
019package org.nuxeo.ecm.core.work;
020
021import java.util.concurrent.atomic.AtomicInteger;
022
023/**
024 * Simple work that just sleeps, mostly used for tests.
025 */
026public class SleepWork extends AbstractWork {
027
028    private static final long serialVersionUID = 1L;
029
030    protected long durationMillis;
031
032    protected String category;
033
034    protected AtomicInteger count = new AtomicInteger();
035
036    protected String partitionKey;
037
038    /**
039     * Creates a work instance that does nothing but sleep.
040     *
041     * @param durationMillis the sleep duration
042     */
043    public SleepWork(long durationMillis) {
044        this(durationMillis, "SleepWork", false);
045    }
046
047    /**
048     * If debug is true, then the various debug* methods must be called in the proper order for the work to start and
049     * stop: {@link #debugStart}, {@link #debugFinish}.
050     *
051     * @param durationMillis the sleep duration
052     * @param debug {@code true} for debug
053     */
054    public SleepWork(long durationMillis, boolean debug) {
055        this(durationMillis, "SleepWork", debug);
056    }
057
058    public SleepWork(long durationMillis, boolean debug, String id) {
059        this(durationMillis, "SleepWork", debug, id);
060    }
061
062    public SleepWork(long durationMillis, String category, boolean debug) {
063        super();
064        init(durationMillis, category, debug);
065    }
066
067    public SleepWork(long durationMillis, String category, boolean debug, String id) {
068        super(id);
069        init(durationMillis, category, debug);
070    }
071
072    private void init(long durationMillis, String category, boolean debug) {
073        this.durationMillis = durationMillis;
074        this.category = category;
075        this.partitionKey = String.valueOf(count.incrementAndGet());
076        setProgress(Progress.PROGRESS_0_PC);
077    }
078
079    @Override
080    public String getCategory() {
081        return category;
082    }
083
084    @Override
085    public String getTitle() {
086        return "Sleep " + durationMillis + " ms";
087    }
088
089    @Override
090    public void work() {
091        try {
092            doWork();
093        } catch (InterruptedException e) {
094            // restore interrupted status
095            Thread.currentThread().interrupt();
096            throw new RuntimeException(e);
097        }
098    }
099
100    protected void doWork() throws InterruptedException {
101        for (;;) {
102            long elapsed = System.currentTimeMillis() - getStartTime();
103            if (elapsed > durationMillis) {
104                break;
105            }
106            setProgress(new Progress(100F * elapsed / durationMillis));
107
108            if (isSuspending()) {
109                durationMillis -= elapsed; // save state
110                suspended();
111                return;
112            }
113
114            Thread.sleep(10);
115        }
116
117    }
118
119    @Override
120    public String getPartitionKey() {
121        return partitionKey;
122    }
123
124    @Override
125    public String toString() {
126        return getClass().getSimpleName() + "(" + (getId().length() > 10 ? "" : (getId() + ", ")) + durationMillis
127                + "ms, " + getProgress() + ")";
128    }
129
130}