1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package org.apache.jmeter.samplers; 20 21 import org.apache.jmeter.util.JMeterUtils; 22 import org.apache.log.Logger; 23 import org.apache.jorphan.logging.LoggingManager; 24 25 import java.util.List; 26 import java.util.ArrayList; 27 import java.rmi.RemoteException; 28 import java.io.Serializable; 29 30 /** 31 * Implements batch reporting for remote testing. 32 * 33 */ 34 public class BatchSampleSender implements SampleSender, Serializable { 35 private static final Logger log = LoggingManager.getLoggerForClass(); 36 37 private static final int DEFAULT_NUM_SAMPLE_THRESHOLD = 100; 38 39 private static final long DEFAULT_TIME_THRESHOLD = 60000L; 40 41 private RemoteSampleListener listener; 42 43 private List sampleStore = new ArrayList(); 44 45 private int numSamplesThreshold; 46 47 private long timeThreshold; 48 49 private long batchSendTime = -1; 50 51 public BatchSampleSender(){ 52 log.warn("Constructor only intended for use in testing"); // $NON-NLS-1$ 53 } 54 /** 55 * Constructor 56 * 57 * @param listener 58 * that the List of sample events will be sent to. 59 */ 60 BatchSampleSender(RemoteSampleListener listener) { 61 this.listener = listener; 62 init(); 63 log.info("Using batching for this run." 64 + " Thresholds: num=" + numSamplesThreshold 65 + ", time=" + timeThreshold); 66 } 67 68 /** 69 * Checks for the Jmeter properties num_sample_threshold and time_threshold, 70 * and assigns defaults if not found. 71 */ 72 private void init() { 73 this.numSamplesThreshold = JMeterUtils.getPropDefault("num_sample_threshold", DEFAULT_NUM_SAMPLE_THRESHOLD); 74 this.timeThreshold = JMeterUtils.getPropDefault("time_threshold", DEFAULT_TIME_THRESHOLD); 75 } 76 77 /** 78 * Checks if any sample events are still present in the sampleStore and 79 * sends them to the listener. Informs the listener of the testended. 80 */ 81 public void testEnded() { 82 try { 83 if (sampleStore.size() != 0) { 84 listener.processBatch(sampleStore); 85 sampleStore.clear(); 86 } 87 listener.testEnded(); 88 } catch (RemoteException err) { 89 log.error("testEnded()", err); 90 } 91 } 92 93 /** 94 * Checks if any sample events are still present in the sampleStore and 95 * sends them to the listener. Informs the listener of the testended. 96 * 97 * @param host 98 * the host that the test has ended on. 99 */ 100 public void testEnded(String host) { 101 try { 102 if (sampleStore.size() != 0) { 103 listener.processBatch(sampleStore); 104 sampleStore.clear(); 105 } 106 listener.testEnded(host); 107 } catch (RemoteException err) { 108 log.error("testEnded(host)", err); 109 } 110 } 111 112 /** 113 * Stores sample events untill either a time or sample threshold is 114 * breached. Both thresholds are reset if one fires. If only one threshold 115 * is set it becomes the only value checked against. When a threhold is 116 * breached the list of sample events is sent to a listener where the event 117 * are fired locally. 118 * 119 * @param e 120 * a Sample Event 121 */ 122 public void sampleOccurred(SampleEvent e) { 123 synchronized (sampleStore) { 124 sampleStore.add(e); 125 126 if (numSamplesThreshold != -1) { 127 if (sampleStore.size() >= numSamplesThreshold) { 128 try { 129 log.debug("Firing sample"); 130 listener.processBatch(sampleStore); 131 sampleStore.clear(); 132 } catch (RemoteException err) { 133 log.error("sampleOccurred", err); 134 } 135 } 136 } 137 138 if (timeThreshold != -1) { 139 SampleResult sr = e.getResult(); 140 long timestamp = sr.getTimeStamp(); 141 142 // Checking for and creating initial timestamp to cheak against 143 if (batchSendTime == -1) { 144 this.batchSendTime = timestamp + timeThreshold; 145 } 146 147 if (batchSendTime < timestamp) { 148 try { 149 log.debug("Firing time"); 150 if (sampleStore.size() > 0) { 151 listener.processBatch(sampleStore); 152 sampleStore.clear(); 153 } 154 this.batchSendTime = timestamp + timeThreshold; 155 } catch (RemoteException err) { 156 log.error("sampleOccurred", err); 157 } 158 } 159 } 160 } 161 } 162 }