001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.performance.pool;
019
020 import java.util.ArrayList;
021 import java.util.List;
022 import java.util.logging.Logger;
023
024 import org.apache.commons.pool.ObjectPool;
025 import org.apache.commons.pool.KeyedObjectPool;
026 import org.apache.commons.math.random.RandomData;
027 import org.apache.commons.math.random.RandomDataImpl;
028 import org.apache.commons.math.stat.descriptive.SummaryStatistics;
029 import org.apache.commons.performance.ClientThread;
030 import org.apache.commons.performance.Statistics;
031
032 /**
033 * Client thread that borrows and returns objects from a pool in a loop.
034 * See {@link ClientThread ClientThread javadoc} for a description
035 * of how times between requests are computed.
036 *
037 */
038 public class PoolClientThread extends ClientThread {
039
040 private ObjectPool pool;
041 private KeyedObjectPool keyedPool;
042 private boolean keyed;
043 private List<Integer> keys;
044 private RandomData randomData = new RandomDataImpl();
045 private SummaryStatistics numActiveStats = new SummaryStatistics();
046 private SummaryStatistics numIdleStats = new SummaryStatistics();
047 private double samplingRate = 0;
048
049 /**
050 * Create a pool client thread for an ObjectPool.
051 *
052 * @param iterations number of iterations
053 * @param minDelay minimum mean time between client requests
054 * @param maxDelay maximum mean time between client requests
055 * @param delayType distribution of time between client requests
056 * @param rampPeriod ramp period of cycle for cyclic load
057 * @param peakPeriod peak period of cycle for cyclic load
058 * @param troughPeriod trough period of cycle for cyclic load
059 * @param cycleType type of cycle for mean delay
060 * @param rampType type of ramp (linear or random jumps)
061 * @param logger common logger shared by all clients
062 * @param stats Statistics container
063 * @param pool ObjectPool
064 */
065 public PoolClientThread(long iterations, long minDelay, long maxDelay,
066 double sigma, String delayType, long rampPeriod, long peakPeriod,
067 long troughPeriod, String cycleType, String rampType, Logger logger,
068 Statistics stats, ObjectPool pool, double samplingRate) {
069
070 super(iterations, minDelay, maxDelay, sigma, delayType, rampPeriod,
071 peakPeriod, troughPeriod, cycleType,rampType, logger,
072 stats);
073 this.pool = pool;
074 this.keyed = false;
075 this.samplingRate = samplingRate;
076 }
077
078 /**
079 * Create a pool client thread for a KeyedObjectPool.
080 *
081 * @param iterations number of iterations
082 * @param minDelay minimum mean time between client requests
083 * @param maxDelay maximum mean time between client requests
084 * @param delayType distribution of time between client requests
085 * @param rampPeriod ramp period of cycle for cyclic load
086 * @param peakPeriod peak period of cycle for cyclic load
087 * @param troughPeriod trough period of cycle for cyclic load
088 * @param cycleType type of cycle for mean delay
089 * @param rampType type of ramp (linear or random jumps)
090 * @param logger common logger shared by all clients
091 * @param stats Statistics container
092 * @param keyedPool KeyedObjectPool
093 */
094 public PoolClientThread(long iterations, long minDelay, long maxDelay,
095 double sigma, String delayType, long rampPeriod, long peakPeriod,
096 long troughPeriod, String cycleType, String rampType, Logger logger,
097 Statistics stats, KeyedObjectPool keyedPool, double samplingRate) {
098
099 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 }