View Javadoc

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.pool;
19  
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.logging.Logger;
23  
24  import org.apache.commons.pool.ObjectPool;
25  import org.apache.commons.pool.KeyedObjectPool;
26  import org.apache.commons.math.random.RandomData;
27  import org.apache.commons.math.random.RandomDataImpl;
28  import org.apache.commons.math.stat.descriptive.SummaryStatistics;
29  import org.apache.commons.performance.ClientThread;
30  import org.apache.commons.performance.Statistics;
31  
32  /**
33   * Client thread that borrows and returns objects from a pool in a loop.
34   * See {@link ClientThread ClientThread javadoc} for a description
35   * of how times between requests are computed.
36   *
37   */
38  public class PoolClientThread extends ClientThread {
39      
40      private ObjectPool pool;
41      private KeyedObjectPool keyedPool;
42      private boolean keyed;
43      private List<Integer> keys;
44      private RandomData randomData = new RandomDataImpl();
45      private SummaryStatistics numActiveStats = new SummaryStatistics();
46      private SummaryStatistics numIdleStats = new SummaryStatistics();
47      private double samplingRate = 0;
48       
49      /**
50       * Create a pool client thread for an ObjectPool.
51       * 
52       * @param iterations number of iterations
53       * @param minDelay minimum mean time between client requests
54       * @param maxDelay maximum mean time between client requests
55       * @param delayType distribution of time between client requests
56       * @param rampPeriod ramp period of cycle for cyclic load
57       * @param peakPeriod peak period of cycle for cyclic load
58       * @param troughPeriod trough period of cycle for cyclic load
59       * @param cycleType type of cycle for mean delay
60       * @param rampType type of ramp (linear or random jumps)
61       * @param logger common logger shared by all clients
62       * @param stats Statistics container
63       * @param pool ObjectPool
64       */
65      public PoolClientThread(long iterations, long minDelay, long maxDelay,
66              double sigma, String delayType, long rampPeriod, long peakPeriod,
67              long troughPeriod, String cycleType, String rampType, Logger logger, 
68              Statistics stats, ObjectPool pool, double samplingRate) {
69          
70          super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
71                  peakPeriod, troughPeriod, cycleType,rampType, logger, 
72                  stats); 
73          this.pool = pool;
74          this.keyed = false;
75          this.samplingRate = samplingRate;
76      }
77      
78      /**
79       * Create a pool client thread for a KeyedObjectPool.
80       * 
81       * @param iterations number of iterations
82       * @param minDelay minimum mean time between client requests
83       * @param maxDelay maximum mean time between client requests
84       * @param delayType distribution of time between client requests
85       * @param rampPeriod ramp period of cycle for cyclic load
86       * @param peakPeriod peak period of cycle for cyclic load
87       * @param troughPeriod trough period of cycle for cyclic load
88       * @param cycleType type of cycle for mean delay
89       * @param rampType type of ramp (linear or random jumps)
90       * @param logger common logger shared by all clients
91       * @param stats Statistics container 
92       * @param keyedPool KeyedObjectPool
93       */
94      public PoolClientThread(long iterations, long minDelay, long maxDelay,
95              double sigma, String delayType, long rampPeriod, long peakPeriod,
96              long troughPeriod, String cycleType, String rampType, Logger logger, 
97              Statistics stats, KeyedObjectPool keyedPool, double samplingRate) {
98          
99          super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
100                 peakPeriod, troughPeriod, cycleType,rampType, logger, 
101                 stats); 
102         
103         this.keyedPool = keyedPool;
104         this.keyed = true;
105         this.samplingRate = samplingRate;
106         keys = new ArrayList<Integer>();
107         for (int i = 0; i < 20; i++) { //TODO: make number of keys configurable
108             keys.add(new Integer(i));
109         }
110         randomData = new RandomDataImpl();
111     }
112     
113     /** Borrow and return */
114     public void execute() throws Exception {
115        if (keyed) {
116            Integer key = keys.get(randomData.nextInt(0, 19));
117            Waiter waiter = (Waiter) keyedPool.borrowObject(key);
118            waiter.doWait();
119            keyedPool.returnObject(key, waiter);
120        } else {
121            Waiter waiter = (Waiter) pool.borrowObject(); 
122            waiter.doWait();
123            pool.returnObject(waiter);
124        }
125     }
126     
127     protected void cleanUp() throws Exception {
128         // Capture pool metrics 
129         if (randomData.nextUniform(0, 1) < samplingRate) {
130             if (keyed) {
131                 numIdleStats.addValue(keyedPool.getNumIdle());
132                 numActiveStats.addValue(keyedPool.getNumActive());
133             } else {
134                 numIdleStats.addValue(pool.getNumIdle());
135                 numActiveStats.addValue(pool.getNumActive());
136             }
137         }
138     }
139     
140     protected void finish() throws Exception {
141         // Add pool metrics to stats
142         stats.addStatistics(
143                 numIdleStats, Thread.currentThread().getName(), "numIdle");
144         stats.addStatistics(
145                 numActiveStats, Thread.currentThread().getName(), "numActive");
146     }
147 }