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 }