1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.pool;
19
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Iterator;
23
24 import org.apache.commons.pool.PoolableObjectFactory;
25 import org.apache.commons.pool.KeyedPoolableObjectFactory;
26
27
28
29
30
31
32
33
34
35 public class WaiterFactory implements PoolableObjectFactory,
36 KeyedPoolableObjectFactory {
37
38
39 private final long activateLatency;
40
41
42 private final long destroyLatency;
43
44
45 private final long makeLatency;
46
47
48 private final long passivateLatency;
49
50
51 private final long validateLatency;
52
53
54 private final long waiterLatency;
55
56
57 private final double passivateInvalidationProbability;
58
59
60 private long activeCount = 0;
61
62
63 private Map activeCounts = new HashMap();
64
65
66 private final long maxActive;
67
68
69 private final long maxActivePerKey;
70
71 public WaiterFactory(long activateLatency, long destroyLatency,
72 long makeLatency, long passivateLatency, long validateLatency,
73 long waiterLatency,long maxActive, long maxActivePerKey,
74 double passivateInvalidationProbability) {
75 this.activateLatency = activateLatency;
76 this.destroyLatency = destroyLatency;
77 this.makeLatency = makeLatency;
78 this.passivateLatency = passivateLatency;
79 this.validateLatency = validateLatency;
80 this.waiterLatency = waiterLatency;
81 this.maxActive = maxActive;
82 this.maxActivePerKey = maxActivePerKey;
83 this.passivateInvalidationProbability = passivateInvalidationProbability;
84 }
85
86 public WaiterFactory(long activateLatency, long destroyLatency,
87 long makeLatency, long passivateLatency, long validateLatency,
88 long waiterLatency) {
89 this(activateLatency, destroyLatency, makeLatency, passivateLatency,
90 validateLatency, waiterLatency, Long.MAX_VALUE, Long.MAX_VALUE, 0);
91 }
92
93 public WaiterFactory(long activateLatency, long destroyLatency,
94 long makeLatency, long passivateLatency, long validateLatency,
95 long waiterLatency,long maxActive) {
96 this(activateLatency, destroyLatency, makeLatency, passivateLatency,
97 validateLatency, waiterLatency, maxActive, Long.MAX_VALUE, 0);
98 }
99
100 public void activateObject(Object obj) throws Exception {
101 doWait(activateLatency);
102 ((Waiter) obj).setActive(true);
103 }
104
105 public void destroyObject(Object obj) throws Exception {
106 doWait(destroyLatency);
107 ((Waiter) obj).setValid(false);
108 ((Waiter) obj).setActive(false);
109
110 synchronized (this) {
111 activeCount--;
112 }
113 }
114
115 public Object makeObject() throws Exception {
116
117 synchronized (this) {
118 if (activeCount >= maxActive) {
119 throw new IllegalStateException("Too many active instances: " +
120 activeCount + " in circulation with maxActive = " + maxActive);
121 } else {
122 activeCount++;
123 }
124 }
125 doWait(makeLatency);
126 return new Waiter(false, true, waiterLatency);
127 }
128
129 public void passivateObject(Object arg0) throws Exception {
130 ((Waiter) arg0).setActive(false);
131 doWait(passivateLatency);
132 if (Math.random() < passivateInvalidationProbability) {
133 ((Waiter) arg0).setValid(false);
134 }
135 }
136
137 public boolean validateObject(Object arg0) {
138 doWait(validateLatency);
139 return ((Waiter) arg0).isValid();
140 }
141
142 protected void doWait(long latency) {
143 try {
144 Thread.sleep(latency);
145 } catch (InterruptedException ex) {
146
147 }
148 }
149
150 public synchronized void reset() {
151 activeCount = 0;
152 if (activeCounts.isEmpty()) {
153 return;
154 }
155 Iterator it = activeCounts.keySet().iterator();
156 while (it.hasNext()) {
157 Object key = it.next();
158 activeCounts.put(key, new Integer (0));
159 }
160 }
161
162
163
164
165 public synchronized long getMaxActive() {
166 return maxActive;
167 }
168
169
170
171 public void activateObject(Object key, Object obj) throws Exception {
172 activateObject(obj);
173 }
174
175 public void destroyObject(Object key, Object obj) throws Exception {
176 destroyObject(obj);
177 synchronized (this) {
178 Integer count = (Integer) activeCounts.get(key);
179 activeCounts.put(key, new Integer(count.intValue() - 1));
180 }
181 }
182
183 public Object makeObject(Object key) throws Exception {
184 synchronized (this) {
185 Integer count = (Integer) activeCounts.get(key);
186 if (count == null) {
187 count = new Integer(1);
188 activeCounts.put(key, count);
189 } else {
190 if (count.intValue() >= maxActivePerKey) {
191 throw new IllegalStateException("Too many active " +
192 "instances for key = " + key + ": " + count.intValue() +
193 " in circulation " + "with maxActivePerKey = " +
194 maxActivePerKey);
195 } else {
196 activeCounts.put(key, new Integer(count.intValue() + 1));
197 }
198 }
199 }
200 return makeObject();
201 }
202
203 public void passivateObject(Object key, Object obj) throws Exception {
204 passivateObject(obj);
205 }
206
207 public boolean validateObject(Object key, Object obj) {
208 return validateObject(obj);
209 }
210
211 }