You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jmeter.apache.org by Philippe Mouawad <ph...@gmail.com> on 2015/12/17 23:52:48 UTC

Re: svn commit: r1720012 - in /jmeter/trunk: bin/ src/components/org/apache/jmeter/modifiers/ src/components/org/apache/jmeter/modifiers/gui/ src/core/org/apache/jmeter/resources/ src/core/org/apache/jmeter/save/ src/core/org/apache/jmeter/threads/ xdocs/ ...

Hi,

1/ Looking at the code, I think there might be a  side effect of this.
With this commit, in JMeterThread we now call SampleListener#sampleStarted
and sampleStopped around sampler.sample().
It was not the case previously.
There might be strange side effect if any 3rd party implements
sampleStarted/sampleStopped.

By the way, I must say it's not clear for me when
sampleStarted/sampleStopped were called before this commit.

2/ So, I wonder if it's a good idea to use this SampleListener interface ?

3/ I also wonder if we should not split SampleListener into 2 interfaces
and deprecate it (as we did with TestListener which we deprecated). Indeed
I looked at all implementations of it, even in 3rd party JMeterPlugins and
no implementation uses sampleStarted/sampleStopped, all implement
sampleOccured()

Regards
Philippe


On Mon, Dec 14, 2015 at 9:52 PM, <se...@apache.org> wrote:

