Coverage Report - org.apache.commons.performance.ClientThread
 
Classes in this File Line Coverage Branch Coverage Complexity
ClientThread
0%
0/195
0%
0/71
2.098
 
 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  
 package org.apache.commons.performance;
 19  
 
 20  
 import java.util.logging.Logger;
 21  
 
 22  
 import org.apache.commons.math.random.RandomData;
 23  
 import org.apache.commons.math.random.RandomDataImpl;
 24  
 import org.apache.commons.math.stat.descriptive.SummaryStatistics;
 25  
 
 26  
 /**
 27  
  * <p>Base for performance / load test clients. 
 28  
  * The run method executes init, then setup-execute-cleanup in a loop,
 29  
  * gathering performance statistics, with time between executions based
 30  
  * on configuration parameters. The <code>finish</code> method is executed once
 31  
  * at the end of a run. See {@link #nextDelay()} for details on
 32  
  * inter-arrival time computation.</p>
 33  
  * 
 34  
  * <p>Subclasses <strong>must</strong> implement <code>execute</code>, which
 35  
  * is the basic client request action that is executed, and timed, 
 36  
  * repeatedly. If per-request setup is required, and you do not want the time
 37  
  * associated with this setup to be included in the reported timings, implement 
 38  
  * <code>setUp</code> and put the setup code there.  Similarly for 
 39  
  * <code>cleanUp</code>. Initialization code that needs to be executed once
 40  
  * only, before any requests are initiated, should be put into 
 41  
  * <code>init</code> and cleanup code that needs to be executed only once
 42  
  * at the end of a simulation should be put into <code>finish.</code></p>
 43  
  * 
 44  
  * <p>By default, the only statistics accumulated are for the latency of the 
 45  
  * <code>execute</code> method. Additional metrics can be captured and added
 46  
  * to the {@link Statistics} for the running thread.</p>
 47  
  * 
 48  
  */
 49  
 public abstract class ClientThread implements Runnable {
 50  
 
 51  
     // Inter-arrival time configuration parameters 
 52  
     /** Minimum mean time between requests */
 53  
     private long minDelay;
 54  
     /** Maximum mean time between requests */
 55  
     private long maxDelay;
 56  
     /** Standard deviation of delay distribution */
 57  
     private double sigma;
 58  
     /** Delay type - determines how next start times are computed */
 59  
     private String delayType;
 60  
     /** Ramp length for cyclic mean delay */
 61  
     private long rampPeriod;
 62  
     /** Peak length for cyclic mean delay */
 63  
     private long peakPeriod;
 64  
     /** Trough length for cyclic mean delay */
 65  
     private long troughPeriod;
 66  
     /** Cycle type */
 67  
     private final String cycleType;
 68  
     /** Ramp type */
 69  
     private String rampType;
 70  
     
 71  
     /** Number of iterations */
 72  
     private final long iterations;
 73  
     
 74  
     // State data
 75  
     /** Start time of run */
 76  
     private long startTime;
 77  
     /** Start time of current period */
 78  
     private long periodStart;
 79  
     /** Last mean delay */
 80  
     private double lastMean;
 81  
     /** Cycle state constants */
 82  
     protected static final int RAMPING_UP = 0;
 83  
     protected static final int RAMPING_DOWN = 1;
 84  
     protected static final int PEAK_LOAD = 2;
 85  
     protected static final int TROUGH_LOAD = 3;
 86  
     /** Cycle state */
 87  0
     private int cycleState = RAMPING_UP;
 88  
     /** Number of errors */
 89  0
     private long numErrors = 0;
 90  
     /** Number of misses */
 91  0
     private long numMisses = 0;
 92  
     
 93  
     /** Random data generator */
 94  0
     protected RandomData randomData = new RandomDataImpl();
 95  
     /** Statistics container */
 96  
     protected Statistics stats;
 97  
     /** Logger shared by client threads */
 98  
     protected Logger logger;
 99  
     
 100  
     /**
 101  
      * Create a client thread.
 102  
      * 
 103  
      * @param iterations number of iterations
 104  
      * @param minDelay minimum mean time between client requests
 105  
      * @param maxDelay maximum mean time between client requests
 106  
      * @param sigma standard deviation of time between client requests
 107  
      * @param delayType distribution of time between client requests
 108  
      * @param rampPeriod ramp period of cycle for cyclic load
 109  
      * @param peakPeriod peak period of cycle for cyclic load
 110  
      * @param troughPeriod trough period of cycle for cyclic load
 111  
      * @param cycleType type of cycle for mean delay
 112  
      * @param rampType type of ramp (linear or random jumps)
 113  
      * @param logger common logger shared by all clients
 114  
      * @param stats Statistics instance to add results to
 115  
      */
 116  
     public ClientThread(long iterations, long minDelay, long maxDelay,
 117  
             double sigma, String delayType, long rampPeriod, long peakPeriod,
 118  
             long troughPeriod, String cycleType,
 119  
             String rampType, Logger logger,
 120  0
             Statistics stats) {
 121  0
         this.iterations = iterations;
 122  0
         this.minDelay = minDelay;
 123  0
         this.maxDelay = maxDelay;
 124  0
         this.sigma = sigma;
 125  0
         this.delayType = delayType;
 126  0
         this.peakPeriod = peakPeriod;
 127  0
         this.rampPeriod = rampPeriod;
 128  0
         this.troughPeriod = troughPeriod;
 129  0
         this.cycleType = cycleType;
 130  0
         this.rampType = rampType;
 131  0
         this.logger = logger;
 132  0
         this.stats = stats;
 133  0
     }
 134  
     
 135  
     public void run() {
 136  
         try {
 137  0
             init();
 138  0
         } catch (Exception ex) {
 139  0
             logger.severe("init failed.");
 140  0
             ex.printStackTrace();
 141  0
             return;
 142  0
         }
 143  0
         long start = 0;
 144  0
         startTime = System.currentTimeMillis();
 145  0
         long lastStart = startTime;
 146  0
         periodStart = System.currentTimeMillis();
 147  0
         lastMean = (double) maxDelay; // Ramp up, if any, starts here
 148  0
         SummaryStatistics responseStats = new SummaryStatistics();
 149  0
         for (int i = 0; i < iterations; i++) {
 150  
             try {
 151  0
                 setUp();
 152  
                 // Generate next interarrival time. If that is in the
 153  
                 // past, go right away and log a miss; otherwise wait.
 154  0
                 long elapsed = System.currentTimeMillis() - lastStart;
 155  0
                 long nextDelay = nextDelay();
 156  0
                 if (elapsed > nextDelay) {
 157  0
                     numMisses++;
 158  
                 } else {
 159  
                     try {
 160  0
                         Thread.sleep(nextDelay - elapsed);
 161  0
                     } catch (InterruptedException ex) {
 162  0
                         logger.info("Sleep interrupted");
 163  0
                     }
 164  
                 }
 165  
                 
 166  
                 // Fire the request and measure response time
 167  0
                 start = System.currentTimeMillis();
 168  0
                 execute();
 169  0
             } catch (Exception ex) {
 170  0
                 ex.printStackTrace();
 171  0
                 numErrors++;
 172  
             } finally {
 173  0
                 try {
 174  0
                     responseStats.addValue(System.currentTimeMillis() - start);
 175  0
                     lastStart = start;
 176  0
                     cleanUp();
 177  0
                 } catch (Exception e) {
 178  0
                     e.printStackTrace();                    
 179  0
                 }
 180  0
             }
 181  
         }
 182  
         
 183  
         try {
 184  0
             finish();
 185  0
         } catch (Exception ex) {
 186  0
             logger.severe("finalize failed.");
 187  0
             ex.printStackTrace();
 188  0
             return;
 189  0
         }
 190  
         
 191  
         // Use thread name as process name
 192  0
         String process = Thread.currentThread().getName();
 193  
         
 194  
         // Record latency statistics
 195  0
         stats.addStatistics(responseStats, process, "latency");
 196  
         
 197  
         // Log accumulated statistics for this thread
 198  0
         logger.info(stats.displayProcessStatistics(process) + 
 199  
           "Number of misses: " + numMisses + "\n" +
 200  
           "Number or errors: " + numErrors + "\n"); 
 201  0
     }
 202  
     
 203  
     /** Executed once at the beginning of the run */
 204  0
     protected void init() throws Exception {}
 205  
     
 206  
     /** Executed at the beginning of each iteration */
 207  0
     protected void setUp() throws Exception {}
 208  
     
 209  
     /** Executed in finally block of iteration try-catch */
 210  0
     protected void cleanUp() throws Exception {}
 211  
     
 212  
     /** Executed once after the run finishes */
 213  0
     protected void finish() throws Exception {}
 214  
     
 215  
     /** 
 216  
      * Core iteration code.  Timings are based on this,
 217  
      *  so keep it tight.
 218  
      */
 219  
     public abstract void execute() throws Exception;
 220  
     
 221  
     /**
 222  
      * <p>Computes the next interarrival time (time to wait between requests)
 223  
      * based on configured values for min/max delay, delay type, cycle type, 
 224  
      * ramp type and period. Currently supports constant (always returning
 225  
      * <code>minDelay</code> delay time), Poisson and Gaussian distributed
 226  
      * random time delays, linear and random ramps, and oscillating / 
 227  
      * non-oscillating cycle types.</p>
 228  
      * 
 229  
      * <p><strong>loadType</strong> determines whether returned times are
 230  
      * deterministic or random. If <code>loadType</code> is not "constant",
 231  
      * a random value with the specified distribution and mean determined by
 232  
      * the other parameters is returned. For "gaussian" <code>loadType</code>,
 233  
      * <code>sigma</code> is used as used as the standard deviation. </p>
 234  
      * 
 235  
      * <p><strong>cycleType</strong> determines how the returned times vary
 236  
      * over time. "oscillating", means times ramp up and down between 
 237  
      * <code>minDelay</code> and <code>maxDelay.</code> Ramp type is controlled
 238  
      * by <code>rampType.</code>  Linear <code>rampType</code> means the means
 239  
      * increase or decrease linearly over the time of the period.  Random
 240  
      * makes random jumps up or down toward the next peak or trough. "None" for
 241  
      * <code>rampType</code> under oscillating <code>cycleType</code> makes the
 242  
      * means alternate between peak (<code>minDelay</code>) and trough 
 243  
      *(<code>maxDelay</code>) with no ramp between. </p>
 244  
      * 
 245  
      * <p>Oscillating loads cycle through RAMPING_UP, PEAK_LOAD, RAMPING_DOWN
 246  
      * and TROUGH_LOAD states, with the amount of time spent in each state
 247  
      * determined by <code>rampPeriod</code> (time spent increasing on the way
 248  
      * up and decreasing on the way down), <code>peakPeriod</code> (time spent
 249  
      * at peak load, i.e., <code>minDelay</code> mean delay) and 
 250  
      * <code>troughPeriod</code> (time spent at minimum load, i.e., 
 251  
      * <code>maxDelay</code> mean delay). All times are specified in
 252  
      * milliseconds. </p>
 253  
      * 
 254  
      * <p><strong>Examples:</strong><ol>
 255  
      * 
 256  
      * <li>Given<pre>
 257  
      * delayType = "constant"
 258  
      * minDelay = 250
 259  
      * maxDelay = 500
 260  
      * cycleType = "oscillating"
 261  
      * rampType = "linear" 
 262  
      * rampPeriod = 10000
 263  
      * peakPeriod = 20000
 264  
      * troughPeriod = 30000</pre> load will start at one request every 500 ms,
 265  
      * which is "trough load." Load then ramps up linearly over the next 10
 266  
      * seconds unil it reaches one request per 250 milliseconds, which is 
 267  
      * "peak load."  Peak load is sustained for 20 seconds and then load ramps
 268  
      * back down, again taking 10 seconds to get down to "trough load," which
 269  
      * is sustained for 30 seconds.  The cycle then repeats.</li>
 270  
      * 
 271  
      * <li><pre>
 272  
      * delayType = "gaussian"
 273  
      * minDelay = 250
 274  
      * maxDelay = 500
 275  
      * cycleType = "oscillating"
 276  
      * rampType = "linear" 
 277  
      * rampPeriod = 10000
 278  
      * peakPeriod = 20000
 279  
      * troughPeriod = 30000
 280  
      * sigma = 100 </pre> produces a load pattern similar to example 1, but in
 281  
      * this case the computed delay value is fed into a gaussian random number
 282  
      * generator as the mean and 100 as the standard deviation - i.e., 
 283  
      * <code>nextDelay</code> returns random, gaussian distributed values with
 284  
      * means moving according to the cyclic pattern in example 1.</li>
 285  
      * 
 286  
      * <li><pre>
 287  
      * delayType = "constant"
 288  
      * minDelay = 250
 289  
      * maxDelay = 500
 290  
      * cycleType = "none"
 291  
      * rampType = "linear" 
 292  
      * rampPeriod = 10000</pre> produces a load pattern that increases linearly
 293  
      * from one request every 500ms to one request every 250ms and then stays
 294  
      * constant at that level until the run is over.  Other parameters are
 295  
      * ignored in this case.</li>
 296  
      * 
 297  
      * <li><pre>
 298  
      * delayType = "poisson"
 299  
      * minDelay = 250
 300  
      * maxDelay = 500
 301  
      * cycleType = "none"
 302  
      * rampType = "none" 
 303  
      * </pre> produces inter-arrival times that are poisson distributed with
 304  
      * mean 250ms. Note that when rampType is "none," the value of 
 305  
      * <code>minDelay</code> is used as the (constant) mean delay.</li></ol>
 306  
      * 
 307  
      * @return next value for delay
 308  
      */
 309  
     protected long nextDelay() throws ConfigurationException {
 310  0
         double targetDelay = 0; 
 311  0
         double dMinDelay = (double) minDelay;
 312  0
         double dMaxDelay = (double) maxDelay;
 313  0
         double delayDifference = dMaxDelay - dMinDelay;
 314  0
         long currentTime = System.currentTimeMillis();
 315  0
         if (cycleType.equals("none")) {
 316  0
             if (rampType.equals("none") || 
 317  
                     (currentTime - startTime) > rampPeriod) { // ramped up
 318  0
                 targetDelay = dMinDelay;
 319  0
             } else if (rampType.equals("linear")) { // single period linear
 320  0
                 double prop = 
 321  
                     (double) (currentTime - startTime) / (double) rampPeriod;
 322  0
                 targetDelay =  dMaxDelay - delayDifference * prop;
 323  0
             } else { // Random jumps down to delay - single period
 324  
                 // TODO: govern size of jumps as in oscillating
 325  
                 // Where we last were as proportion of way down to minDelay
 326  0
                 double lastProp = 
 327  
                     (dMaxDelay - lastMean) / delayDifference;
 328  
                 // Make a random jump toward 1 (1 = all the way down)
 329  0
                 double prop = randomData.nextUniform(lastProp, 1);
 330  0
                 targetDelay = dMaxDelay - delayDifference * prop;
 331  0
             }
 332  0
         } else if (cycleType.equals("oscillating")) {
 333  
             // First change cycle state if we need to
 334  0
             adjustState(currentTime);
 335  0
             targetDelay = computeCyclicDelay(
 336  
                     currentTime, dMinDelay, dMaxDelay);
 337  
         } else {
 338  0
             throw new ConfigurationException(
 339  
                     "Cycle type not supported: " + cycleType);
 340  
         }
 341  
 
 342  
         // Remember last mean for ramp up / down
 343  0
         lastMean = targetDelay;
 344  
 
 345  0
         if (delayType.equals("constant")) { 
 346  0
             return Math.round(targetDelay);
 347  
         }
 348  
 
 349  
         // Generate and return random deviate
 350  0
         if (delayType.equals("gaussian")) {
 351  0
             return Math.round(randomData.nextGaussian(targetDelay, sigma));
 352  
         } else { // must be Poisson
 353  0
             return randomData.nextPoisson(targetDelay);
 354  
         } 
 355  
     }
 356  
     
 357  
     /**
 358  
      * Adjusts cycleState, periodStart and lastMean if a cycle state
 359  
      * transition needs to happen.
 360  
      * 
 361  
      * @param currentTime current time
 362  
      */
 363  
     protected void adjustState(long currentTime) {
 364  0
         long timeInPeriod = currentTime - periodStart;
 365  0
         if ( ((cycleState == RAMPING_UP || cycleState == RAMPING_DOWN) && 
 366  
                 timeInPeriod < rampPeriod) ||
 367  
              (cycleState == PEAK_LOAD && timeInPeriod < peakPeriod) ||
 368  
              (cycleState == TROUGH_LOAD && timeInPeriod < troughPeriod)) {
 369  0
             return; // No state change
 370  
         }
 371  0
         switch (cycleState) {
 372  
             case RAMPING_UP: 
 373  0
                 if (peakPeriod > 0) {
 374  0
                     cycleState = PEAK_LOAD;
 375  
                 } else {
 376  0
                     cycleState = RAMPING_DOWN;
 377  
                 }
 378  0
                 lastMean = (double) minDelay;
 379  0
                 periodStart = currentTime;
 380  0
                 break;
 381  
             
 382  
             case RAMPING_DOWN: 
 383  0
                 if (troughPeriod > 0) {
 384  0
                     cycleState = TROUGH_LOAD;
 385  
                 } else {
 386  0
                     cycleState = RAMPING_UP;
 387  
                 }
 388  0
                 lastMean = (double) maxDelay;
 389  0
                 periodStart = currentTime;
 390  0
                 break;
 391  
             
 392  
             case PEAK_LOAD: 
 393  0
                 if (rampPeriod > 0) {
 394  0
                     cycleState = RAMPING_DOWN;
 395  0
                     lastMean = (double) minDelay;
 396  
                 } else {
 397  0
                     cycleState = TROUGH_LOAD;
 398  0
                     lastMean = (double) maxDelay;
 399  
                 }
 400  0
                 periodStart = currentTime;
 401  0
                 break;
 402  
             
 403  
             case TROUGH_LOAD: 
 404  0
                 if (rampPeriod > 0) {
 405  0
                     cycleState = RAMPING_UP;
 406  0
                     lastMean = (double) maxDelay;
 407  
                 } else {
 408  0
                     cycleState = PEAK_LOAD;
 409  0
                     lastMean = (double) minDelay;
 410  
                 }
 411  0
                 periodStart = currentTime;
 412  0
                 break;
 413  
             
 414  
             default: 
 415  0
                 throw new IllegalStateException(
 416  
                         "Illegal cycle state: " + cycleState);
 417  
         }
 418  0
     }
 419  
     
 420  
     protected double computeCyclicDelay(
 421  
             long currentTime, double min, double max) {
 422  
         
 423  
         // Constant load states
 424  0
         if (cycleState == PEAK_LOAD) { 
 425  0
             return min;
 426  
         } 
 427  0
         if (cycleState == TROUGH_LOAD) {
 428  0
             return max;
 429  
         } 
 430  
 
 431  
         // No ramp - stay at min or max load during ramp
 432  0
         if (rampType.equals("none")) { // min or max, no ramp
 433  0
             if (cycleState == RAMPING_UP) {
 434  0
                 return max;
 435  
             } else {
 436  0
                 return min;
 437  
             }
 438  
         } 
 439  
 
 440  
         // Linear ramp type and ramping up or down
 441  0
         double diff = max - min;
 442  0
         if (rampType.equals("linear")) {
 443  0
             double prop = 
 444  
                 (double)(currentTime - periodStart) / (double) rampPeriod;
 445  0
             if (cycleState == RAMPING_UP) {
 446  0
                 return max - diff * prop; 
 447  
             } else {
 448  0
                 return min + diff * prop;
 449  
             }
 450  
         } else { // random jumps down, then back up
 451  
             // Where we last were as proportion of way down to minDelay
 452  0
             double lastProp = 
 453  
                 (max - lastMean) / diff;
 454  
             // Where we would be if this were a linear ramp
 455  0
             double linearProp = 
 456  
                 (double)(currentTime - periodStart) / (double) rampPeriod;
 457  
             // Need to govern size of jumps, otherwise "convergence"
 458  
             // can be too fast - use linear ramp as governor
 459  0
             if ((cycleState == RAMPING_UP && (lastProp > linearProp)) || 
 460  
                     (cycleState == RAMPING_DOWN && 
 461  
                             ((1 - lastProp) > linearProp))) 
 462  0
                 lastProp = (cycleState == RAMPING_UP) ? linearProp : 
 463  
                     (1 - linearProp);
 464  0
             double prop = 0;
 465  0
             if (cycleState == RAMPING_UP) { // Random jump toward 1
 466  0
                 prop = randomData.nextUniform(lastProp, 1);
 467  
             } else { // Random jump toward 0
 468  0
                 prop = randomData.nextUniform(0, lastProp);
 469  
             }
 470  
             // Make sure sequence is monotone
 471  0
             if (cycleState == RAMPING_UP) {
 472  0
                 return Math.min(lastMean, max - diff * prop);
 473  
             } else {
 474  0
                 return Math.max(lastMean, min + diff * prop);
 475  
             }
 476  
         }
 477  
     }
 478  
 
 479  
     public long getMinDelay() {
 480  0
         return minDelay;
 481  
     }
 482  
 
 483  
     public long getMaxDelay() {
 484  0
         return maxDelay;
 485  
     }
 486  
 
 487  
     public double getSigma() {
 488  0
         return sigma;
 489  
     }
 490  
 
 491  
     public String getDelayType() {
 492  0
         return delayType;
 493  
     }
 494  
 
 495  
     public long getRampPeriod() {
 496  0
         return rampPeriod;
 497  
     }
 498  
 
 499  
     public long getPeakPeriod() {
 500  0
         return peakPeriod;
 501  
     }
 502  
 
 503  
     public long getTroughPeriod() {
 504  0
         return troughPeriod;
 505  
     }
 506  
 
 507  
     public String getCycleType() {
 508  0
         return cycleType;
 509  
     }
 510  
 
 511  
     public String getRampType() {
 512  0
         return rampType;
 513  
     }
 514  
 
 515  
     public long getIterations() {
 516  0
         return iterations;
 517  
     }
 518  
 
 519  
     public long getStartTime() {
 520  0
         return startTime;
 521  
     }
 522  
 
 523  
     public long getPeriodStart() {
 524  0
         return periodStart;
 525  
     }
 526  
 
 527  
     public double getLastMean() {
 528  0
         return lastMean;
 529  
     }
 530  
 
 531  
     public int getCycleState() {
 532  0
         return cycleState;
 533  
     }
 534  
 
 535  
     public long getNumErrors() {
 536  0
         return numErrors;
 537  
     }
 538  
 
 539  
     public long getNumMisses() {
 540  0
         return numMisses;
 541  
     }
 542  
 
 543  
     public Statistics getStats() {
 544  0
         return stats;
 545  
     }
 546  
 
 547  
     public void setStartTime(long startTime) {
 548  0
         this.startTime = startTime;
 549  0
     }
 550  
 
 551  
     public void setPeriodStart(long periodStart) {
 552  0
         this.periodStart = periodStart;
 553  0
     }
 554  
 
 555  
     public void setLastMean(double lastMean) {
 556  0
         this.lastMean = lastMean;
 557  0
     }
 558  
 
 559  
     public void setCycleState(int cycleState) {
 560  0
         this.cycleState = cycleState;
 561  0
     }
 562  
 
 563  
     public void setNumErrors(long numErrors) {
 564  0
         this.numErrors = numErrors;
 565  0
     }
 566  
 
 567  
     public void setNumMisses(long numMisses) {
 568  0
         this.numMisses = numMisses;
 569  0
     }
 570  
 
 571  
     public void setRampType(String rampType) {
 572  0
         this.rampType = rampType;
 573  0
     }
 574  
 
 575  
     public void setMinDelay(long minDelay) {
 576  0
         this.minDelay = minDelay;
 577  0
     }
 578  
 
 579  
     public void setMaxDelay(long maxDelay) {
 580  0
         this.maxDelay = maxDelay;
 581  0
     }
 582  
 
 583  
     public void setSigma(double sigma) {
 584  0
         this.sigma = sigma;
 585  0
     }
 586  
 
 587  
     public void setDelayType(String delayType) {
 588  0
         this.delayType = delayType;
 589  0
     }
 590  
 
 591  
     public void setRampPeriod(long rampPeriod) {
 592  0
         this.rampPeriod = rampPeriod;
 593  0
     }
 594  
 
 595  
     public void setPeakPeriod(long peakPeriod) {
 596  0
         this.peakPeriod = peakPeriod;
 597  0
     }
 598  
 
 599  
     public void setTroughPeriod(long troughPeriod) {
 600  0
         this.troughPeriod = troughPeriod;
 601  0
     }
 602  
     
 603  
 }