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    protected boolean idempotent = true;
039
040    /**
041     * Creates a work instance that does nothing but sleep.
042     *
043     * @param durationMillis the sleep duration
044     */
045    public SleepWork(long durationMillis) {
046        this(durationMillis, "SleepWork", false);
047    }
048
049    /**
050     * If debug is true, then the various debug* methods must be called in the proper order for the work to start and
051     * stop: {@link #debugStart}, {@link #debugFinish}.
052     *
053     * @param durationMillis the sleep duration
054     * @param debug {@code true} for debug
055     */
056    public SleepWork(long durationMillis, boolean debug) {
057        this(durationMillis, "SleepWork", debug);
058    }
059
060    public SleepWork(long durationMillis, boolean debug, String id) {
061        this(durationMillis, "SleepWork", debug, id);
062    }
063
064    public SleepWork(long durationMillis, String category, boolean debug) {
065        super();
066        init(durationMillis, category, debug);
067    }
068
069    public SleepWork(long durationMillis, String category, boolean debug, String id) {
070        super(id);
071        init(durationMillis, category, debug);
072    }
073
074    private void init(long durationMillis, String category, boolean debug) {
075        this.durationMillis = durationMillis;
076        this.category = category;
077        this.partitionKey = String.valueOf(count.incrementAndGet());
078        setProgress(Progress.PROGRESS_0_PC);
079    }
080
081    @Override
082    public String getCategory() {
083        return category;
084    }
085
086    @Override
087    public String getTitle() {
088        return "Sleep " + durationMillis + " ms";
089    }
090
091    @Override
092    public void work() {
093        try {
094            doWork();
095        } catch (InterruptedException e) {
096            Thread.currentThread().interrupt();
097            throw new RuntimeException(e);
098        }
099    }
100
101    protected void doWork() throws InterruptedException {
102        for (;;) {
103            long elapsed = System.currentTimeMillis() - getStartTime();
104            if (elapsed > durationMillis) {
105                break;
106            }
107            setProgress(new Progress(100F * elapsed / durationMillis));
108
109            if (isSuspending()) {
110                durationMillis -= elapsed; // save state
111                suspended();
112                return;
113            }
114
115            Thread.sleep(10);
116        }
117
118    }
119
120    @Override
121    public String getPartitionKey() {
122        return partitionKey;
123    }
124
125    @Override
126    public boolean isIdempotent() {
127        return idempotent;
128    }
129
130    public void setIdempotent(boolean idempotent) {
131        this.idempotent = idempotent;
132    }
133
134    @Override
135    public String toString() {
136        return getClass().getSimpleName() + "(" + (getId().length() > 10 ? "" : (getId() + ", ")) + durationMillis
137                + "ms, " + getProgress() + ")";
138    }
139
140}