> Author: sebb
> Date: Mon Dec 14 20:52:19 2015
> New Revision: 1720012
>
> URL: http://svn.apache.org/viewvc?rev=1720012&view=rev
> Log:
> Add Sample Timeout support
> Bugzilla Id: 58736
>
> Added:
>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>  (with props)
>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>  (with props)
>     jmeter/trunk/xdocs/images/screenshots/sample_timeout.png   (with props)
> Modified:
>     jmeter/trunk/bin/jmeter.properties
>     jmeter/trunk/bin/saveservice.properties
>     jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>
> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>     jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
>     jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
>     jmeter/trunk/xdocs/changes.xml
>     jmeter/trunk/xdocs/usermanual/component_reference.xml
>
> Modified: jmeter/trunk/bin/jmeter.properties
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>
> ==============================================================================
> --- jmeter/trunk/bin/jmeter.properties (original)
> +++ jmeter/trunk/bin/jmeter.properties Mon Dec 14 20:52:19 2015
> @@ -1035,6 +1035,11 @@ beanshell.server.file=../extras/startup.
>  # Uncomment the following line to revert to the original behaviour
>  #jmeterthread.reversePostProcessors=true
>
> +# (2.14) JMeterThread behaviour has changed: it now implements
> sampleStarted/sampleStopped
> +# This is necessary for the test element Sample Timeout
> +# Uncomment the following line to revert to the original behaviour
> (Sample Timeout will no longer work)
> +#JMeterThread.sampleStarted=false
> +
>  # (2.2) StandardJMeterEngine behaviour has been changed to notify the
> listeners after
>  # the running version is enabled. This is so they can access variables.
>  # In case this causes problems, the previous behaviour can be restored by
> uncommenting
>
> Modified: jmeter/trunk/bin/saveservice.properties
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/bin/saveservice.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>
> ==============================================================================
> --- jmeter/trunk/bin/saveservice.properties (original)
> +++ jmeter/trunk/bin/saveservice.properties Mon Dec 14 20:52:19 2015
> @@ -269,6 +269,8 @@ ResultSaverGui=org.apache.jmeter.reporte
>  RunTime=org.apache.jmeter.control.RunTime
>  RunTimeGui=org.apache.jmeter.control.gui.RunTimeGui
>  SampleSaveConfiguration=org.apache.jmeter.samplers.SampleSaveConfiguration
> +SampleTimeout=org.apache.jmeter.modifiers.SampleTimeout
> +SampleTimeoutGui=org.apache.jmeter.modifiers.gui.SampleTimeoutGui
>  SimpleConfigGui=org.apache.jmeter.config.gui.SimpleConfigGui
>  SimpleDataWriter=org.apache.jmeter.visualizers.SimpleDataWriter
>  SizeAssertion=org.apache.jmeter.assertions.SizeAssertion
>
> Added:
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java?rev=1720012&view=auto
>
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
> (added)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
> Mon Dec 14 20:52:19 2015
> @@ -0,0 +1,230 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + *
> + */
> +
> +package org.apache.jmeter.modifiers;
> +
> +import java.io.Serializable;
> +import java.util.concurrent.Callable;
> +import java.util.concurrent.Executors;
> +import java.util.concurrent.ScheduledExecutorService;
> +import java.util.concurrent.ScheduledFuture;
> +import java.util.concurrent.ThreadFactory;
> +import java.util.concurrent.TimeUnit;
> +
> +import org.apache.jmeter.samplers.Interruptible;
> +import org.apache.jmeter.samplers.SampleEvent;
> +import org.apache.jmeter.samplers.SampleListener;
> +import org.apache.jmeter.samplers.Sampler;
> +import org.apache.jmeter.testelement.AbstractTestElement;
> +import org.apache.jmeter.testelement.TestElement;
> +import org.apache.jmeter.testelement.ThreadListener;
> +import org.apache.jmeter.threads.JMeterContext;
> +import org.apache.jmeter.threads.JMeterContextService;
> +import org.apache.jmeter.util.JMeterUtils;
> +import org.apache.jorphan.logging.LoggingManager;
> +import org.apache.log.Logger;
> +
> +/**
> + *
> + * Sample timeout implementation using Executor threads
> + *
> + */
> +public class SampleTimeout extends AbstractTestElement implements
> Serializable, ThreadListener, SampleListener {
> +
> +    private static final long serialVersionUID = 1L;
> +
> +    private static final Logger LOG = LoggingManager.getLoggerForClass();
> +
> +    private static final String TIMEOUT = "InterruptTimer.timeout";
> //$NON-NLS-1$
> +
> +    private final boolean useRunnable =
> JMeterUtils.getPropDefault("InterruptTimer.useRunnable", false);
> +
> +    private static class TPOOLHolder {
> +        static final ScheduledExecutorService EXEC_SERVICE =
> +                Executors.newScheduledThreadPool(1,
> +                        new ThreadFactory() {
> +                            public Thread newThread(Runnable r) {
> +                                Thread t =
> Executors.defaultThreadFactory().newThread(r);
> +                                t.setDaemon(true); // also ensures that
> Executor thread is daemon
> +                                return t;
> +                            }
> +                        });
> +    }
> +
> +    private static ScheduledExecutorService getExecutorService() {
> +        return TPOOLHolder.EXEC_SERVICE;
> +    }
> +
> +    private JMeterContext context; // Cache this here to avoid refetching
> +
> +    private ScheduledFuture<?> future;
> +
> +    private final transient ScheduledExecutorService execService;
> +
> +    private final boolean debug;
> +
> +    /**
> +     * No-arg constructor.
> +     */
> +    public SampleTimeout() {
> +//        LOG.setPriority(org.apache.log.Priority.DEBUG); // for local
> debugging when enabled
> +        debug = LOG.isDebugEnabled();
> +        execService = getExecutorService();
> +        if (debug) {
> +            LOG.debug(whoAmI("InterruptTimer()", this));
> +        }
> +    }
> +
> +    /**
> +     * Set the timeout for this timer.
> +     * @param timeout The timeout for this timer
> +     */
> +    public void setTimeout(String timeout) {
> +        setProperty(TIMEOUT, timeout);
> +    }
> +
> +    /**
> +     * Get the timeout value for display.
> +     *
> +     * @return the timeout value for display.
> +     */
> +    public String getTimeout() {
> +        return getPropertyAsString(TIMEOUT);
> +    }
> +
> +    @Override
> +    public void sampleStarted(SampleEvent e) {
> +        if (debug) {
> +            LOG.debug(whoAmI("sampleStarted()", this));
> +        }
> +        createTask();
> +    }
> +
> +    @Override
> +    public void sampleStopped(SampleEvent e) {
> +        if (debug) {
> +            LOG.debug(whoAmI("sampleStopped()", this));
> +        }
> +        cancelTask();
> +    }
> +
> +    private void createTask() {
> +        long timeout = getPropertyAsLong(TIMEOUT); // refetch each time
> so it can be a variable
> +        if (timeout <= 0) {
> +            return;
> +        }
> +        final Sampler samp = context.getCurrentSampler();
> +        if (!(samp instanceof Interruptible)) { // may be applied to a
> whole test
> +            return; // Cannot time out in this case
> +        }
> +        final Interruptible sampler = (Interruptible) samp;
> +
> +        if (useRunnable) {
> +            Runnable run=new Runnable() {
> +                public void run() {
> +                    long start = System.nanoTime();
> +                    boolean interrupted = sampler.interrupt();
> +                    String elapsed =
> Double.toString((double)(System.nanoTime()-start)/ 1000000000)+" secs";
> +                    if (interrupted) {
> +                        LOG.warn("Run Done interrupting " + getInfo(samp)
> + " took " + elapsed);
> +                    } else {
> +                        if (debug) {
> +                            LOG.debug("Run Didn't interrupt: " +
> getInfo(samp) + " took " + elapsed);
> +                        }
> +                    }
> +                }
> +            };
> +            // schedule the interrupt to occur and save for possible
> cancellation
> +            future = execService.schedule(run, timeout,
> TimeUnit.MILLISECONDS);
> +        } else {
> +            Callable<Object> call = new Callable<Object>() {
> +                @Override
> +                public Object call() throws Exception {
> +                    long start = System.nanoTime();
> +                    boolean interrupted = sampler.interrupt();
> +                    String elapsed =
> Double.toString((double)(System.nanoTime()-start)/ 1000000000)+" secs";
> +                    if (interrupted) {
> +                        LOG.warn("Call Done interrupting " +
> getInfo(samp) + " took " + elapsed);
> +                    } else {
> +                        if (debug) {
> +                            LOG.debug("Call Didn't interrupt: " +
> getInfo(samp) + " took " + elapsed);
> +                        }
> +                    }
> +                    return null;
> +                }
> +
> +            };
> +            // schedule the interrupt to occur and save for possible
> cancellation
> +            future = execService.schedule(call, timeout,
> TimeUnit.MILLISECONDS);
> +        }
> +        if (debug) {
> +            LOG.debug("Scheduled timer: @" +
> System.identityHashCode(future) + " " + getInfo(samp));
> +        }
> +    }
> +
> +    @Override
> +    public void threadStarted() {
> +        if (debug) {
> +            LOG.debug(whoAmI("threadStarted()", this));
> +        }
> +        context = JMeterContextService.getContext();
> +     }
> +
> +    @Override
> +    public void threadFinished() {
> +        if (debug) {
> +            LOG.debug(whoAmI("threadFinished()", this));
> +        }
> +        cancelTask(); // cancel final if any
> +     }
> +
> +    /**
> +     * Provide a description of this class.
> +     *
> +     * @return the description of this class.
> +     */
> +    @Override
> +    public String toString() {
> +        return JMeterUtils.getResString("sample_timeout_memo");
> //$NON-NLS-1$
> +    }
> +
> +    private String whoAmI(String id, TestElement o) {
> +        return id + " @" + System.identityHashCode(o)+ " '"+ o.getName()
> + "' " + (debug ?  Thread.currentThread().getName() : "");
> +    }
> +
> +    private String getInfo(TestElement o) {
> +        return whoAmI(o.getClass().getSimpleName(), o);
> +    }
> +
> +    private void cancelTask() {
> +        if (future != null) {
> +            if (!future.isDone()) {
> +                boolean cancelled = future.cancel(false);
> +                if (debug) {
> +                    LOG.debug("Cancelled timer: @" +
> System.identityHashCode(future) + " with result " + cancelled);
> +                }
> +            }
> +            future = null;
> +        }
> +    }
> +
> +    @Override
> +    public void sampleOccurred(SampleEvent e) {
> +        // Not used
> +    }
> +}
>
> Propchange:
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>
> ------------------------------------------------------------------------------
>     svn:eol-style = native
>
> Added:
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java?rev=1720012&view=auto
>
> ==============================================================================
> ---
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
> (added)
> +++
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
> Mon Dec 14 20:52:19 2015
> @@ -0,0 +1,133 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *   http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + *
> + */
> +
> +package org.apache.jmeter.modifiers.gui;
> +
> +import javax.swing.Box;
> +import javax.swing.JComponent;
> +import javax.swing.JLabel;
> +import javax.swing.JOptionPane;
> +import javax.swing.JTextField;
> +
> +import org.apache.jmeter.modifiers.SampleTimeout;
> +import org.apache.jmeter.processor.gui.AbstractPreProcessorGui;
> +import org.apache.jmeter.testelement.TestElement;
> +import org.apache.jmeter.util.JMeterUtils;
> +import org.apache.jorphan.gui.layout.VerticalLayout;
> +
> +/**
> + * The GUI for SampleTimeout.
> + */
> +public class SampleTimeoutGui extends AbstractPreProcessorGui {
> +
> +    private static final long serialVersionUID = 240L;
> +
> +    /**
> +     * The default value for the timeout.
> +     */
> +    private static final String DEFAULT_TIMEOUT = "10000";
> +
> +    private JTextField timeoutField;
> +
> +    /**
> +     * No-arg constructor.
> +     */
> +    public SampleTimeoutGui() {
> +        init();
> +    }
> +
> +    /**
> +     * Handle an error.
> +     *
> +     * @param e
> +     *            the Exception that was thrown.
> +     * @param thrower
> +     *            the JComponent that threw the Exception.
> +     */
> +    public static void error(Exception e, JComponent thrower) {
> +        JOptionPane.showMessageDialog(thrower, e, "Error",
> JOptionPane.ERROR_MESSAGE);
> +    }
> +
> +    @Override
> +    public String getLabelResource() {
> +        return "sample_timeout_title"; // $NON-NLS-1$
> +    }
> +
> +    /**
> +     * Create the test element underlying this GUI component.
> +     *
> +     * @see org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()
> +     */
> +    @Override
> +    public TestElement createTestElement() {
> +        SampleTimeout timer = new SampleTimeout();
> +        modifyTestElement(timer);
> +        return timer;
> +    }
> +
> +    /**
> +     * Modifies a given TestElement to mirror the data in the gui
> components.
> +     *
> +     * @see
> org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
> +     */
> +    @Override
> +    public void modifyTestElement(TestElement timer) {
> +        this.configureTestElement(timer);
> +        ((SampleTimeout) timer).setTimeout(timeoutField.getText());
> +    }
> +
> +    /**
> +     * Configure this GUI component from the underlying TestElement.
> +     *
> +     * @see
> org.apache.jmeter.gui.JMeterGUIComponent#configure(TestElement)
> +     */
> +    @Override
> +    public void configure(TestElement el) {
> +        super.configure(el);
> +        timeoutField.setText(((SampleTimeout) el).getTimeout());
> +    }
> +
> +    /**
> +     * Initialize this component.
> +     */
> +    private void init() {
> +        setLayout(new VerticalLayout(5, VerticalLayout.BOTH,
> VerticalLayout.TOP));
> +
> +        setBorder(makeBorder());
> +        add(makeTitlePanel());
> +
> +        Box timeoutPanel = Box.createHorizontalBox();
> +        JLabel timeoutLabel = new
> JLabel(JMeterUtils.getResString("sample_timeout_timeout"));//$NON-NLS-1$
> +        timeoutPanel.add(timeoutLabel);
> +
> +        timeoutField = new JTextField(6);
> +        timeoutField.setText(DEFAULT_TIMEOUT);
> +        timeoutPanel.add(timeoutField);
> +
> +        add(timeoutPanel);
> +    }
> +
> +    /**
> +     * {@inheritDoc}
> +     */
> +    @Override
> +    public void clearGui() {
> +        timeoutField.setText(DEFAULT_TIMEOUT);
> +        super.clearGui();
> +    }
> +}
>
> Propchange:
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>
> ------------------------------------------------------------------------------
>     svn:eol-style = native
>
> Modified:
> jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>
> ==============================================================================
> --- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> (original)
> +++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> Mon Dec 14 20:52:19 2015
> @@ -914,6 +914,9 @@ sampler_on_error_start_next_loop=Start N
>  sampler_on_error_stop_test=Stop Test
>  sampler_on_error_stop_test_now=Stop Test Now
>  sampler_on_error_stop_thread=Stop Thread
> +sample_timeout_memo=Interrupt the sampler if it times out
> +sample_timeout_timeout=Sample timeout (in milliseconds)\:
> +sample_timeout_title=Sample Timeout
>  save=Save
>  save?=Save?
>  save_all_as=Save Test Plan as
>
> Modified:
> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>
> ==============================================================================
> ---
> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> (original)
> +++
> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> Mon Dec 14 20:52:19 2015
> @@ -893,6 +893,9 @@ sample_scope_children=Les ressources li\
>  sample_scope_parent=L'\u00E9chantillon
>  sample_scope_variable=Une variable \:
>  sampler_label=Libell\u00E9
> +sample_timeout_memo=Interrompre l'\u00E9chantillon si le d\u00E9lai est
> d\u00E9pass\u00E9
> +sample_timeout_timeout=D\u00E9lai d'attente avant interruption (en
> millisecondes) \:
> +sample_timeout_title=Compteur Interruption
>  sampler_on_error_action=Action \u00E0 suivre apr\u00E8s une erreur
> d'\u00E9chantillon
>  sampler_on_error_continue=Continuer
>  sampler_on_error_start_next_loop=D\u00E9marrer it\u00E9ration suivante
>
> Modified: jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java?rev=1720012&r1=1720011&r2=1720012&view=diff
>
> ==============================================================================
> --- jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
> (original)
> +++ jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java Mon Dec
> 14 20:52:19 2015
> @@ -192,7 +192,7 @@ public class SaveService {
>      private static String fileVersion = ""; // computed from
> saveservice.properties file// $NON-NLS-1$
>      // Must match the sha1 checksum of the file saveservice.properties
> (without newline character),
>      // used to ensure saveservice.properties and SaveService are updated
> simultaneously
> -    static final String FILEVERSION =
> "3136d9168702a07555b110a86f7ba4da4ab88346"; // Expected value $NON-NLS-1$
> +    static final String FILEVERSION =
> "7bc78392d5d18fc977b789d99aea6e790f9816f2"; // Expected value $NON-NLS-1$
>
>      private static String fileEncoding = ""; // read from properties
> file// $NON-NLS-1$
>
>
> Modified: jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java?rev=1720012&r1=1720011&r2=1720012&view=diff
>
> ==============================================================================
> --- jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
> (original)
> +++ jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java Mon
> Dec 14 20:52:19 2015
> @@ -65,6 +65,11 @@ import org.apache.log.Logger;
>  public class JMeterThread implements Runnable, Interruptible {
>      private static final Logger log = LoggingManager.getLoggerForClass();
>
> +    public static final boolean IMPLEMENTS_SAMPLE_STARTED =
> JMeterUtils.getPropDefault("temp.sampleStarted", true);
> +    static {
> +        log.info("IMPLEMENTS_SAMPLE_STARTED="+IMPLEMENTS_SAMPLE_STARTED);
> +    }
> +
>      public static final String PACKAGE_OBJECT = "JMeterThread.pack"; //
> $NON-NLS-1$
>
>      public static final String LAST_SAMPLE_OK =
> "JMeterThread.last_sample_ok"; // $NON-NLS-1$
> @@ -449,7 +454,24 @@ public class JMeterThread implements Run
>
>          // Perform the actual sample
>          currentSampler = sampler;
> +        if (IMPLEMENTS_SAMPLE_STARTED) {
> +            for(SampleListener listener : pack.getSampleListeners()) {
> +                try {
> +                    TestBeanHelper.prepare((TestElement) listener);
> +                    listener.sampleStarted(null);
> +                } catch (RuntimeException e) {
> +                    log.error("Detected problem in Listener: ", e);
> +                    log.info("Continuing to process further listeners");
> +                }
> +            }
> +        }
>          SampleResult result = sampler.sample(null); // TODO: remove this
> useless Entry parameter
> +        if (IMPLEMENTS_SAMPLE_STARTED) {
> +            for(SampleListener listener : pack.getSampleListeners()) {
> +                // We don't need to prepare these again here
> +                listener.sampleStopped(null);
> +            }
> +        }
>          currentSampler = null;
>
>          // If we got any results, then perform processing on the result
>
> Modified: jmeter/trunk/xdocs/changes.xml
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1720012&r1=1720011&r2=1720012&view=diff
>
> ==============================================================================
> --- jmeter/trunk/xdocs/changes.xml (original)
> +++ jmeter/trunk/xdocs/changes.xml Mon Dec 14 20:52:19 2015
> @@ -134,6 +134,7 @@ Summary
>
>  <h3>General</h3>
>  <ul>
> +<li><bug>58736</bug>Add Sample Timeout support</li>
>  <li><bug>57913</bug>Automated backups of last saved JMX files.
> Contributed by Benoit Vatan (benoit.vatan at gmail.com)</li>
>  <li><bug>57988</bug>Shortcuts
> (<keycombo><keysym>Ctrl</keysym><keysym>1</keysym></keycombo> &hellip;
>      <keycombo><keysym>Ctrl</keysym><keysym>9</keysym></keycombo>) to
> quick add elements into test plan.
>
> Added: jmeter/trunk/xdocs/images/screenshots/sample_timeout.png
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/images/screenshots/sample_timeout.png?rev=1720012&view=auto
>
> ==============================================================================
> Binary file - no diff available.
>
> Propchange: jmeter/trunk/xdocs/images/screenshots/sample_timeout.png
>
> ------------------------------------------------------------------------------
>     svn:mime-type = image/png
>
> Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
> URL:
> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1720012&r1=1720011&r2=1720012&view=diff
>
> ==============================================================================
> --- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
> +++ jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Dec 14
> 20:52:19 2015
> @@ -5613,6 +5613,36 @@ this one will be used by "<code>Calculat
>          <link href="../demos/RegEx-User-Parameters.jmx">Test Plan showing
> how to use RegEx User Parameters</link>
>  </links>
>
> +<component name="Sample Timeout" index="&sect-num;.7.11"
> anchor="interrupt" width="316" height="138" screenshot="sample_timeout.png">
> +<description>
> +<note>BETA CODE - the test element may be moved or replaced in a future
> release</note>
> +<p>This Pre-Processor schedules a timer task to interrupt a sample if it
> takes too long to complete.
> +The timeout is ignored if it is zero or negative.
> +For this to work, the sampler must implement Interruptible.
> +The following samplers are known to do so:<br></br>
> +AJP, BeanShell, FTP, HTTP, Soap, AccessLog, MailReader, JMS Subscriber,
> TCPSampler, TestAction, JavaSampler
> +</p>
> +<p>
> +The test element is intended for use where individual timeouts such as
> Connection Timeout or Response Timeout are insufficient,
> +or where the Sampler does not support timeouts.
> +The timeout should be set sufficiently long so that it is not triggered
> in normal tests, but short enough that it interrupts samples
> +that are stuck.
> +</p>
> +<p>
> +[By default, JMeter uses a Callable to interrupt the sampler.
> +This executes in the same thread as the timer, so if the interrupt takes
> a long while,
> +it may delay the processing of subsequent timeouts.
> +This is not expected to be a problem, but if necessary the property
> <code>InterruptTimer.useRunnable</code>
> +can be set to <code>true</code> to use a separate Runnable thread instead
> of the Callable.]
> +</p>
> +</description>
> +
> +<properties>
> +        <property name="Name" required="No">Descriptive name for this
> timer that is shown in the tree.</property>
> +        <property name="Sampler Timeout" required="Yes">If the sample
> takes longer to complete, it will be interrupted.</property>
> +</properties>
> +</component>
> +
>  <a href="#">^</a>
>
>  </section>
>
>
>


-- 
Cordialement.
Philippe Mouawad.

Re: svn commit: r1720012 - in /jmeter/trunk: bin/ src/components/org/apache/jmeter/modifiers/ src/components/org/apache/jmeter/modifiers/gui/ src/core/org/apache/jmeter/resources/ src/core/org/apache/jmeter/save/ src/core/org/apache/jmeter/threads/ xdocs/ ...

Posted by sebb <se...@gmail.com>.
On 18 December 2015 at 11:07, Philippe Mouawad
<p....@ubik-ingenierie.com> wrote:
> On Fri, Dec 18, 2015 at 3:22 AM, sebb <sebbaz@gmail.com
> <javascript:_e(%7B%7D,'cvml','sebbaz@gmail.com');>> wrote:
>
>> On 17 December 2015 at 22:52, Philippe Mouawad
>> <philippe.mouawad@gmail.com
>> <javascript:_e(%7B%7D,'cvml','philippe.mouawad@gmail.com');>> wrote:
>> > Hi,
>> >
>> > 1/ Looking at the code, I think there might be a  side effect of this.
>> > With this commit, in JMeterThread we now call
>> SampleListener#sampleStarted
>> > and sampleStopped around sampler.sample().
>> > It was not the case previously.
>> > There might be strange side effect if any 3rd party implements
>> > sampleStarted/sampleStopped.
>>
>> See below - the side effect is that they are now implemented.
>>
>> > By the way, I must say it's not clear for me when
>> > sampleStarted/sampleStopped were called before this commit.
>>
>> They were never called.
>>
>
> So this is an impacting change as per our usual strategy of being as much
> upward compatible as possible.

This adds functionality, so is upwards compatible.

>
>>
>> So the effect of the code change is to implement the behaviour that
>> had been promised by the interface but never delivered.
>>
>
> Yes but this has a huge impact on distributed testing, as you end up
> calling sampleStart/samplerStopped (which is an RMI call involving Network)
> for every sampling.

Now that is something I had overlooked.

> I think with this feature, distributed testing cannot scale anymore as even
> if using AsynchSampleSender or BatchSampleSender, the 2 RMI calls will
> occur for every sample.

Indeed.

> So for me, it's a BLOCKER as is and cannot go as is in next 2.14.
>

OK, I've changed the implementation to use a new interface.

>
>> > 2/ So, I wonder if it's a good idea to use this SampleListener interface
>> ?
>>
>> One could use a new interface, but is there any point?
>>
>
> The point is to avoid any side effect as per my previous note.
>
>>
>> > 3/ I also wonder if we should not split SampleListener into 2 interfaces
>> > and deprecate it (as we did with TestListener which we deprecated).
>> Indeed
>> > I looked at all implementations of it, even in 3rd party JMeterPlugins
>> and
>> > no implementation uses sampleStarted/sampleStopped, all implement
>> > sampleOccured()
>>
>> That would be fine, but it's a separate issue entirely.
>>
>
> If you want, I will open an Bugzilla for it.

It's up to you whether you think it's worth the effort.

>
>>
>> > Regards
>> > Philippe
>> >
>> >
>> > On Mon, Dec 14, 2015 at 9:52 PM, <sebb@apache.org
>> <javascript:_e(%7B%7D,'cvml','sebb@apache.org');>> wrote:
>> >
>> >> Author: sebb
>> >> Date: Mon Dec 14 20:52:19 2015
>> >> New Revision: 1720012
>> >>
>> >> URL: http://svn.apache.org/viewvc?rev=1720012&view=rev
>> >> Log:
>> >> Add Sample Timeout support
>> >> Bugzilla Id: 58736
>> >>
>> >> Added:
>> >>
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>> >>  (with props)
>> >>
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>> >>  (with props)
>> >>     jmeter/trunk/xdocs/images/screenshots/sample_timeout.png   (with
>> props)
>> >> Modified:
>> >>     jmeter/trunk/bin/jmeter.properties
>> >>     jmeter/trunk/bin/saveservice.properties
>> >>
>>  jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>> >>
>> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>> >>     jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
>> >>     jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
>> >>     jmeter/trunk/xdocs/changes.xml
>> >>     jmeter/trunk/xdocs/usermanual/component_reference.xml
>> >>
>> >> Modified: jmeter/trunk/bin/jmeter.properties
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>> >>
>> >>
>> ==============================================================================
>> >> --- jmeter/trunk/bin/jmeter.properties (original)
>> >> +++ jmeter/trunk/bin/jmeter.properties Mon Dec 14 20:52:19 2015
>> >> @@ -1035,6 +1035,11 @@ beanshell.server.file=../extras/startup.
>> >>  # Uncomment the following line to revert to the original behaviour
>> >>  #jmeterthread.reversePostProcessors=true
>> >>
>> >> +# (2.14) JMeterThread behaviour has changed: it now implements
>> >> sampleStarted/sampleStopped
>> >> +# This is necessary for the test element Sample Timeout
>> >> +# Uncomment the following line to revert to the original behaviour
>> >> (Sample Timeout will no longer work)
>> >> +#JMeterThread.sampleStarted=false
>> >> +
>> >>  # (2.2) StandardJMeterEngine behaviour has been changed to notify the
>> >> listeners after
>> >>  # the running version is enabled. This is so they can access variables.
>> >>  # In case this causes problems, the previous behaviour can be restored
>> by
>> >> uncommenting
>> >>
>> >> Modified: jmeter/trunk/bin/saveservice.properties
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/bin/saveservice.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>> >>
>> >>
>> ==============================================================================
>> >> --- jmeter/trunk/bin/saveservice.properties (original)
>> >> +++ jmeter/trunk/bin/saveservice.properties Mon Dec 14 20:52:19 2015
>> >> @@ -269,6 +269,8 @@ ResultSaverGui=org.apache.jmeter.reporte
>> >>  RunTime=org.apache.jmeter.control.RunTime
>> >>  RunTimeGui=org.apache.jmeter.control.gui.RunTimeGui
>> >>
>> SampleSaveConfiguration=org.apache.jmeter.samplers.SampleSaveConfiguration
>> >> +SampleTimeout=org.apache.jmeter.modifiers.SampleTimeout
>> >> +SampleTimeoutGui=org.apache.jmeter.modifiers.gui.SampleTimeoutGui
>> >>  SimpleConfigGui=org.apache.jmeter.config.gui.SimpleConfigGui
>> >>  SimpleDataWriter=org.apache.jmeter.visualizers.SimpleDataWriter
>> >>  SizeAssertion=org.apache.jmeter.assertions.SizeAssertion
>> >>
>> >> Added:
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java?rev=1720012&view=auto
>> >>
>> >>
>> ==============================================================================
>> >> ---
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>> >> (added)
>> >> +++
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>> >> Mon Dec 14 20:52:19 2015
>> >> @@ -0,0 +1,230 @@
>> >> +/*
>> >> + * Licensed to the Apache Software Foundation (ASF) under one or more
>> >> + * contributor license agreements.  See the NOTICE file distributed
>> with
>> >> + * this work for additional information regarding copyright ownership.
>> >> + * The ASF licenses this file to You under the Apache License, Version
>> 2.0
>> >> + * (the "License"); you may not use this file except in compliance with
>> >> + * the License.  You may obtain a copy of the License at
>> >> + *
>> >> + *   http://www.apache.org/licenses/LICENSE-2.0
>> >> + *
>> >> + * Unless required by applicable law or agreed to in writing, software
>> >> + * distributed under the License is distributed on an "AS IS" BASIS,
>> >> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>> >> implied.
>> >> + * See the License for the specific language governing permissions and
>> >> + * limitations under the License.
>> >> + *
>> >> + */
>> >> +
>> >> +package org.apache.jmeter.modifiers;
>> >> +
>> >> +import java.io.Serializable;
>> >> +import java.util.concurrent.Callable;
>> >> +import java.util.concurrent.Executors;
>> >> +import java.util.concurrent.ScheduledExecutorService;
>> >> +import java.util.concurrent.ScheduledFuture;
>> >> +import java.util.concurrent.ThreadFactory;
>> >> +import java.util.concurrent.TimeUnit;
>> >> +
>> >> +import org.apache.jmeter.samplers.Interruptible;
>> >> +import org.apache.jmeter.samplers.SampleEvent;
>> >> +import org.apache.jmeter.samplers.SampleListener;
>> >> +import org.apache.jmeter.samplers.Sampler;
>> >> +import org.apache.jmeter.testelement.AbstractTestElement;
>> >> +import org.apache.jmeter.testelement.TestElement;
>> >> +import org.apache.jmeter.testelement.ThreadListener;
>> >> +import org.apache.jmeter.threads.JMeterContext;
>> >> +import org.apache.jmeter.threads.JMeterContextService;
>> >> +import org.apache.jmeter.util.JMeterUtils;
>> >> +import org.apache.jorphan.logging.LoggingManager;
>> >> +import org.apache.log.Logger;
>> >> +
>> >> +/**
>> >> + *
>> >> + * Sample timeout implementation using Executor threads
>> >> + *
>> >> + */
>> >> +public class SampleTimeout extends AbstractTestElement implements
>> >> Serializable, ThreadListener, SampleListener {
>> >> +
>> >> +    private static final long serialVersionUID = 1L;
>> >> +
>> >> +    private static final Logger LOG =
>> LoggingManager.getLoggerForClass();
>> >> +
>> >> +    private static final String TIMEOUT = "InterruptTimer.timeout";
>> >> //$NON-NLS-1$
>> >> +
>> >> +    private final boolean useRunnable =
>> >> JMeterUtils.getPropDefault("InterruptTimer.useRunnable", false);
>> >> +
>> >> +    private static class TPOOLHolder {
>> >> +        static final ScheduledExecutorService EXEC_SERVICE =
>> >> +                Executors.newScheduledThreadPool(1,
>> >> +                        new ThreadFactory() {
>> >> +                            public Thread newThread(Runnable r) {
>> >> +                                Thread t =
>> >> Executors.defaultThreadFactory().newThread(r);
>> >> +                                t.setDaemon(true); // also ensures that
>> >> Executor thread is daemon
>> >> +                                return t;
>> >> +                            }
>> >> +                        });
>> >> +    }
>> >> +
>> >> +    private static ScheduledExecutorService getExecutorService() {
>> >> +        return TPOOLHolder.EXEC_SERVICE;
>> >> +    }
>> >> +
>> >> +    private JMeterContext context; // Cache this here to avoid
>> refetching
>> >> +
>> >> +    private ScheduledFuture<?> future;
>> >> +
>> >> +    private final transient ScheduledExecutorService execService;
>> >> +
>> >> +    private final boolean debug;
>> >> +
>> >> +    /**
>> >> +     * No-arg constructor.
>> >> +     */
>> >> +    public SampleTimeout() {
>> >> +//        LOG.setPriority(org.apache.log.Priority.DEBUG); // for local
>> >> debugging when enabled
>> >> +        debug = LOG.isDebugEnabled();
>> >> +        execService = getExecutorService();
>> >> +        if (debug) {
>> >> +            LOG.debug(whoAmI("InterruptTimer()", this));
>> >> +        }
>> >> +    }
>> >> +
>> >> +    /**
>> >> +     * Set the timeout for this timer.
>> >> +     * @param timeout The timeout for this timer
>> >> +     */
>> >> +    public void setTimeout(String timeout) {
>> >> +        setProperty(TIMEOUT, timeout);
>> >> +    }
>> >> +
>> >> +    /**
>> >> +     * Get the timeout value for display.
>> >> +     *
>> >> +     * @return the timeout value for display.
>> >> +     */
>> >> +    public String getTimeout() {
>> >> +        return getPropertyAsString(TIMEOUT);
>> >> +    }
>> >> +
>> >> +    @Override
>> >> +    public void sampleStarted(SampleEvent e) {
>> >> +        if (debug) {
>> >> +            LOG.debug(whoAmI("sampleStarted()", this));
>> >> +        }
>> >> +        createTask();
>> >> +    }
>> >> +
>> >> +    @Override
>> >> +    public void sampleStopped(SampleEvent e) {
>> >> +        if (debug) {
>> >> +            LOG.debug(whoAmI("sampleStopped()", this));
>> >> +        }
>> >> +        cancelTask();
>> >> +    }
>> >> +
>> >> +    private void createTask() {
>> >> +        long timeout = getPropertyAsLong(TIMEOUT); // refetch each time
>> >> so it can be a variable
>> >> +        if (timeout <= 0) {
>> >> +            return;
>> >> +        }
>> >> +        final Sampler samp = context.getCurrentSampler();
>> >> +        if (!(samp instanceof Interruptible)) { // may be applied to a
>> >> whole test
>> >> +            return; // Cannot time out in this case
>> >> +        }
>> >> +        final Interruptible sampler = (Interruptible) samp;
>> >> +
>> >> +        if (useRunnable) {
>> >> +            Runnable run=new Runnable() {
>> >> +                public void run() {
>> >> +                    long start = System.nanoTime();
>> >> +                    boolean interrupted = sampler.interrupt();
>> >> +                    String elapsed =
>> >> Double.toString((double)(System.nanoTime()-start)/ 1000000000)+" secs";
>> >> +                    if (interrupted) {
>> >> +                        LOG.warn("Run Done interrupting " +
>> getInfo(samp)
>> >> + " took " + elapsed);
>> >> +                    } else {
>> >> +                        if (debug) {
>> >> +                            LOG.debug("Run Didn't interrupt: " +
>> >> getInfo(samp) + " took " + elapsed);
>> >> +                        }
>> >> +                    }
>> >> +                }
>> >> +            };
>> >> +            // schedule the interrupt to occur and save for possible
>> >> cancellation
>> >> +            future = execService.schedule(run, timeout,
>> >> TimeUnit.MILLISECONDS);
>> >> +        } else {
>> >> +            Callable<Object> call = new Callable<Object>() {
>> >> +                @Override
>> >> +                public Object call() throws Exception {
>> >> +                    long start = System.nanoTime();
>> >> +                    boolean interrupted = sampler.interrupt();
>> >> +                    String elapsed =
>> >> Double.toString((double)(System.nanoTime()-start)/ 1000000000)+" secs";
>> >> +                    if (interrupted) {
>> >> +                        LOG.warn("Call Done interrupting " +
>> >> getInfo(samp) + " took " + elapsed);
>> >> +                    } else {
>> >> +                        if (debug) {
>> >> +                            LOG.debug("Call Didn't interrupt: " +
>> >> getInfo(samp) + " took " + elapsed);
>> >> +                        }
>> >> +                    }
>> >> +                    return null;
>> >> +                }
>> >> +
>> >> +            };
>> >> +            // schedule the interrupt to occur and save for possible
>> >> cancellation
>> >> +            future = execService.schedule(call, timeout,
>> >> TimeUnit.MILLISECONDS);
>> >> +        }
>> >> +        if (debug) {
>> >> +            LOG.debug("Scheduled timer: @" +
>> >> System.identityHashCode(future) + " " + getInfo(samp));
>> >> +        }
>> >> +    }
>> >> +
>> >> +    @Override
>> >> +    public void threadStarted() {
>> >> +        if (debug) {
>> >> +            LOG.debug(whoAmI("threadStarted()", this));
>> >> +        }
>> >> +        context = JMeterContextService.getContext();
>> >> +     }
>> >> +
>> >> +    @Override
>> >> +    public void threadFinished() {
>> >> +        if (debug) {
>> >> +            LOG.debug(whoAmI("threadFinished()", this));
>> >> +        }
>> >> +        cancelTask(); // cancel final if any
>> >> +     }
>> >> +
>> >> +    /**
>> >> +     * Provide a description of this class.
>> >> +     *
>> >> +     * @return the description of this class.
>> >> +     */
>> >> +    @Override
>> >> +    public String toString() {
>> >> +        return JMeterUtils.getResString("sample_timeout_memo");
>> >> //$NON-NLS-1$
>> >> +    }
>> >> +
>> >> +    private String whoAmI(String id, TestElement o) {
>> >> +        return id + " @" + System.identityHashCode(o)+ " '"+
>> o.getName()
>> >> + "' " + (debug ?  Thread.currentThread().getName() : "");
>> >> +    }
>> >> +
>> >> +    private String getInfo(TestElement o) {
>> >> +        return whoAmI(o.getClass().getSimpleName(), o);
>> >> +    }
>> >> +
>> >> +    private void cancelTask() {
>> >> +        if (future != null) {
>> >> +            if (!future.isDone()) {
>> >> +                boolean cancelled = future.cancel(false);
>> >> +                if (debug) {
>> >> +                    LOG.debug("Cancelled timer: @" +
>> >> System.identityHashCode(future) + " with result " + cancelled);
>> >> +                }
>> >> +            }
>> >> +            future = null;
>> >> +        }
>> >> +    }
>> >> +
>> >> +    @Override
>> >> +    public void sampleOccurred(SampleEvent e) {
>> >> +        // Not used
>> >> +    }
>> >> +}
>> >>
>> >> Propchange:
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>> >>
>> >>
>> ------------------------------------------------------------------------------
>> >>     svn:eol-style = native
>> >>
>> >> Added:
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java?rev=1720012&view=auto
>> >>
>> >>
>> ==============================================================================
>> >> ---
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>> >> (added)
>> >> +++
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>> >> Mon Dec 14 20:52:19 2015
>> >> @@ -0,0 +1,133 @@
>> >> +/*
>> >> + * Licensed to the Apache Software Foundation (ASF) under one or more
>> >> + * contributor license agreements.  See the NOTICE file distributed
>> with
>> >> + * this work for additional information regarding copyright ownership.
>> >> + * The ASF licenses this file to You under the Apache License, Version
>> 2.0
>> >> + * (the "License"); you may not use this file except in compliance with
>> >> + * the License.  You may obtain a copy of the License at
>> >> + *
>> >> + *   http://www.apache.org/licenses/LICENSE-2.0
>> >> + *
>> >> + * Unless required by applicable law or agreed to in writing, software
>> >> + * distributed under the License is distributed on an "AS IS" BASIS,
>> >> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>> >> implied.
>> >> + * See the License for the specific language governing permissions and
>> >> + * limitations under the License.
>> >> + *
>> >> + */
>> >> +
>> >> +package org.apache.jmeter.modifiers.gui;
>> >> +
>> >> +import javax.swing.Box;
>> >> +import javax.swing.JComponent;
>> >> +import javax.swing.JLabel;
>> >> +import javax.swing.JOptionPane;
>> >> +import javax.swing.JTextField;
>> >> +
>> >> +import org.apache.jmeter.modifiers.SampleTimeout;
>> >> +import org.apache.jmeter.processor.gui.AbstractPreProcessorGui;
>> >> +import org.apache.jmeter.testelement.TestElement;
>> >> +import org.apache.jmeter.util.JMeterUtils;
>> >> +import org.apache.jorphan.gui.layout.VerticalLayout;
>> >> +
>> >> +/**
>> >> + * The GUI for SampleTimeout.
>> >> + */
>> >> +public class SampleTimeoutGui extends AbstractPreProcessorGui {
>> >> +
>> >> +    private static final long serialVersionUID = 240L;
>> >> +
>> >> +    /**
>> >> +     * The default value for the timeout.
>> >> +     */
>> >> +    private static final String DEFAULT_TIMEOUT = "10000";
>> >> +
>> >> +    private JTextField timeoutField;
>> >> +
>> >> +    /**
>> >> +     * No-arg constructor.
>> >> +     */
>> >> +    public SampleTimeoutGui() {
>> >> +        init();
>> >> +    }
>> >> +
>> >> +    /**
>> >> +     * Handle an error.
>> >> +     *
>> >> +     * @param e
>> >> +     *            the Exception that was thrown.
>> >> +     * @param thrower
>> >> +     *            the JComponent that threw the Exception.
>> >> +     */
>> >> +    public static void error(Exception e, JComponent thrower) {
>> >> +        JOptionPane.showMessageDialog(thrower, e, "Error",
>> >> JOptionPane.ERROR_MESSAGE);
>> >> +    }
>> >> +
>> >> +    @Override
>> >> +    public String getLabelResource() {
>> >> +        return "sample_timeout_title"; // $NON-NLS-1$
>> >> +    }
>> >> +
>> >> +    /**
>> >> +     * Create the test element underlying this GUI component.
>> >> +     *
>> >> +     * @see
>> org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()
>> >> +     */
>> >> +    @Override
>> >> +    public TestElement createTestElement() {
>> >> +        SampleTimeout timer = new SampleTimeout();
>> >> +        modifyTestElement(timer);
>> >> +        return timer;
>> >> +    }
>> >> +
>> >> +    /**
>> >> +     * Modifies a given TestElement to mirror the data in the gui
>> >> components.
>> >> +     *
>> >> +     * @see
>> >> org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
>> >> +     */
>> >> +    @Override
>> >> +    public void modifyTestElement(TestElement timer) {
>> >> +        this.configureTestElement(timer);
>> >> +        ((SampleTimeout) timer).setTimeout(timeoutField.getText());
>> >> +    }
>> >> +
>> >> +    /**
>> >> +     * Configure this GUI component from the underlying TestElement.
>> >> +     *
>> >> +     * @see
>> >> org.apache.jmeter.gui.JMeterGUIComponent#configure(TestElement)
>> >> +     */
>> >> +    @Override
>> >> +    public void configure(TestElement el) {
>> >> +        super.configure(el);
>> >> +        timeoutField.setText(((SampleTimeout) el).getTimeout());
>> >> +    }
>> >> +
>> >> +    /**
>> >> +     * Initialize this component.
>> >> +     */
>> >> +    private void init() {
>> >> +        setLayout(new VerticalLayout(5, VerticalLayout.BOTH,
>> >> VerticalLayout.TOP));
>> >> +
>> >> +        setBorder(makeBorder());
>> >> +        add(makeTitlePanel());
>> >> +
>> >> +        Box timeoutPanel = Box.createHorizontalBox();
>> >> +        JLabel timeoutLabel = new
>> >> JLabel(JMeterUtils.getResString("sample_timeout_timeout"));//$NON-NLS-1$
>> >> +        timeoutPanel.add(timeoutLabel);
>> >> +
>> >> +        timeoutField = new JTextField(6);
>> >> +        timeoutField.setText(DEFAULT_TIMEOUT);
>> >> +        timeoutPanel.add(timeoutField);
>> >> +
>> >> +        add(timeoutPanel);
>> >> +    }
>> >> +
>> >> +    /**
>> >> +     * {@inheritDoc}
>> >> +     */
>> >> +    @Override
>> >> +    public void clearGui() {
>> >> +        timeoutField.setText(DEFAULT_TIMEOUT);
>> >> +        super.clearGui();
>> >> +    }
>> >> +}
>> >>
>> >> Propchange:
>> >>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>> >>
>> >>
>> ------------------------------------------------------------------------------
>> >>     svn:eol-style = native
>> >>
>> >> Modified:
>> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>> >>
>> >>
>> ==============================================================================
>> >> ---
>> jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>> >> (original)
>> >> +++
>> jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>> >> Mon Dec 14 20:52:19 2015
>> >> @@ -914,6 +914,9 @@ sampler_on_error_start_next_loop=Start N
>> >>  sampler_on_error_stop_test=Stop Test
>> >>  sampler_on_error_stop_test_now=Stop Test Now
>> >>  sampler_on_error_stop_thread=Stop Thread
>> >> +sample_timeout_memo=Interrupt the sampler if it times out
>> >> +sample_timeout_timeout=Sample timeout (in milliseconds)\:
>> >> +sample_timeout_title=Sample Timeout
>> >>  save=Save
>> >>  save?=Save?
>> >>  save_all_as=Save Test Plan as
>> >>
>> >> Modified:
>> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>> >>
>> >>
>> ==============================================================================
>> >> ---
>> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>> >> (original)
>> >> +++
>> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>> >> Mon Dec 14 20:52:19 2015
>> >> @@ -893,6 +893,9 @@ sample_scope_children=Les ressources li\
>> >>  sample_scope_parent=L'\u00E9chantillon
>> >>  sample_scope_variable=Une variable \:
>> >>  sampler_label=Libell\u00E9
>> >> +sample_timeout_memo=Interrompre l'\u00E9chantillon si le d\u00E9lai est
>> >> d\u00E9pass\u00E9
>> >> +sample_timeout_timeout=D\u00E9lai d'attente avant interruption (en
>> >> millisecondes) \:
>> >> +sample_timeout_title=Compteur Interruption
>> >>  sampler_on_error_action=Action \u00E0 suivre apr\u00E8s une erreur
>> >> d'\u00E9chantillon
>> >>  sampler_on_error_continue=Continuer
>> >>  sampler_on_error_start_next_loop=D\u00E9marrer it\u00E9ration suivante
>> >>
>> >> Modified: jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java?rev=1720012&r1=1720011&r2=1720012&view=diff
>> >>
>> >>
>> ==============================================================================
>> >> --- jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
>> >> (original)
>> >> +++ jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java Mon
>> Dec
>> >> 14 20:52:19 2015
>> >> @@ -192,7 +192,7 @@ public class SaveService {
>> >>      private static String fileVersion = ""; // computed from
>> >> saveservice.properties file// $NON-NLS-1$
>> >>      // Must match the sha1 checksum of the file saveservice.properties
>> >> (without newline character),
>> >>      // used to ensure saveservice.properties and SaveService are
>> updated
>> >> simultaneously
>> >> -    static final String FILEVERSION =
>> >> "3136d9168702a07555b110a86f7ba4da4ab88346"; // Expected value
>> $NON-NLS-1$
>> >> +    static final String FILEVERSION =
>> >> "7bc78392d5d18fc977b789d99aea6e790f9816f2"; // Expected value
>> $NON-NLS-1$
>> >>
>> >>      private static String fileEncoding = ""; // read from properties
>> >> file// $NON-NLS-1$
>> >>
>> >>
>> >> Modified:
>> jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java?rev=1720012&r1=1720011&r2=1720012&view=diff
>> >>
>> >>
>> ==============================================================================
>> >> --- jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
>> >> (original)
>> >> +++ jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
>> Mon
>> >> Dec 14 20:52:19 2015
>> >> @@ -65,6 +65,11 @@ import org.apache.log.Logger;
>> >>  public class JMeterThread implements Runnable, Interruptible {
>> >>      private static final Logger log =
>> LoggingManager.getLoggerForClass();
>> >>
>> >> +    public static final boolean IMPLEMENTS_SAMPLE_STARTED =
>> >> JMeterUtils.getPropDefault("temp.sampleStarted", true);
>> >> +    static {
>> >> +        log.info
>> ("IMPLEMENTS_SAMPLE_STARTED="+IMPLEMENTS_SAMPLE_STARTED);
>> >> +    }
>> >> +
>> >>      public static final String PACKAGE_OBJECT = "JMeterThread.pack"; //
>> >> $NON-NLS-1$
>> >>
>> >>      public static final String LAST_SAMPLE_OK =
>> >> "JMeterThread.last_sample_ok"; // $NON-NLS-1$
>> >> @@ -449,7 +454,24 @@ public class JMeterThread implements Run
>> >>
>> >>          // Perform the actual sample
>> >>          currentSampler = sampler;
>> >> +        if (IMPLEMENTS_SAMPLE_STARTED) {
>> >> +            for(SampleListener listener : pack.getSampleListeners()) {
>> >> +                try {
>> >> +                    TestBeanHelper.prepare((TestElement) listener);
>> >> +                    listener.sampleStarted(null);
>> >> +                } catch (RuntimeException e) {
>> >> +                    log.error("Detected problem in Listener: ", e);
>> >> +                    log.info("Continuing to process further
>> listeners");
>> >> +                }
>> >> +            }
>> >> +        }
>> >>          SampleResult result = sampler.sample(null); // TODO: remove
>> this
>> >> useless Entry parameter
>> >> +        if (IMPLEMENTS_SAMPLE_STARTED) {
>> >> +            for(SampleListener listener : pack.getSampleListeners()) {
>> >> +                // We don't need to prepare these again here
>> >> +                listener.sampleStopped(null);
>> >> +            }
>> >> +        }
>> >>          currentSampler = null;
>> >>
>> >>          // If we got any results, then perform processing on the result
>> >>
>> >> Modified: jmeter/trunk/xdocs/changes.xml
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1720012&r1=1720011&r2=1720012&view=diff
>> >>
>> >>
>> ==============================================================================
>> >> --- jmeter/trunk/xdocs/changes.xml (original)
>> >> +++ jmeter/trunk/xdocs/changes.xml Mon Dec 14 20:52:19 2015
>> >> @@ -134,6 +134,7 @@ Summary
>> >>
>> >>  <h3>General</h3>
>> >>  <ul>
>> >> +<li><bug>58736</bug>Add Sample Timeout support</li>
>> >>  <li><bug>57913</bug>Automated backups of last saved JMX files.
>> >> Contributed by Benoit Vatan (benoit.vatan at gmail.com)</li>
>> >>  <li><bug>57988</bug>Shortcuts
>> >> (<keycombo><keysym>Ctrl</keysym><keysym>1</keysym></keycombo> &hellip;
>> >>      <keycombo><keysym>Ctrl</keysym><keysym>9</keysym></keycombo>) to
>> >> quick add elements into test plan.
>> >>
>> >> Added: jmeter/trunk/xdocs/images/screenshots/sample_timeout.png
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/images/screenshots/sample_timeout.png?rev=1720012&view=auto
>> >>
>> >>
>> ==============================================================================
>> >> Binary file - no diff available.
>> >>
>> >> Propchange: jmeter/trunk/xdocs/images/screenshots/sample_timeout.png
>> >>
>> >>
>> ------------------------------------------------------------------------------
>> >>     svn:mime-type = image/png
>> >>
>> >> Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
>> >> URL:
>> >>
>> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1720012&r1=1720011&r2=1720012&view=diff
>> >>
>> >>
>> ==============================================================================
>> >> --- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
>> >> +++ jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Dec 14
>> >> 20:52:19 2015
>> >> @@ -5613,6 +5613,36 @@ this one will be used by "<code>Calculat
>> >>          <link href="../demos/RegEx-User-Parameters.jmx">Test Plan
>> showing
>> >> how to use RegEx User Parameters</link>
>> >>  </links>
>> >>
>> >> +<component name="Sample Timeout" index="&sect-num;.7.11"
>> >> anchor="interrupt" width="316" height="138"
>> screenshot="sample_timeout.png">
>> >> +<description>
>> >> +<note>BETA CODE - the test element may be moved or replaced in a future
>> >> release</note>
>> >> +<p>This Pre-Processor schedules a timer task to interrupt a sample if
>> it
>> >> takes too long to complete.
>> >> +The timeout is ignored if it is zero or negative.
>> >> +For this to work, the sampler must implement Interruptible.
>> >> +The following samplers are known to do so:<br></br>
>> >> +AJP, BeanShell, FTP, HTTP, Soap, AccessLog, MailReader, JMS Subscriber,
>> >> TCPSampler, TestAction, JavaSampler
>> >> +</p>
>> >> +<p>
>> >> +The test element is intended for use where individual timeouts such as
>> >> Connection Timeout or Response Timeout are insufficient,
>> >> +or where the Sampler does not support timeouts.
>> >> +The timeout should be set sufficiently long so that it is not triggered
>> >> in normal tests, but short enough that it interrupts samples
>> >> +that are stuck.
>> >> +</p>
>> >> +<p>
>> >> +[By default, JMeter uses a Callable to interrupt the sampler.
>> >> +This executes in the same thread as the timer, so if the interrupt
>> takes
>> >> a long while,
>> >> +it may delay the processing of subsequent timeouts.
>> >> +This is not expected to be a problem, but if necessary the property
>> >> <code>InterruptTimer.useRunnable</code>
>> >> +can be set to <code>true</code> to use a separate Runnable thread
>> instead
>> >> of the Callable.]
>> >> +</p>
>> >> +</description>
>> >> +
>> >> +<properties>
>> >> +        <property name="Name" required="No">Descriptive name for this
>> >> timer that is shown in the tree.</property>
>> >> +        <property name="Sampler Timeout" required="Yes">If the sample
>> >> takes longer to complete, it will be interrupted.</property>
>> >> +</properties>
>> >> +</component>
>> >> +
>> >>  <a href="#">^</a>
>> >>
>> >>  </section>
>> >>
>> >>
>> >>
>> >
>> >
>> > --
>> > Cordialement.
>> > Philippe Mouawad.
>>
>
>
>
> --
>
>
>
> --
> Cordialement.
> Philippe Mouawad.
> Ubik-Ingénierie
>
> UBIK LOAD PACK Web Site <http://www.ubikloadpack.com/>
>
> UBIK LOAD PACK on TWITTER <https://twitter.com/ubikloadpack>

svn commit: r1720012 - in /jmeter/trunk: bin/ src/components/org/apache/jmeter/modifiers/ src/components/org/apache/jmeter/modifiers/gui/ src/core/org/apache/jmeter/resources/ src/core/org/apache/jmeter/save/ src/core/org/apache/jmeter/threads/ xdocs/ ...

Posted by Philippe Mouawad <p....@ubik-ingenierie.com>.
On Fri, Dec 18, 2015 at 3:22 AM, sebb <sebbaz@gmail.com
<javascript:_e(%7B%7D,'cvml','sebbaz@gmail.com');>> wrote:

> On 17 December 2015 at 22:52, Philippe Mouawad
> <philippe.mouawad@gmail.com
> <javascript:_e(%7B%7D,'cvml','philippe.mouawad@gmail.com');>> wrote:
> > Hi,
> >
> > 1/ Looking at the code, I think there might be a  side effect of this.
> > With this commit, in JMeterThread we now call
> SampleListener#sampleStarted
> > and sampleStopped around sampler.sample().
> > It was not the case previously.
> > There might be strange side effect if any 3rd party implements
> > sampleStarted/sampleStopped.
>
> See below - the side effect is that they are now implemented.
>
> > By the way, I must say it's not clear for me when
> > sampleStarted/sampleStopped were called before this commit.
>
> They were never called.
>

So this is an impacting change as per our usual strategy of being as much
upward compatible as possible.


>
> So the effect of the code change is to implement the behaviour that
> had been promised by the interface but never delivered.
>

Yes but this has a huge impact on distributed testing, as you end up
calling sampleStart/samplerStopped (which is an RMI call involving Network)
for every sampling.
I think with this feature, distributed testing cannot scale anymore as even
if using AsynchSampleSender or BatchSampleSender, the 2 RMI calls will
occur for every sample.

So for me, it's a BLOCKER as is and cannot go as is in next 2.14.



> > 2/ So, I wonder if it's a good idea to use this SampleListener interface
> ?
>
> One could use a new interface, but is there any point?
>

The point is to avoid any side effect as per my previous note.

>
> > 3/ I also wonder if we should not split SampleListener into 2 interfaces
> > and deprecate it (as we did with TestListener which we deprecated).
> Indeed
> > I looked at all implementations of it, even in 3rd party JMeterPlugins
> and
> > no implementation uses sampleStarted/sampleStopped, all implement
> > sampleOccured()
>
> That would be fine, but it's a separate issue entirely.
>

If you want, I will open an Bugzilla for it.


>
> > Regards
> > Philippe
> >
> >
> > On Mon, Dec 14, 2015 at 9:52 PM, <sebb@apache.org
> <javascript:_e(%7B%7D,'cvml','sebb@apache.org');>> wrote:
> >
> >> Author: sebb
> >> Date: Mon Dec 14 20:52:19 2015
> >> New Revision: 1720012
> >>
> >> URL: http://svn.apache.org/viewvc?rev=1720012&view=rev
> >> Log:
> >> Add Sample Timeout support
> >> Bugzilla Id: 58736
> >>
> >> Added:
> >>
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
> >>  (with props)
> >>
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
> >>  (with props)
> >>     jmeter/trunk/xdocs/images/screenshots/sample_timeout.png   (with
> props)
> >> Modified:
> >>     jmeter/trunk/bin/jmeter.properties
> >>     jmeter/trunk/bin/saveservice.properties
> >>
>  jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> >>
> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> >>     jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
> >>     jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
> >>     jmeter/trunk/xdocs/changes.xml
> >>     jmeter/trunk/xdocs/usermanual/component_reference.xml
> >>
> >> Modified: jmeter/trunk/bin/jmeter.properties
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
> >>
> >>
> ==============================================================================
> >> --- jmeter/trunk/bin/jmeter.properties (original)
> >> +++ jmeter/trunk/bin/jmeter.properties Mon Dec 14 20:52:19 2015
> >> @@ -1035,6 +1035,11 @@ beanshell.server.file=../extras/startup.
> >>  # Uncomment the following line to revert to the original behaviour
> >>  #jmeterthread.reversePostProcessors=true
> >>
> >> +# (2.14) JMeterThread behaviour has changed: it now implements
> >> sampleStarted/sampleStopped
> >> +# This is necessary for the test element Sample Timeout
> >> +# Uncomment the following line to revert to the original behaviour
> >> (Sample Timeout will no longer work)
> >> +#JMeterThread.sampleStarted=false
> >> +
> >>  # (2.2) StandardJMeterEngine behaviour has been changed to notify the
> >> listeners after
> >>  # the running version is enabled. This is so they can access variables.
> >>  # In case this causes problems, the previous behaviour can be restored
> by
> >> uncommenting
> >>
> >> Modified: jmeter/trunk/bin/saveservice.properties
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/bin/saveservice.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
> >>
> >>
> ==============================================================================
> >> --- jmeter/trunk/bin/saveservice.properties (original)
> >> +++ jmeter/trunk/bin/saveservice.properties Mon Dec 14 20:52:19 2015
> >> @@ -269,6 +269,8 @@ ResultSaverGui=org.apache.jmeter.reporte
> >>  RunTime=org.apache.jmeter.control.RunTime
> >>  RunTimeGui=org.apache.jmeter.control.gui.RunTimeGui
> >>
> SampleSaveConfiguration=org.apache.jmeter.samplers.SampleSaveConfiguration
> >> +SampleTimeout=org.apache.jmeter.modifiers.SampleTimeout
> >> +SampleTimeoutGui=org.apache.jmeter.modifiers.gui.SampleTimeoutGui
> >>  SimpleConfigGui=org.apache.jmeter.config.gui.SimpleConfigGui
> >>  SimpleDataWriter=org.apache.jmeter.visualizers.SimpleDataWriter
> >>  SizeAssertion=org.apache.jmeter.assertions.SizeAssertion
> >>
> >> Added:
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java?rev=1720012&view=auto
> >>
> >>
> ==============================================================================
> >> ---
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
> >> (added)
> >> +++
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
> >> Mon Dec 14 20:52:19 2015
> >> @@ -0,0 +1,230 @@
> >> +/*
> >> + * Licensed to the Apache Software Foundation (ASF) under one or more
> >> + * contributor license agreements.  See the NOTICE file distributed
> with
> >> + * this work for additional information regarding copyright ownership.
> >> + * The ASF licenses this file to You under the Apache License, Version
> 2.0
> >> + * (the "License"); you may not use this file except in compliance with
> >> + * the License.  You may obtain a copy of the License at
> >> + *
> >> + *   http://www.apache.org/licenses/LICENSE-2.0
> >> + *
> >> + * Unless required by applicable law or agreed to in writing, software
> >> + * distributed under the License is distributed on an "AS IS" BASIS,
> >> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> >> implied.
> >> + * See the License for the specific language governing permissions and
> >> + * limitations under the License.
> >> + *
> >> + */
> >> +
> >> +package org.apache.jmeter.modifiers;
> >> +
> >> +import java.io.Serializable;
> >> +import java.util.concurrent.Callable;
> >> +import java.util.concurrent.Executors;
> >> +import java.util.concurrent.ScheduledExecutorService;
> >> +import java.util.concurrent.ScheduledFuture;
> >> +import java.util.concurrent.ThreadFactory;
> >> +import java.util.concurrent.TimeUnit;
> >> +
> >> +import org.apache.jmeter.samplers.Interruptible;
> >> +import org.apache.jmeter.samplers.SampleEvent;
> >> +import org.apache.jmeter.samplers.SampleListener;
> >> +import org.apache.jmeter.samplers.Sampler;
> >> +import org.apache.jmeter.testelement.AbstractTestElement;
> >> +import org.apache.jmeter.testelement.TestElement;
> >> +import org.apache.jmeter.testelement.ThreadListener;
> >> +import org.apache.jmeter.threads.JMeterContext;
> >> +import org.apache.jmeter.threads.JMeterContextService;
> >> +import org.apache.jmeter.util.JMeterUtils;
> >> +import org.apache.jorphan.logging.LoggingManager;
> >> +import org.apache.log.Logger;
> >> +
> >> +/**
> >> + *
> >> + * Sample timeout implementation using Executor threads
> >> + *
> >> + */
> >> +public class SampleTimeout extends AbstractTestElement implements
> >> Serializable, ThreadListener, SampleListener {
> >> +
> >> +    private static final long serialVersionUID = 1L;
> >> +
> >> +    private static final Logger LOG =
> LoggingManager.getLoggerForClass();
> >> +
> >> +    private static final String TIMEOUT = "InterruptTimer.timeout";
> >> //$NON-NLS-1$
> >> +
> >> +    private final boolean useRunnable =
> >> JMeterUtils.getPropDefault("InterruptTimer.useRunnable", false);
> >> +
> >> +    private static class TPOOLHolder {
> >> +        static final ScheduledExecutorService EXEC_SERVICE =
> >> +                Executors.newScheduledThreadPool(1,
> >> +                        new ThreadFactory() {
> >> +                            public Thread newThread(Runnable r) {
> >> +                                Thread t =
> >> Executors.defaultThreadFactory().newThread(r);
> >> +                                t.setDaemon(true); // also ensures that
> >> Executor thread is daemon
> >> +                                return t;
> >> +                            }
> >> +                        });
> >> +    }
> >> +
> >> +    private static ScheduledExecutorService getExecutorService() {
> >> +        return TPOOLHolder.EXEC_SERVICE;
> >> +    }
> >> +
> >> +    private JMeterContext context; // Cache this here to avoid
> refetching
> >> +
> >> +    private ScheduledFuture<?> future;
> >> +
> >> +    private final transient ScheduledExecutorService execService;
> >> +
> >> +    private final boolean debug;
> >> +
> >> +    /**
> >> +     * No-arg constructor.
> >> +     */
> >> +    public SampleTimeout() {
> >> +//        LOG.setPriority(org.apache.log.Priority.DEBUG); // for local
> >> debugging when enabled
> >> +        debug = LOG.isDebugEnabled();
> >> +        execService = getExecutorService();
> >> +        if (debug) {
> >> +            LOG.debug(whoAmI("InterruptTimer()", this));
> >> +        }
> >> +    }
> >> +
> >> +    /**
> >> +     * Set the timeout for this timer.
> >> +     * @param timeout The timeout for this timer
> >> +     */
> >> +    public void setTimeout(String timeout) {
> >> +        setProperty(TIMEOUT, timeout);
> >> +    }
> >> +
> >> +    /**
> >> +     * Get the timeout value for display.
> >> +     *
> >> +     * @return the timeout value for display.
> >> +     */
> >> +    public String getTimeout() {
> >> +        return getPropertyAsString(TIMEOUT);
> >> +    }
> >> +
> >> +    @Override
> >> +    public void sampleStarted(SampleEvent e) {
> >> +        if (debug) {
> >> +            LOG.debug(whoAmI("sampleStarted()", this));
> >> +        }
> >> +        createTask();
> >> +    }
> >> +
> >> +    @Override
> >> +    public void sampleStopped(SampleEvent e) {
> >> +        if (debug) {
> >> +            LOG.debug(whoAmI("sampleStopped()", this));
> >> +        }
> >> +        cancelTask();
> >> +    }
> >> +
> >> +    private void createTask() {
> >> +        long timeout = getPropertyAsLong(TIMEOUT); // refetch each time
> >> so it can be a variable
> >> +        if (timeout <= 0) {
> >> +            return;
> >> +        }
> >> +        final Sampler samp = context.getCurrentSampler();
> >> +        if (!(samp instanceof Interruptible)) { // may be applied to a
> >> whole test
> >> +            return; // Cannot time out in this case
> >> +        }
> >> +        final Interruptible sampler = (Interruptible) samp;
> >> +
> >> +        if (useRunnable) {
> >> +            Runnable run=new Runnable() {
> >> +                public void run() {
> >> +                    long start = System.nanoTime();
> >> +                    boolean interrupted = sampler.interrupt();
> >> +                    String elapsed =
> >> Double.toString((double)(System.nanoTime()-start)/ 1000000000)+" secs";
> >> +                    if (interrupted) {
> >> +                        LOG.warn("Run Done interrupting " +
> getInfo(samp)
> >> + " took " + elapsed);
> >> +                    } else {
> >> +                        if (debug) {
> >> +                            LOG.debug("Run Didn't interrupt: " +
> >> getInfo(samp) + " took " + elapsed);
> >> +                        }
> >> +                    }
> >> +                }
> >> +            };
> >> +            // schedule the interrupt to occur and save for possible
> >> cancellation
> >> +            future = execService.schedule(run, timeout,
> >> TimeUnit.MILLISECONDS);
> >> +        } else {
> >> +            Callable<Object> call = new Callable<Object>() {
> >> +                @Override
> >> +                public Object call() throws Exception {
> >> +                    long start = System.nanoTime();
> >> +                    boolean interrupted = sampler.interrupt();
> >> +                    String elapsed =
> >> Double.toString((double)(System.nanoTime()-start)/ 1000000000)+" secs";
> >> +                    if (interrupted) {
> >> +                        LOG.warn("Call Done interrupting " +
> >> getInfo(samp) + " took " + elapsed);
> >> +                    } else {
> >> +                        if (debug) {
> >> +                            LOG.debug("Call Didn't interrupt: " +
> >> getInfo(samp) + " took " + elapsed);
> >> +                        }
> >> +                    }
> >> +                    return null;
> >> +                }
> >> +
> >> +            };
> >> +            // schedule the interrupt to occur and save for possible
> >> cancellation
> >> +            future = execService.schedule(call, timeout,
> >> TimeUnit.MILLISECONDS);
> >> +        }
> >> +        if (debug) {
> >> +            LOG.debug("Scheduled timer: @" +
> >> System.identityHashCode(future) + " " + getInfo(samp));
> >> +        }
> >> +    }
> >> +
> >> +    @Override
> >> +    public void threadStarted() {
> >> +        if (debug) {
> >> +            LOG.debug(whoAmI("threadStarted()", this));
> >> +        }
> >> +        context = JMeterContextService.getContext();
> >> +     }
> >> +
> >> +    @Override
> >> +    public void threadFinished() {
> >> +        if (debug) {
> >> +            LOG.debug(whoAmI("threadFinished()", this));
> >> +        }
> >> +        cancelTask(); // cancel final if any
> >> +     }
> >> +
> >> +    /**
> >> +     * Provide a description of this class.
> >> +     *
> >> +     * @return the description of this class.
> >> +     */
> >> +    @Override
> >> +    public String toString() {
> >> +        return JMeterUtils.getResString("sample_timeout_memo");
> >> //$NON-NLS-1$
> >> +    }
> >> +
> >> +    private String whoAmI(String id, TestElement o) {
> >> +        return id + " @" + System.identityHashCode(o)+ " '"+
> o.getName()
> >> + "' " + (debug ?  Thread.currentThread().getName() : "");
> >> +    }
> >> +
> >> +    private String getInfo(TestElement o) {
> >> +        return whoAmI(o.getClass().getSimpleName(), o);
> >> +    }
> >> +
> >> +    private void cancelTask() {
> >> +        if (future != null) {
> >> +            if (!future.isDone()) {
> >> +                boolean cancelled = future.cancel(false);
> >> +                if (debug) {
> >> +                    LOG.debug("Cancelled timer: @" +
> >> System.identityHashCode(future) + " with result " + cancelled);
> >> +                }
> >> +            }
> >> +            future = null;
> >> +        }
> >> +    }
> >> +
> >> +    @Override
> >> +    public void sampleOccurred(SampleEvent e) {
> >> +        // Not used
> >> +    }
> >> +}
> >>
> >> Propchange:
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
> >>
> >>
> ------------------------------------------------------------------------------
> >>     svn:eol-style = native
> >>
> >> Added:
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java?rev=1720012&view=auto
> >>
> >>
> ==============================================================================
> >> ---
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
> >> (added)
> >> +++
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
> >> Mon Dec 14 20:52:19 2015
> >> @@ -0,0 +1,133 @@
> >> +/*
> >> + * Licensed to the Apache Software Foundation (ASF) under one or more
> >> + * contributor license agreements.  See the NOTICE file distributed
> with
> >> + * this work for additional information regarding copyright ownership.
> >> + * The ASF licenses this file to You under the Apache License, Version
> 2.0
> >> + * (the "License"); you may not use this file except in compliance with
> >> + * the License.  You may obtain a copy of the License at
> >> + *
> >> + *   http://www.apache.org/licenses/LICENSE-2.0
> >> + *
> >> + * Unless required by applicable law or agreed to in writing, software
> >> + * distributed under the License is distributed on an "AS IS" BASIS,
> >> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> >> implied.
> >> + * See the License for the specific language governing permissions and
> >> + * limitations under the License.
> >> + *
> >> + */
> >> +
> >> +package org.apache.jmeter.modifiers.gui;
> >> +
> >> +import javax.swing.Box;
> >> +import javax.swing.JComponent;
> >> +import javax.swing.JLabel;
> >> +import javax.swing.JOptionPane;
> >> +import javax.swing.JTextField;
> >> +
> >> +import org.apache.jmeter.modifiers.SampleTimeout;
> >> +import org.apache.jmeter.processor.gui.AbstractPreProcessorGui;
> >> +import org.apache.jmeter.testelement.TestElement;
> >> +import org.apache.jmeter.util.JMeterUtils;
> >> +import org.apache.jorphan.gui.layout.VerticalLayout;
> >> +
> >> +/**
> >> + * The GUI for SampleTimeout.
> >> + */
> >> +public class SampleTimeoutGui extends AbstractPreProcessorGui {
> >> +
> >> +    private static final long serialVersionUID = 240L;
> >> +
> >> +    /**
> >> +     * The default value for the timeout.
> >> +     */
> >> +    private static final String DEFAULT_TIMEOUT = "10000";
> >> +
> >> +    private JTextField timeoutField;
> >> +
> >> +    /**
> >> +     * No-arg constructor.
> >> +     */
> >> +    public SampleTimeoutGui() {
> >> +        init();
> >> +    }
> >> +
> >> +    /**
> >> +     * Handle an error.
> >> +     *
> >> +     * @param e
> >> +     *            the Exception that was thrown.
> >> +     * @param thrower
> >> +     *            the JComponent that threw the Exception.
> >> +     */
> >> +    public static void error(Exception e, JComponent thrower) {
> >> +        JOptionPane.showMessageDialog(thrower, e, "Error",
> >> JOptionPane.ERROR_MESSAGE);
> >> +    }
> >> +
> >> +    @Override
> >> +    public String getLabelResource() {
> >> +        return "sample_timeout_title"; // $NON-NLS-1$
> >> +    }
> >> +
> >> +    /**
> >> +     * Create the test element underlying this GUI component.
> >> +     *
> >> +     * @see
> org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()
> >> +     */
> >> +    @Override
> >> +    public TestElement createTestElement() {
> >> +        SampleTimeout timer = new SampleTimeout();
> >> +        modifyTestElement(timer);
> >> +        return timer;
> >> +    }
> >> +
> >> +    /**
> >> +     * Modifies a given TestElement to mirror the data in the gui
> >> components.
> >> +     *
> >> +     * @see
> >> org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
> >> +     */
> >> +    @Override
> >> +    public void modifyTestElement(TestElement timer) {
> >> +        this.configureTestElement(timer);
> >> +        ((SampleTimeout) timer).setTimeout(timeoutField.getText());
> >> +    }
> >> +
> >> +    /**
> >> +     * Configure this GUI component from the underlying TestElement.
> >> +     *
> >> +     * @see
> >> org.apache.jmeter.gui.JMeterGUIComponent#configure(TestElement)
> >> +     */
> >> +    @Override
> >> +    public void configure(TestElement el) {
> >> +        super.configure(el);
> >> +        timeoutField.setText(((SampleTimeout) el).getTimeout());
> >> +    }
> >> +
> >> +    /**
> >> +     * Initialize this component.
> >> +     */
> >> +    private void init() {
> >> +        setLayout(new VerticalLayout(5, VerticalLayout.BOTH,
> >> VerticalLayout.TOP));
> >> +
> >> +        setBorder(makeBorder());
> >> +        add(makeTitlePanel());
> >> +
> >> +        Box timeoutPanel = Box.createHorizontalBox();
> >> +        JLabel timeoutLabel = new
> >> JLabel(JMeterUtils.getResString("sample_timeout_timeout"));//$NON-NLS-1$
> >> +        timeoutPanel.add(timeoutLabel);
> >> +
> >> +        timeoutField = new JTextField(6);
> >> +        timeoutField.setText(DEFAULT_TIMEOUT);
> >> +        timeoutPanel.add(timeoutField);
> >> +
> >> +        add(timeoutPanel);
> >> +    }
> >> +
> >> +    /**
> >> +     * {@inheritDoc}
> >> +     */
> >> +    @Override
> >> +    public void clearGui() {
> >> +        timeoutField.setText(DEFAULT_TIMEOUT);
> >> +        super.clearGui();
> >> +    }
> >> +}
> >>
> >> Propchange:
> >>
> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
> >>
> >>
> ------------------------------------------------------------------------------
> >>     svn:eol-style = native
> >>
> >> Modified:
> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
> >>
> >>
> ==============================================================================
> >> ---
> jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> >> (original)
> >> +++
> jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
> >> Mon Dec 14 20:52:19 2015
> >> @@ -914,6 +914,9 @@ sampler_on_error_start_next_loop=Start N
> >>  sampler_on_error_stop_test=Stop Test
> >>  sampler_on_error_stop_test_now=Stop Test Now
> >>  sampler_on_error_stop_thread=Stop Thread
> >> +sample_timeout_memo=Interrupt the sampler if it times out
> >> +sample_timeout_timeout=Sample timeout (in milliseconds)\:
> >> +sample_timeout_title=Sample Timeout
> >>  save=Save
> >>  save?=Save?
> >>  save_all_as=Save Test Plan as
> >>
> >> Modified:
> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
> >>
> >>
> ==============================================================================
> >> ---
> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> >> (original)
> >> +++
> >> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
> >> Mon Dec 14 20:52:19 2015
> >> @@ -893,6 +893,9 @@ sample_scope_children=Les ressources li\
> >>  sample_scope_parent=L'\u00E9chantillon
> >>  sample_scope_variable=Une variable \:
> >>  sampler_label=Libell\u00E9
> >> +sample_timeout_memo=Interrompre l'\u00E9chantillon si le d\u00E9lai est
> >> d\u00E9pass\u00E9
> >> +sample_timeout_timeout=D\u00E9lai d'attente avant interruption (en
> >> millisecondes) \:
> >> +sample_timeout_title=Compteur Interruption
> >>  sampler_on_error_action=Action \u00E0 suivre apr\u00E8s une erreur
> >> d'\u00E9chantillon
> >>  sampler_on_error_continue=Continuer
> >>  sampler_on_error_start_next_loop=D\u00E9marrer it\u00E9ration suivante
> >>
> >> Modified: jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java?rev=1720012&r1=1720011&r2=1720012&view=diff
> >>
> >>
> ==============================================================================
> >> --- jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
> >> (original)
> >> +++ jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java Mon
> Dec
> >> 14 20:52:19 2015
> >> @@ -192,7 +192,7 @@ public class SaveService {
> >>      private static String fileVersion = ""; // computed from
> >> saveservice.properties file// $NON-NLS-1$
> >>      // Must match the sha1 checksum of the file saveservice.properties
> >> (without newline character),
> >>      // used to ensure saveservice.properties and SaveService are
> updated
> >> simultaneously
> >> -    static final String FILEVERSION =
> >> "3136d9168702a07555b110a86f7ba4da4ab88346"; // Expected value
> $NON-NLS-1$
> >> +    static final String FILEVERSION =
> >> "7bc78392d5d18fc977b789d99aea6e790f9816f2"; // Expected value
> $NON-NLS-1$
> >>
> >>      private static String fileEncoding = ""; // read from properties
> >> file// $NON-NLS-1$
> >>
> >>
> >> Modified:
> jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java?rev=1720012&r1=1720011&r2=1720012&view=diff
> >>
> >>
> ==============================================================================
> >> --- jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
> >> (original)
> >> +++ jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
> Mon
> >> Dec 14 20:52:19 2015
> >> @@ -65,6 +65,11 @@ import org.apache.log.Logger;
> >>  public class JMeterThread implements Runnable, Interruptible {
> >>      private static final Logger log =
> LoggingManager.getLoggerForClass();
> >>
> >> +    public static final boolean IMPLEMENTS_SAMPLE_STARTED =
> >> JMeterUtils.getPropDefault("temp.sampleStarted", true);
> >> +    static {
> >> +        log.info
> ("IMPLEMENTS_SAMPLE_STARTED="+IMPLEMENTS_SAMPLE_STARTED);
> >> +    }
> >> +
> >>      public static final String PACKAGE_OBJECT = "JMeterThread.pack"; //
> >> $NON-NLS-1$
> >>
> >>      public static final String LAST_SAMPLE_OK =
> >> "JMeterThread.last_sample_ok"; // $NON-NLS-1$
> >> @@ -449,7 +454,24 @@ public class JMeterThread implements Run
> >>
> >>          // Perform the actual sample
> >>          currentSampler = sampler;
> >> +        if (IMPLEMENTS_SAMPLE_STARTED) {
> >> +            for(SampleListener listener : pack.getSampleListeners()) {
> >> +                try {
> >> +                    TestBeanHelper.prepare((TestElement) listener);
> >> +                    listener.sampleStarted(null);
> >> +                } catch (RuntimeException e) {
> >> +                    log.error("Detected problem in Listener: ", e);
> >> +                    log.info("Continuing to process further
> listeners");
> >> +                }
> >> +            }
> >> +        }
> >>          SampleResult result = sampler.sample(null); // TODO: remove
> this
> >> useless Entry parameter
> >> +        if (IMPLEMENTS_SAMPLE_STARTED) {
> >> +            for(SampleListener listener : pack.getSampleListeners()) {
> >> +                // We don't need to prepare these again here
> >> +                listener.sampleStopped(null);
> >> +            }
> >> +        }
> >>          currentSampler = null;
> >>
> >>          // If we got any results, then perform processing on the result
> >>
> >> Modified: jmeter/trunk/xdocs/changes.xml
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1720012&r1=1720011&r2=1720012&view=diff
> >>
> >>
> ==============================================================================
> >> --- jmeter/trunk/xdocs/changes.xml (original)
> >> +++ jmeter/trunk/xdocs/changes.xml Mon Dec 14 20:52:19 2015
> >> @@ -134,6 +134,7 @@ Summary
> >>
> >>  <h3>General</h3>
> >>  <ul>
> >> +<li><bug>58736</bug>Add Sample Timeout support</li>
> >>  <li><bug>57913</bug>Automated backups of last saved JMX files.
> >> Contributed by Benoit Vatan (benoit.vatan at gmail.com)</li>
> >>  <li><bug>57988</bug>Shortcuts
> >> (<keycombo><keysym>Ctrl</keysym><keysym>1</keysym></keycombo> &hellip;
> >>      <keycombo><keysym>Ctrl</keysym><keysym>9</keysym></keycombo>) to
> >> quick add elements into test plan.
> >>
> >> Added: jmeter/trunk/xdocs/images/screenshots/sample_timeout.png
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/images/screenshots/sample_timeout.png?rev=1720012&view=auto
> >>
> >>
> ==============================================================================
> >> Binary file - no diff available.
> >>
> >> Propchange: jmeter/trunk/xdocs/images/screenshots/sample_timeout.png
> >>
> >>
> ------------------------------------------------------------------------------
> >>     svn:mime-type = image/png
> >>
> >> Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
> >> URL:
> >>
> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1720012&r1=1720011&r2=1720012&view=diff
> >>
> >>
> ==============================================================================
> >> --- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
> >> +++ jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Dec 14
> >> 20:52:19 2015
> >> @@ -5613,6 +5613,36 @@ this one will be used by "<code>Calculat
> >>          <link href="../demos/RegEx-User-Parameters.jmx">Test Plan
> showing
> >> how to use RegEx User Parameters</link>
> >>  </links>
> >>
> >> +<component name="Sample Timeout" index="&sect-num;.7.11"
> >> anchor="interrupt" width="316" height="138"
> screenshot="sample_timeout.png">
> >> +<description>
> >> +<note>BETA CODE - the test element may be moved or replaced in a future
> >> release</note>
> >> +<p>This Pre-Processor schedules a timer task to interrupt a sample if
> it
> >> takes too long to complete.
> >> +The timeout is ignored if it is zero or negative.
> >> +For this to work, the sampler must implement Interruptible.
> >> +The following samplers are known to do so:<br></br>
> >> +AJP, BeanShell, FTP, HTTP, Soap, AccessLog, MailReader, JMS Subscriber,
> >> TCPSampler, TestAction, JavaSampler
> >> +</p>
> >> +<p>
> >> +The test element is intended for use where individual timeouts such as
> >> Connection Timeout or Response Timeout are insufficient,
> >> +or where the Sampler does not support timeouts.
> >> +The timeout should be set sufficiently long so that it is not triggered
> >> in normal tests, but short enough that it interrupts samples
> >> +that are stuck.
> >> +</p>
> >> +<p>
> >> +[By default, JMeter uses a Callable to interrupt the sampler.
> >> +This executes in the same thread as the timer, so if the interrupt
> takes
> >> a long while,
> >> +it may delay the processing of subsequent timeouts.
> >> +This is not expected to be a problem, but if necessary the property
> >> <code>InterruptTimer.useRunnable</code>
> >> +can be set to <code>true</code> to use a separate Runnable thread
> instead
> >> of the Callable.]
> >> +</p>
> >> +</description>
> >> +
> >> +<properties>
> >> +        <property name="Name" required="No">Descriptive name for this
> >> timer that is shown in the tree.</property>
> >> +        <property name="Sampler Timeout" required="Yes">If the sample
> >> takes longer to complete, it will be interrupted.</property>
> >> +</properties>
> >> +</component>
> >> +
> >>  <a href="#">^</a>
> >>
> >>  </section>
> >>
> >>
> >>
> >
> >
> > --
> > Cordialement.
> > Philippe Mouawad.
>



-- 



-- 
Cordialement.
Philippe Mouawad.
Ubik-Ingénierie

UBIK LOAD PACK Web Site <http://www.ubikloadpack.com/>

UBIK LOAD PACK on TWITTER <https://twitter.com/ubikloadpack>

Re: svn commit: r1720012 - in /jmeter/trunk: bin/ src/components/org/apache/jmeter/modifiers/ src/components/org/apache/jmeter/modifiers/gui/ src/core/org/apache/jmeter/resources/ src/core/org/apache/jmeter/save/ src/core/org/apache/jmeter/threads/ xdocs/ ...

Posted by sebb <se...@gmail.com>.
On 17 December 2015 at 22:52, Philippe Mouawad
<ph...@gmail.com> wrote:
> Hi,
>
> 1/ Looking at the code, I think there might be a  side effect of this.
> With this commit, in JMeterThread we now call SampleListener#sampleStarted
> and sampleStopped around sampler.sample().
> It was not the case previously.
> There might be strange side effect if any 3rd party implements
> sampleStarted/sampleStopped.

See below - the side effect is that they are now implemented.

> By the way, I must say it's not clear for me when
> sampleStarted/sampleStopped were called before this commit.

They were never called.

So the effect of the code change is to implement the behaviour that
had been promised by the interface but never delivered.

> 2/ So, I wonder if it's a good idea to use this SampleListener interface ?

One could use a new interface, but is there any point?

> 3/ I also wonder if we should not split SampleListener into 2 interfaces
> and deprecate it (as we did with TestListener which we deprecated). Indeed
> I looked at all implementations of it, even in 3rd party JMeterPlugins and
> no implementation uses sampleStarted/sampleStopped, all implement
> sampleOccured()

That would be fine, but it's a separate issue entirely.

> Regards
> Philippe
>
>
> On Mon, Dec 14, 2015 at 9:52 PM, <se...@apache.org> wrote:
>
>> Author: sebb
>> Date: Mon Dec 14 20:52:19 2015
>> New Revision: 1720012
>>
>> URL: http://svn.apache.org/viewvc?rev=1720012&view=rev
>> Log:
>> Add Sample Timeout support
>> Bugzilla Id: 58736
>>
>> Added:
>>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>>  (with props)
>>
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>>  (with props)
>>     jmeter/trunk/xdocs/images/screenshots/sample_timeout.png   (with props)
>> Modified:
>>     jmeter/trunk/bin/jmeter.properties
>>     jmeter/trunk/bin/saveservice.properties
>>     jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>>
>> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>>     jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
>>     jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
>>     jmeter/trunk/xdocs/changes.xml
>>     jmeter/trunk/xdocs/usermanual/component_reference.xml
>>
>> Modified: jmeter/trunk/bin/jmeter.properties
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/bin/jmeter.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>>
>> ==============================================================================
>> --- jmeter/trunk/bin/jmeter.properties (original)
>> +++ jmeter/trunk/bin/jmeter.properties Mon Dec 14 20:52:19 2015
>> @@ -1035,6 +1035,11 @@ beanshell.server.file=../extras/startup.
>>  # Uncomment the following line to revert to the original behaviour
>>  #jmeterthread.reversePostProcessors=true
>>
>> +# (2.14) JMeterThread behaviour has changed: it now implements
>> sampleStarted/sampleStopped
>> +# This is necessary for the test element Sample Timeout
>> +# Uncomment the following line to revert to the original behaviour
>> (Sample Timeout will no longer work)
>> +#JMeterThread.sampleStarted=false
>> +
>>  # (2.2) StandardJMeterEngine behaviour has been changed to notify the
>> listeners after
>>  # the running version is enabled. This is so they can access variables.
>>  # In case this causes problems, the previous behaviour can be restored by
>> uncommenting
>>
>> Modified: jmeter/trunk/bin/saveservice.properties
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/bin/saveservice.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>>
>> ==============================================================================
>> --- jmeter/trunk/bin/saveservice.properties (original)
>> +++ jmeter/trunk/bin/saveservice.properties Mon Dec 14 20:52:19 2015
>> @@ -269,6 +269,8 @@ ResultSaverGui=org.apache.jmeter.reporte
>>  RunTime=org.apache.jmeter.control.RunTime
>>  RunTimeGui=org.apache.jmeter.control.gui.RunTimeGui
>>  SampleSaveConfiguration=org.apache.jmeter.samplers.SampleSaveConfiguration
>> +SampleTimeout=org.apache.jmeter.modifiers.SampleTimeout
>> +SampleTimeoutGui=org.apache.jmeter.modifiers.gui.SampleTimeoutGui
>>  SimpleConfigGui=org.apache.jmeter.config.gui.SimpleConfigGui
>>  SimpleDataWriter=org.apache.jmeter.visualizers.SimpleDataWriter
>>  SizeAssertion=org.apache.jmeter.assertions.SizeAssertion
>>
>> Added:
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java?rev=1720012&view=auto
>>
>> ==============================================================================
>> ---
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>> (added)
>> +++
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>> Mon Dec 14 20:52:19 2015
>> @@ -0,0 +1,230 @@
>> +/*
>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>> + * contributor license agreements.  See the NOTICE file distributed with
>> + * this work for additional information regarding copyright ownership.
>> + * The ASF licenses this file to You under the Apache License, Version 2.0
>> + * (the "License"); you may not use this file except in compliance with
>> + * the License.  You may obtain a copy of the License at
>> + *
>> + *   http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + *
>> + */
>> +
>> +package org.apache.jmeter.modifiers;
>> +
>> +import java.io.Serializable;
>> +import java.util.concurrent.Callable;
>> +import java.util.concurrent.Executors;
>> +import java.util.concurrent.ScheduledExecutorService;
>> +import java.util.concurrent.ScheduledFuture;
>> +import java.util.concurrent.ThreadFactory;
>> +import java.util.concurrent.TimeUnit;
>> +
>> +import org.apache.jmeter.samplers.Interruptible;
>> +import org.apache.jmeter.samplers.SampleEvent;
>> +import org.apache.jmeter.samplers.SampleListener;
>> +import org.apache.jmeter.samplers.Sampler;
>> +import org.apache.jmeter.testelement.AbstractTestElement;
>> +import org.apache.jmeter.testelement.TestElement;
>> +import org.apache.jmeter.testelement.ThreadListener;
>> +import org.apache.jmeter.threads.JMeterContext;
>> +import org.apache.jmeter.threads.JMeterContextService;
>> +import org.apache.jmeter.util.JMeterUtils;
>> +import org.apache.jorphan.logging.LoggingManager;
>> +import org.apache.log.Logger;
>> +
>> +/**
>> + *
>> + * Sample timeout implementation using Executor threads
>> + *
>> + */
>> +public class SampleTimeout extends AbstractTestElement implements
>> Serializable, ThreadListener, SampleListener {
>> +
>> +    private static final long serialVersionUID = 1L;
>> +
>> +    private static final Logger LOG = LoggingManager.getLoggerForClass();
>> +
>> +    private static final String TIMEOUT = "InterruptTimer.timeout";
>> //$NON-NLS-1$
>> +
>> +    private final boolean useRunnable =
>> JMeterUtils.getPropDefault("InterruptTimer.useRunnable", false);
>> +
>> +    private static class TPOOLHolder {
>> +        static final ScheduledExecutorService EXEC_SERVICE =
>> +                Executors.newScheduledThreadPool(1,
>> +                        new ThreadFactory() {
>> +                            public Thread newThread(Runnable r) {
>> +                                Thread t =
>> Executors.defaultThreadFactory().newThread(r);
>> +                                t.setDaemon(true); // also ensures that
>> Executor thread is daemon
>> +                                return t;
>> +                            }
>> +                        });
>> +    }
>> +
>> +    private static ScheduledExecutorService getExecutorService() {
>> +        return TPOOLHolder.EXEC_SERVICE;
>> +    }
>> +
>> +    private JMeterContext context; // Cache this here to avoid refetching
>> +
>> +    private ScheduledFuture<?> future;
>> +
>> +    private final transient ScheduledExecutorService execService;
>> +
>> +    private final boolean debug;
>> +
>> +    /**
>> +     * No-arg constructor.
>> +     */
>> +    public SampleTimeout() {
>> +//        LOG.setPriority(org.apache.log.Priority.DEBUG); // for local
>> debugging when enabled
>> +        debug = LOG.isDebugEnabled();
>> +        execService = getExecutorService();
>> +        if (debug) {
>> +            LOG.debug(whoAmI("InterruptTimer()", this));
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Set the timeout for this timer.
>> +     * @param timeout The timeout for this timer
>> +     */
>> +    public void setTimeout(String timeout) {
>> +        setProperty(TIMEOUT, timeout);
>> +    }
>> +
>> +    /**
>> +     * Get the timeout value for display.
>> +     *
>> +     * @return the timeout value for display.
>> +     */
>> +    public String getTimeout() {
>> +        return getPropertyAsString(TIMEOUT);
>> +    }
>> +
>> +    @Override
>> +    public void sampleStarted(SampleEvent e) {
>> +        if (debug) {
>> +            LOG.debug(whoAmI("sampleStarted()", this));
>> +        }
>> +        createTask();
>> +    }
>> +
>> +    @Override
>> +    public void sampleStopped(SampleEvent e) {
>> +        if (debug) {
>> +            LOG.debug(whoAmI("sampleStopped()", this));
>> +        }
>> +        cancelTask();
>> +    }
>> +
>> +    private void createTask() {
>> +        long timeout = getPropertyAsLong(TIMEOUT); // refetch each time
>> so it can be a variable
>> +        if (timeout <= 0) {
>> +            return;
>> +        }
>> +        final Sampler samp = context.getCurrentSampler();
>> +        if (!(samp instanceof Interruptible)) { // may be applied to a
>> whole test
>> +            return; // Cannot time out in this case
>> +        }
>> +        final Interruptible sampler = (Interruptible) samp;
>> +
>> +        if (useRunnable) {
>> +            Runnable run=new Runnable() {
>> +                public void run() {
>> +                    long start = System.nanoTime();
>> +                    boolean interrupted = sampler.interrupt();
>> +                    String elapsed =
>> Double.toString((double)(System.nanoTime()-start)/ 1000000000)+" secs";
>> +                    if (interrupted) {
>> +                        LOG.warn("Run Done interrupting " + getInfo(samp)
>> + " took " + elapsed);
>> +                    } else {
>> +                        if (debug) {
>> +                            LOG.debug("Run Didn't interrupt: " +
>> getInfo(samp) + " took " + elapsed);
>> +                        }
>> +                    }
>> +                }
>> +            };
>> +            // schedule the interrupt to occur and save for possible
>> cancellation
>> +            future = execService.schedule(run, timeout,
>> TimeUnit.MILLISECONDS);
>> +        } else {
>> +            Callable<Object> call = new Callable<Object>() {
>> +                @Override
>> +                public Object call() throws Exception {
>> +                    long start = System.nanoTime();
>> +                    boolean interrupted = sampler.interrupt();
>> +                    String elapsed =
>> Double.toString((double)(System.nanoTime()-start)/ 1000000000)+" secs";
>> +                    if (interrupted) {
>> +                        LOG.warn("Call Done interrupting " +
>> getInfo(samp) + " took " + elapsed);
>> +                    } else {
>> +                        if (debug) {
>> +                            LOG.debug("Call Didn't interrupt: " +
>> getInfo(samp) + " took " + elapsed);
>> +                        }
>> +                    }
>> +                    return null;
>> +                }
>> +
>> +            };
>> +            // schedule the interrupt to occur and save for possible
>> cancellation
>> +            future = execService.schedule(call, timeout,
>> TimeUnit.MILLISECONDS);
>> +        }
>> +        if (debug) {
>> +            LOG.debug("Scheduled timer: @" +
>> System.identityHashCode(future) + " " + getInfo(samp));
>> +        }
>> +    }
>> +
>> +    @Override
>> +    public void threadStarted() {
>> +        if (debug) {
>> +            LOG.debug(whoAmI("threadStarted()", this));
>> +        }
>> +        context = JMeterContextService.getContext();
>> +     }
>> +
>> +    @Override
>> +    public void threadFinished() {
>> +        if (debug) {
>> +            LOG.debug(whoAmI("threadFinished()", this));
>> +        }
>> +        cancelTask(); // cancel final if any
>> +     }
>> +
>> +    /**
>> +     * Provide a description of this class.
>> +     *
>> +     * @return the description of this class.
>> +     */
>> +    @Override
>> +    public String toString() {
>> +        return JMeterUtils.getResString("sample_timeout_memo");
>> //$NON-NLS-1$
>> +    }
>> +
>> +    private String whoAmI(String id, TestElement o) {
>> +        return id + " @" + System.identityHashCode(o)+ " '"+ o.getName()
>> + "' " + (debug ?  Thread.currentThread().getName() : "");
>> +    }
>> +
>> +    private String getInfo(TestElement o) {
>> +        return whoAmI(o.getClass().getSimpleName(), o);
>> +    }
>> +
>> +    private void cancelTask() {
>> +        if (future != null) {
>> +            if (!future.isDone()) {
>> +                boolean cancelled = future.cancel(false);
>> +                if (debug) {
>> +                    LOG.debug("Cancelled timer: @" +
>> System.identityHashCode(future) + " with result " + cancelled);
>> +                }
>> +            }
>> +            future = null;
>> +        }
>> +    }
>> +
>> +    @Override
>> +    public void sampleOccurred(SampleEvent e) {
>> +        // Not used
>> +    }
>> +}
>>
>> Propchange:
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/SampleTimeout.java
>>
>> ------------------------------------------------------------------------------
>>     svn:eol-style = native
>>
>> Added:
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java?rev=1720012&view=auto
>>
>> ==============================================================================
>> ---
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>> (added)
>> +++
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>> Mon Dec 14 20:52:19 2015
>> @@ -0,0 +1,133 @@
>> +/*
>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>> + * contributor license agreements.  See the NOTICE file distributed with
>> + * this work for additional information regarding copyright ownership.
>> + * The ASF licenses this file to You under the Apache License, Version 2.0
>> + * (the "License"); you may not use this file except in compliance with
>> + * the License.  You may obtain a copy of the License at
>> + *
>> + *   http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + *
>> + */
>> +
>> +package org.apache.jmeter.modifiers.gui;
>> +
>> +import javax.swing.Box;
>> +import javax.swing.JComponent;
>> +import javax.swing.JLabel;
>> +import javax.swing.JOptionPane;
>> +import javax.swing.JTextField;
>> +
>> +import org.apache.jmeter.modifiers.SampleTimeout;
>> +import org.apache.jmeter.processor.gui.AbstractPreProcessorGui;
>> +import org.apache.jmeter.testelement.TestElement;
>> +import org.apache.jmeter.util.JMeterUtils;
>> +import org.apache.jorphan.gui.layout.VerticalLayout;
>> +
>> +/**
>> + * The GUI for SampleTimeout.
>> + */
>> +public class SampleTimeoutGui extends AbstractPreProcessorGui {
>> +
>> +    private static final long serialVersionUID = 240L;
>> +
>> +    /**
>> +     * The default value for the timeout.
>> +     */
>> +    private static final String DEFAULT_TIMEOUT = "10000";
>> +
>> +    private JTextField timeoutField;
>> +
>> +    /**
>> +     * No-arg constructor.
>> +     */
>> +    public SampleTimeoutGui() {
>> +        init();
>> +    }
>> +
>> +    /**
>> +     * Handle an error.
>> +     *
>> +     * @param e
>> +     *            the Exception that was thrown.
>> +     * @param thrower
>> +     *            the JComponent that threw the Exception.
>> +     */
>> +    public static void error(Exception e, JComponent thrower) {
>> +        JOptionPane.showMessageDialog(thrower, e, "Error",
>> JOptionPane.ERROR_MESSAGE);
>> +    }
>> +
>> +    @Override
>> +    public String getLabelResource() {
>> +        return "sample_timeout_title"; // $NON-NLS-1$
>> +    }
>> +
>> +    /**
>> +     * Create the test element underlying this GUI component.
>> +     *
>> +     * @see org.apache.jmeter.gui.JMeterGUIComponent#createTestElement()
>> +     */
>> +    @Override
>> +    public TestElement createTestElement() {
>> +        SampleTimeout timer = new SampleTimeout();
>> +        modifyTestElement(timer);
>> +        return timer;
>> +    }
>> +
>> +    /**
>> +     * Modifies a given TestElement to mirror the data in the gui
>> components.
>> +     *
>> +     * @see
>> org.apache.jmeter.gui.JMeterGUIComponent#modifyTestElement(TestElement)
>> +     */
>> +    @Override
>> +    public void modifyTestElement(TestElement timer) {
>> +        this.configureTestElement(timer);
>> +        ((SampleTimeout) timer).setTimeout(timeoutField.getText());
>> +    }
>> +
>> +    /**
>> +     * Configure this GUI component from the underlying TestElement.
>> +     *
>> +     * @see
>> org.apache.jmeter.gui.JMeterGUIComponent#configure(TestElement)
>> +     */
>> +    @Override
>> +    public void configure(TestElement el) {
>> +        super.configure(el);
>> +        timeoutField.setText(((SampleTimeout) el).getTimeout());
>> +    }
>> +
>> +    /**
>> +     * Initialize this component.
>> +     */
>> +    private void init() {
>> +        setLayout(new VerticalLayout(5, VerticalLayout.BOTH,
>> VerticalLayout.TOP));
>> +
>> +        setBorder(makeBorder());
>> +        add(makeTitlePanel());
>> +
>> +        Box timeoutPanel = Box.createHorizontalBox();
>> +        JLabel timeoutLabel = new
>> JLabel(JMeterUtils.getResString("sample_timeout_timeout"));//$NON-NLS-1$
>> +        timeoutPanel.add(timeoutLabel);
>> +
>> +        timeoutField = new JTextField(6);
>> +        timeoutField.setText(DEFAULT_TIMEOUT);
>> +        timeoutPanel.add(timeoutField);
>> +
>> +        add(timeoutPanel);
>> +    }
>> +
>> +    /**
>> +     * {@inheritDoc}
>> +     */
>> +    @Override
>> +    public void clearGui() {
>> +        timeoutField.setText(DEFAULT_TIMEOUT);
>> +        super.clearGui();
>> +    }
>> +}
>>
>> Propchange:
>> jmeter/trunk/src/components/org/apache/jmeter/modifiers/gui/SampleTimeoutGui.java
>>
>> ------------------------------------------------------------------------------
>>     svn:eol-style = native
>>
>> Modified:
>> jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>>
>> ==============================================================================
>> --- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>> (original)
>> +++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
>> Mon Dec 14 20:52:19 2015
>> @@ -914,6 +914,9 @@ sampler_on_error_start_next_loop=Start N
>>  sampler_on_error_stop_test=Stop Test
>>  sampler_on_error_stop_test_now=Stop Test Now
>>  sampler_on_error_stop_thread=Stop Thread
>> +sample_timeout_memo=Interrupt the sampler if it times out
>> +sample_timeout_timeout=Sample timeout (in milliseconds)\:
>> +sample_timeout_title=Sample Timeout
>>  save=Save
>>  save?=Save?
>>  save_all_as=Save Test Plan as
>>
>> Modified:
>> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1720012&r1=1720011&r2=1720012&view=diff
>>
>> ==============================================================================
>> ---
>> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>> (original)
>> +++
>> jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
>> Mon Dec 14 20:52:19 2015
>> @@ -893,6 +893,9 @@ sample_scope_children=Les ressources li\
>>  sample_scope_parent=L'\u00E9chantillon
>>  sample_scope_variable=Une variable \:
>>  sampler_label=Libell\u00E9
>> +sample_timeout_memo=Interrompre l'\u00E9chantillon si le d\u00E9lai est
>> d\u00E9pass\u00E9
>> +sample_timeout_timeout=D\u00E9lai d'attente avant interruption (en
>> millisecondes) \:
>> +sample_timeout_title=Compteur Interruption
>>  sampler_on_error_action=Action \u00E0 suivre apr\u00E8s une erreur
>> d'\u00E9chantillon
>>  sampler_on_error_continue=Continuer
>>  sampler_on_error_start_next_loop=D\u00E9marrer it\u00E9ration suivante
>>
>> Modified: jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java?rev=1720012&r1=1720011&r2=1720012&view=diff
>>
>> ==============================================================================
>> --- jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
>> (original)
>> +++ jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java Mon Dec
>> 14 20:52:19 2015
>> @@ -192,7 +192,7 @@ public class SaveService {
>>      private static String fileVersion = ""; // computed from
>> saveservice.properties file// $NON-NLS-1$
>>      // Must match the sha1 checksum of the file saveservice.properties
>> (without newline character),
>>      // used to ensure saveservice.properties and SaveService are updated
>> simultaneously
>> -    static final String FILEVERSION =
>> "3136d9168702a07555b110a86f7ba4da4ab88346"; // Expected value $NON-NLS-1$
>> +    static final String FILEVERSION =
>> "7bc78392d5d18fc977b789d99aea6e790f9816f2"; // Expected value $NON-NLS-1$
>>
>>      private static String fileEncoding = ""; // read from properties
>> file// $NON-NLS-1$
>>
>>
>> Modified: jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java?rev=1720012&r1=1720011&r2=1720012&view=diff
>>
>> ==============================================================================
>> --- jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
>> (original)
>> +++ jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java Mon
>> Dec 14 20:52:19 2015
>> @@ -65,6 +65,11 @@ import org.apache.log.Logger;
>>  public class JMeterThread implements Runnable, Interruptible {
>>      private static final Logger log = LoggingManager.getLoggerForClass();
>>
>> +    public static final boolean IMPLEMENTS_SAMPLE_STARTED =
>> JMeterUtils.getPropDefault("temp.sampleStarted", true);
>> +    static {
>> +        log.info("IMPLEMENTS_SAMPLE_STARTED="+IMPLEMENTS_SAMPLE_STARTED);
>> +    }
>> +
>>      public static final String PACKAGE_OBJECT = "JMeterThread.pack"; //
>> $NON-NLS-1$
>>
>>      public static final String LAST_SAMPLE_OK =
>> "JMeterThread.last_sample_ok"; // $NON-NLS-1$
>> @@ -449,7 +454,24 @@ public class JMeterThread implements Run
>>
>>          // Perform the actual sample
>>          currentSampler = sampler;
>> +        if (IMPLEMENTS_SAMPLE_STARTED) {
>> +            for(SampleListener listener : pack.getSampleListeners()) {
>> +                try {
>> +                    TestBeanHelper.prepare((TestElement) listener);
>> +                    listener.sampleStarted(null);
>> +                } catch (RuntimeException e) {
>> +                    log.error("Detected problem in Listener: ", e);
>> +                    log.info("Continuing to process further listeners");
>> +                }
>> +            }
>> +        }
>>          SampleResult result = sampler.sample(null); // TODO: remove this
>> useless Entry parameter
>> +        if (IMPLEMENTS_SAMPLE_STARTED) {
>> +            for(SampleListener listener : pack.getSampleListeners()) {
>> +                // We don't need to prepare these again here
>> +                listener.sampleStopped(null);
>> +            }
>> +        }
>>          currentSampler = null;
>>
>>          // If we got any results, then perform processing on the result
>>
>> Modified: jmeter/trunk/xdocs/changes.xml
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1720012&r1=1720011&r2=1720012&view=diff
>>
>> ==============================================================================
>> --- jmeter/trunk/xdocs/changes.xml (original)
>> +++ jmeter/trunk/xdocs/changes.xml Mon Dec 14 20:52:19 2015
>> @@ -134,6 +134,7 @@ Summary
>>
>>  <h3>General</h3>
>>  <ul>
>> +<li><bug>58736</bug>Add Sample Timeout support</li>
>>  <li><bug>57913</bug>Automated backups of last saved JMX files.
>> Contributed by Benoit Vatan (benoit.vatan at gmail.com)</li>
>>  <li><bug>57988</bug>Shortcuts
>> (<keycombo><keysym>Ctrl</keysym><keysym>1</keysym></keycombo> &hellip;
>>      <keycombo><keysym>Ctrl</keysym><keysym>9</keysym></keycombo>) to
>> quick add elements into test plan.
>>
>> Added: jmeter/trunk/xdocs/images/screenshots/sample_timeout.png
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/images/screenshots/sample_timeout.png?rev=1720012&view=auto
>>
>> ==============================================================================
>> Binary file - no diff available.
>>
>> Propchange: jmeter/trunk/xdocs/images/screenshots/sample_timeout.png
>>
>> ------------------------------------------------------------------------------
>>     svn:mime-type = image/png
>>
>> Modified: jmeter/trunk/xdocs/usermanual/component_reference.xml
>> URL:
>> http://svn.apache.org/viewvc/jmeter/trunk/xdocs/usermanual/component_reference.xml?rev=1720012&r1=1720011&r2=1720012&view=diff
>>
>> ==============================================================================
>> --- jmeter/trunk/xdocs/usermanual/component_reference.xml (original)
>> +++ jmeter/trunk/xdocs/usermanual/component_reference.xml Mon Dec 14
>> 20:52:19 2015
>> @@ -5613,6 +5613,36 @@ this one will be used by "<code>Calculat
>>          <link href="../demos/RegEx-User-Parameters.jmx">Test Plan showing
>> how to use RegEx User Parameters</link>
>>  </links>
>>
>> +<component name="Sample Timeout" index="&sect-num;.7.11"
>> anchor="interrupt" width="316" height="138" screenshot="sample_timeout.png">
>> +<description>
>> +<note>BETA CODE - the test element may be moved or replaced in a future
>> release</note>
>> +<p>This Pre-Processor schedules a timer task to interrupt a sample if it
>> takes too long to complete.
>> +The timeout is ignored if it is zero or negative.
>> +For this to work, the sampler must implement Interruptible.
>> +The following samplers are known to do so:<br></br>
>> +AJP, BeanShell, FTP, HTTP, Soap, AccessLog, MailReader, JMS Subscriber,
>> TCPSampler, TestAction, JavaSampler
>> +</p>
>> +<p>
>> +The test element is intended for use where individual timeouts such as
>> Connection Timeout or Response Timeout are insufficient,
>> +or where the Sampler does not support timeouts.
>> +The timeout should be set sufficiently long so that it is not triggered
>> in normal tests, but short enough that it interrupts samples
>> +that are stuck.
>> +</p>
>> +<p>
>> +[By default, JMeter uses a Callable to interrupt the sampler.
>> +This executes in the same thread as the timer, so if the interrupt takes
>> a long while,
>> +it may delay the processing of subsequent timeouts.
>> +This is not expected to be a problem, but if necessary the property
>> <code>InterruptTimer.useRunnable</code>
>> +can be set to <code>true</code> to use a separate Runnable thread instead
>> of the Callable.]
>> +</p>
>> +</description>
>> +
>> +<properties>
>> +        <property name="Name" required="No">Descriptive name for this
>> timer that is shown in the tree.</property>
>> +        <property name="Sampler Timeout" required="Yes">If the sample
>> takes longer to complete, it will be interrupted.</property>
>> +</properties>
>> +</component>
>> +
>>  <a href="#">^</a>
>>
>>  </section>
>>
>>
>>
>
>
> --
> Cordialement.
> Philippe Mouawad.