KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > connector > outbound > SinglePoolMatchAllConnectionInterceptor


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.geronimo.connector.outbound;
19
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.Map JavaDoc;
24 import javax.resource.ResourceException JavaDoc;
25 import javax.resource.spi.ManagedConnection JavaDoc;
26 import javax.resource.spi.ManagedConnectionFactory JavaDoc;
27
28 /**
29  * This pool is the most spec-compliant pool. It can be used by itself with no partitioning.
30  * It is apt to be the slowest pool.
31  * For each connection request, it synchronizes access to the pool and asks the
32  * ManagedConnectionFactory for a match from among all managed connections. If none is found,
33  * it may discard a random existing connection, and creates a new connection.
34  *
35  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
36  */

37 public class SinglePoolMatchAllConnectionInterceptor extends AbstractSinglePoolConnectionInterceptor {
38
39     private HashMap JavaDoc pool;
40
41     private int maxSize;
42
43     public SinglePoolMatchAllConnectionInterceptor(final ConnectionInterceptor next,
44                                                    int maxSize,
45                                                    int minSize,
46                                                    int blockingTimeoutMilliseconds,
47                                                    int idleTimeoutMinutes) {
48
49         super(next, maxSize, minSize, blockingTimeoutMilliseconds, idleTimeoutMinutes);
50         this.maxSize = maxSize;
51         pool = new HashMap JavaDoc(maxSize);
52     }
53
54     protected void internalGetConnection(ConnectionInfo connectionInfo) throws ResourceException JavaDoc {
55         synchronized (pool) {
56             if (destroyed) {
57                 throw new ResourceException JavaDoc("ManagedConnection pool has been destroyed");
58             }
59             try {
60                 if (!pool.isEmpty()) {
61                     ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
62                     ManagedConnectionFactory JavaDoc managedConnectionFactory = mci.getManagedConnectionFactory();
63                     ManagedConnection JavaDoc matchedMC =
64                             managedConnectionFactory
65                             .matchManagedConnections(pool.keySet(),
66                                     mci.getSubject(),
67                                     mci.getConnectionRequestInfo());
68                     if (matchedMC != null) {
69                         connectionInfo.setManagedConnectionInfo((ManagedConnectionInfo) pool.get(matchedMC));
70                         pool.remove(matchedMC);
71                         if (log.isTraceEnabled()) {
72                             log.trace("Returning pooled connection " + connectionInfo.getManagedConnectionInfo());
73                         }
74                         if (connectionCount < minSize) {
75                             timer.schedule(new FillTask(connectionInfo), 10);
76                         }
77                         return;
78                     }
79                 }
80                 //matching failed or pool is empty
81
//if pool is at maximum size, pick a cx to kill
82
if (connectionCount == maxSize) {
83                     Iterator JavaDoc iterator = pool.entrySet().iterator();
84                     ManagedConnectionInfo kill = (ManagedConnectionInfo) ((Map.Entry JavaDoc) iterator.next()).getValue();
85                     iterator.remove();
86                     ConnectionInfo killInfo = new ConnectionInfo(kill);
87                     internalReturn(killInfo, ConnectionReturnAction.DESTROY);
88                 }
89                 next.getConnection(connectionInfo);
90                 connectionCount++;
91                 if (log.isTraceEnabled()) {
92                     log.trace("Returning new connection " + connectionInfo.getManagedConnectionInfo());
93                 }
94                 if (connectionCount < minSize) {
95                     timer.schedule(new FillTask(connectionInfo), 10);
96                 }
97
98             } catch (ResourceException JavaDoc e) {
99                 //something is wrong: rethrow, release permit
100
permits.release();
101                 throw e;
102             }
103         }
104     }
105
106     protected boolean internalReturn(ConnectionInfo connectionInfo, ConnectionReturnAction connectionReturnAction) {
107         ManagedConnectionInfo mci = connectionInfo.getManagedConnectionInfo();
108         ManagedConnection JavaDoc mc = mci.getManagedConnection();
109         try {
110             mc.cleanup();
111         } catch (ResourceException JavaDoc e) {
112             connectionReturnAction = ConnectionReturnAction.DESTROY;
113         }
114
115         boolean wasInPool = false;
116         synchronized (pool) {
117             // a bit redundant, but this closes a small timing hole...
118
if (destroyed) {
119                 try {
120                     mc.destroy();
121                 }
122                 catch (ResourceException JavaDoc re) { } // ignore
123
return pool.remove(mci.getManagedConnection()) != null;
124             }
125             if (shrinkLater > 0) {
126                 //nothing can get in the pool while shrinkLater > 0, so wasInPool is false here.
127
connectionReturnAction = ConnectionReturnAction.DESTROY;
128                 shrinkLater--;
129             } else if (connectionReturnAction == ConnectionReturnAction.RETURN_HANDLE) {
130                 mci.setLastUsed(System.currentTimeMillis());
131                 pool.put(mci.getManagedConnection(), mci);
132                 return wasInPool;
133             } else {
134                 wasInPool = pool.remove(mci.getManagedConnection()) != null;
135             }
136         }
137         //we must destroy connection.
138
next.returnConnection(connectionInfo, connectionReturnAction);
139         connectionCount--;
140         return wasInPool;
141     }
142
143     protected void internalDestroy() {
144         synchronized (pool) {
145             Iterator JavaDoc it = pool.keySet().iterator();
146             for (; it.hasNext(); ) {
147                 try {
148                     ((ManagedConnection JavaDoc)it.next()).destroy();
149                 }
150                 catch (ResourceException JavaDoc re) { } // ignore
151
it.remove();
152             }
153         }
154     }
155
156     public int getPartitionMaxSize() {
157         return maxSize;
158     }
159
160     public int getIdleConnectionCount() {
161         return pool.size();
162     }
163
164     protected void transferConnections(int maxSize, int shrinkNow) {
165         //1st example: copy 0 (none)
166
//2nd example: copy 10 (all)
167
HashMap JavaDoc oldPool = pool;
168         pool = new HashMap JavaDoc(maxSize);
169         //since we have replaced pool already, pool.remove will be very fast:-)
170
assert oldPool.size() == connectionCount;
171         Iterator JavaDoc it = oldPool.entrySet().iterator();
172         for (int i = 0; i < shrinkNow; i++) {
173             ConnectionInfo killInfo = new ConnectionInfo((ManagedConnectionInfo) ((Map.Entry JavaDoc)it.next()).getValue());
174             internalReturn(killInfo, ConnectionReturnAction.DESTROY);
175         }
176         for (; it.hasNext(); ) {
177             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
178             pool.put(entry.getKey(), entry.getValue());
179         }
180
181     }
182
183     protected void getExpiredManagedConnectionInfos(long threshold, ArrayList JavaDoc killList) {
184         synchronized (pool) {
185             for (Iterator JavaDoc iterator = pool.entrySet().iterator(); iterator.hasNext();) {
186                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
187                 ManagedConnectionInfo mci = (ManagedConnectionInfo) entry.getValue();
188                 if (mci.getLastUsed() < threshold) {
189                     killList.add(mci);
190                 }
191             }
192         }
193
194     }
195
196     protected boolean addToPool(ManagedConnectionInfo mci) {
197         boolean added;
198         synchronized (pool) {
199             connectionCount++;
200             added = getPartitionMaxSize() > getIdleConnectionCount();
201             if (added) {
202                 pool.put(mci.getManagedConnection(), mci);
203             }
204         }
205         return added;
206     }
207
208 }
209
Popular Tags