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 }