View | Details | Raw Unified | Return to bug 62637
Collapse All | Expand All

(-)a/src/components/org/apache/jmeter/timers/SyncTimer.java (-3 / +19 lines)
Lines 29-34 import org.apache.jmeter.testelement.AbstractTestElement; Link Here
29
import org.apache.jmeter.testelement.TestStateListener;
29
import org.apache.jmeter.testelement.TestStateListener;
30
import org.apache.jmeter.testelement.ThreadListener;
30
import org.apache.jmeter.testelement.ThreadListener;
31
import org.apache.jmeter.threads.JMeterContextService;
31
import org.apache.jmeter.threads.JMeterContextService;
32
import org.apache.jmeter.threads.BlockingTimer;
32
import org.slf4j.Logger;
33
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34
import org.slf4j.LoggerFactory;
34
35
Lines 38-44 import org.slf4j.LoggerFactory; Link Here
38
 * thus create large instant loads at various points of the test plan.
39
 * thus create large instant loads at various points of the test plan.
39
 *
40
 *
40
 */
41
 */
41
public class SyncTimer extends AbstractTestElement implements Timer, Serializable, TestBean, TestStateListener, ThreadListener {
42
public class SyncTimer extends AbstractTestElement implements BlockingTimer, Serializable, TestBean, TestStateListener, ThreadListener {
42
    private static final Logger log = LoggerFactory.getLogger(SyncTimer.class);
43
    private static final Logger log = LoggerFactory.getLogger(SyncTimer.class);
43
44
44
    /**
45
    /**
Lines 142-147 public class SyncTimer extends AbstractTestElement implements Timer, Serializabl Link Here
142
    
143
    
143
    private long timeoutInMs;
144
    private long timeoutInMs;
144
145
146
    private long endTime;
147
145
    // Ensure transient object is created by the server
148
    // Ensure transient object is created by the server
146
    private Object readResolve(){
149
    private Object readResolve(){
147
        createBarrier();
150
        createBarrier();
Lines 172-184 public class SyncTimer extends AbstractTestElement implements Timer, Serializabl Link Here
172
            int arrival = 0;
175
            int arrival = 0;
173
            try {
176
            try {
174
                if(timeoutInMs==0) {
177
                if(timeoutInMs==0) {
175
                    arrival = this.barrier.await();                    
178
                    long forcedTimeoutInMs = endTime - System.currentTimeMillis();
179
                    arrival = this.barrier.await(forcedTimeoutInMs, TimeUnit.MILLISECONDS);
176
                } else if(timeoutInMs > 0){
180
                } else if(timeoutInMs > 0){
177
                    arrival = this.barrier.await(timeoutInMs, TimeUnit.MILLISECONDS);
181
                    arrival = this.barrier.await(timeoutInMs, TimeUnit.MILLISECONDS);
178
                } else {
182
                } else {
179
                    throw new IllegalArgumentException("Negative value for timeout:"+timeoutInMs+" in Synchronizing Timer "+getName());
183
                    throw new IllegalArgumentException("Negative value for timeout:"+timeoutInMs+" in Synchronizing Timer "+getName());
180
                }
184
                }
181
            } catch (InterruptedException | BrokenBarrierException e) {
185
            } catch (InterruptedException e) {
186
                Thread.currentThread().interrupt();
187
                return 0;
188
            } catch (BrokenBarrierException e) {
182
                return 0;
189
                return 0;
183
            } catch (TimeoutException e) {
190
            } catch (TimeoutException e) {
184
                if (log.isWarnEnabled()) {
191
                if (log.isWarnEnabled()) {
Lines 242-247 public class SyncTimer extends AbstractTestElement implements Timer, Serializabl Link Here
242
     *
249
     *
243
     */
250
     */
244
    private void createBarrier() {
251
    private void createBarrier() {
252
        if (this.barrier != null) {
253
            log.debug("Reset old barrier before creating new one.");
254
            this.barrier.reset();
255
        }
245
        if(getGroupSize() == 0) {
256
        if(getGroupSize() == 0) {
246
            // Lazy init
257
            // Lazy init
247
            this.barrier = new BarrierWrapper();
258
            this.barrier = new BarrierWrapper();
Lines 277-280 public class SyncTimer extends AbstractTestElement implements Timer, Serializabl Link Here
277
    public void setTimeoutInMs(long timeoutInMs) {
288
    public void setTimeoutInMs(long timeoutInMs) {
278
        this.timeoutInMs = timeoutInMs;
289
        this.timeoutInMs = timeoutInMs;
279
    }
290
    }
291
292
    @Override
293
    public void setMaxEndTime(long endTime) {
294
        this.endTime = endTime;
295
    }
280
}
296
}
(-)a/src/core/org/apache/jmeter/threads/BlockingTimer.java (+44 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
 * License for the specific language governing permissions and limitations
15
 * under the License.
16
 *
17
 */
18
19
package org.apache.jmeter.threads;
20
21
import org.apache.jmeter.timers.Timer;
22
23
/**
24
 * If a {@link Timer} can block while calculating its delay, we need a
25
 * way to stop it early, if it is used with a scheduled Test plan.
26
 * <p>
27
 * A Class implementing this interface specifies that it can block while
28
 * calculating the delay and will stop calculating the delay, when the specified
29
 * end time has been reached.
30
 *
31
 */
32
public interface BlockingTimer extends Timer {
33
34
    /**
35
     * Indicate the max end time before the delay for this Timer has to be
36
     * calculated and returned.
37
     * 
38
     * @param endTime
39
     *            the max end time for the {@link JMeterThread} for which the
40
     *            delay should be calculated
41
     */
42
    void setMaxEndTime(long endTime);
43
44
}
(-)a/src/core/org/apache/jmeter/threads/JMeterThread.java (-1 / +8 lines)
Lines 940-946 public class JMeterThread implements Runnable, Interruptible { Link Here
940
        long totalDelay = 0;
940
        long totalDelay = 0;
941
        for (Timer timer : timers) {
941
        for (Timer timer : timers) {
942
            TestBeanHelper.prepare((TestElement) timer);
942
            TestBeanHelper.prepare((TestElement) timer);
943
            long delay = timer.delay();
943
            long delay = calculateDelay(timer);
944
            if (APPLY_TIMER_FACTOR && timer.isModifiable()) {
944
            if (APPLY_TIMER_FACTOR && timer.isModifiable()) {
945
                if (log.isDebugEnabled()) {
945
                if (log.isDebugEnabled()) {
946
                    log.debug("Applying TIMER_FACTOR:{} on timer:{} for thread:{}", TIMER_FACTOR,
946
                    log.debug("Applying TIMER_FACTOR:{} on timer:{} for thread:{}", TIMER_FACTOR,
Lines 965-970 public class JMeterThread implements Runnable, Interruptible { Link Here
965
        }
965
        }
966
    }
966
    }
967
967
968
    private long calculateDelay(Timer timer) {
969
        if (timer instanceof BlockingTimer) {
970
            ((BlockingTimer) timer).setMaxEndTime(getEndTime());
971
        }
972
        return timer.delay();
973
    }
974
968
    void notifyTestListeners() {
975
    void notifyTestListeners() {
969
        threadVars.incIteration();
976
        threadVars.incIteration();
970
        for (TestIterationListener listener : testIterationStartListeners) {
977
        for (TestIterationListener listener : testIterationStartListeners) {
(-)a/test/src/org/apache/jmeter/timers/SyncTimerTest.java (-1 / +36 lines)
Line 0 Link Here
0
- 
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
 * License for the specific language governing permissions and limitations
15
 * under the License.
16
 *
17
 */
18
19
package org.apache.jmeter.timers;
20
21
import org.hamcrest.CoreMatchers;
22
import org.junit.Assert;
23
import org.junit.Test;
24
25
public class SyncTimerTest {
26
27
    @Test
28
    public void testMaxEndTime() {
29
        SyncTimer timer = new SyncTimer();
30
        timer.setGroupSize(2);
31
        timer.setMaxEndTime(System.currentTimeMillis() + 200L);
32
        timer.testStarted();
33
        Assert.assertThat(timer.delay(), CoreMatchers.is(0L));
34
    }
35
36
}

Return to bug 62637