KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > resource > pool > lib > HArrayPool


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * ObjectWeb Connector: an implementation of JCA Sun specification along
7  * with some extensions of this specification.
8  * Copyright (C) 2001-2002 France Telecom R&D - INRIA
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  * Based on LArrayPool in ObjectWeb common
25  *
26  * --------------------------------------------------------------------------
27  * $Id: HArrayPool.java,v 1.24 2005/07/22 12:35:12 durieuxp Exp $
28  * --------------------------------------------------------------------------
29  */

30
31 package org.objectweb.jonas.resource.pool.lib;
32
33 import java.util.HashSet JavaDoc;
34 import java.util.Hashtable JavaDoc;
35 import java.util.LinkedList JavaDoc;
36 import java.util.Iterator JavaDoc;
37 import java.util.Vector JavaDoc;
38
39 import javax.resource.spi.ManagedConnection JavaDoc;
40
41 import org.objectweb.jonas.resource.ConnectionManagerImpl;
42 import org.objectweb.jonas.resource.pool.api.Pool;
43 import org.objectweb.jonas.resource.pool.api.PoolItemStats;
44 import org.objectweb.jonas.resource.pool.api.PoolMatchFactory;
45 import org.objectweb.util.monolog.api.BasicLevel;
46 import org.objectweb.util.monolog.api.Logger;
47
48 /**
49  * The class <b>HArrayPool</b> implements a Pool as a HashSet of ManagedConnections,
50  * managing free/active resources.
51  *
52  * Updated to use an LRU list of free resources
53  *
54  * Author: Eric HARDESTY
55  */

56 public class HArrayPool implements Pool {
57
58     /**
59      * The Logger instance where messages are written.
60      */

61     private Logger logger = null;
62
63     /**
64      * timeout value
65      */

66     private long timeout = 0;
67     /**
68      * Pool match factory for this pool
69      */

70     private PoolMatchFactory matchFactory = null;
71     /**
72      * Free list of ManagedConnections
73      */

74     private HashSet JavaDoc freeList = null;
75     /**
76      * Active list of ManagedConnections
77      */

78     private HashSet JavaDoc activeList = null;
79     /**
80      * PoolItem information list
81      */

82     private Hashtable JavaDoc infoList = null;
83
84     /**
85      * High Value for no limit for the connection pool
86      */

87     private static final int NO_LIMIT = -1;
88
89     /**
90      * Nb of milliseconds in a day
91      */

92     private static final long ONE_DAY = 1440L * 60L * 1000L;
93
94     /**
95      * max number of remove at once in the freelist
96      * We avoid removing too many items at once for perf reasons.
97      */

98     private static final int MAX_REMOVE_FREELIST = 10;
99
100     /**
101      * count min busy connection during current period.
102      */

103     private int busyMin = 0;
104
105     /**
106      * count max busy connection during current period.
107      */

108     private int busyMax = 0;
109
110     /**
111      * initial size of the pool
112      */

113     private int initSize = -1;
114
115     /**
116      * max age a connection will be available for use
117      */

118     private int maxAge = 0;
119
120     /**
121      * max open time for a connection, in minutes
122      */

123     private int maxOpentime = 0;
124
125     /**
126      * max size of the pool
127      */

128     private int maxSize = -1;
129
130     /**
131      * max nb of waiters allowed to wait for a Connection
132      */

133     private int maxWaiters = 1000;
134
135     /**
136      * max nb of milliseconds to wait for a connection when pool is full
137      */

138     private long maxWaitTimeout = 10000;
139
140     /**
141      * minimum size of the pool
142      */

143     private int minSize = 0;
144
145     /**
146      * pool monitor
147      */

148     private HArrayPoolMonitor poolMonitor = null;
149
150     /**
151      * sampling period in sec.
152      */

153     private int samplingPeriod = 60; // defaultSamplingPeriod;
154

155     /**
156      * count max waiters during current period.
157      */

158     private int waiterCount = 0;
159
160     /**
161      * count max waiting time during current period.
162      */

163     private long waitingTime = 0;
164
165
166     /**
167      * HArrayPool constructor
168      * @param logger Logger for the pool to use
169      */

170     public HArrayPool(Logger logger) {
171         this.logger = logger;
172         freeList = new HashSet JavaDoc();
173         activeList = new HashSet JavaDoc();
174         infoList = new Hashtable JavaDoc();
175     }
176
177     // ----------------------------------------------------------------
178
// Config properties (Getters & Setters)
179
// ----------------------------------------------------------------
180

181     /**
182      * @return int number of busy connections
183      */

184     public int getCurrentBusy() {
185         return activeList.size();
186     }
187
188     /**
189      * @return int number of opened connections
190      */

191     public int getCurrentOpened() {
192         return getSize();
193     }
194
195     /**
196      * @see org.objectweb.jonas.resource.pool.api.Pool#getInitSize
197      */

198     public int getInitSize() {
199         return initSize;
200     }
201
202     /**
203      * @see org.objectweb.jonas.resource.pool.api.Pool#setInitSize
204      */

205     public synchronized void setInitSize(int initsize) throws Exception JavaDoc {
206         if (matchFactory == null) {
207             throw new Exception JavaDoc("The matchFactory is mandatory!");
208         }
209         if (initSize < 0 && initsize >= 0) {
210             initSize = initsize;
211             setInitSize();
212         }
213     }
214
215     /**
216      * Internal setInitSize
217      * @throws Exception if an error is encountered
218      */

219     private void setInitSize() throws Exception JavaDoc {
220         int initsize;
221
222         if (initSize <= 0) {
223             return;
224         }
225
226         if (maxSize < 0) {
227             initsize = initSize;
228         } else {
229             initsize = initSize < maxSize ? initSize : maxSize;
230         }
231         initsize = initsize < minSize ? 0 : initsize - minSize;
232
233         ManagedConnection JavaDoc res;
234         synchronized (this) {
235             for (int i = 0; i < initsize; i++) {
236                 res = createResource(null);
237                 freeList.add(res);
238                 infoList.put(res, new PoolItemStats());
239             }
240         }
241     }
242
243     /**
244      * @see org.objectweb.jonas.resource.pool.api.Pool#getMaxAge
245      */

246     public int getMaxAge() {
247         return maxAge;
248     }
249
250     /**
251      * @see org.objectweb.jonas.resource.pool.api.Pool#setMaxAge
252      */

253     public void setMaxAge(int maxAge) {
254         this.maxAge = maxAge;
255     }
256
257     /**
258      * @return max age for connections (in mns)
259      */

260     public int getMaxOpentime() {
261         return maxOpentime;
262     }
263
264     /**
265      * @param mx max time of open connection in minutes
266      */

267     public void setMaxOpentime(int mx) {
268         maxOpentime = mx;
269     }
270
271     /**
272      * @see org.objectweb.jonas.resource.pool.api.Pool#getMaxSize
273      */

274     public int getMaxSize() {
275         return maxSize;
276     }
277
278     /**
279      * @see org.objectweb.jonas.resource.pool.api.Pool#setMaxSize
280      */

281     public synchronized void setMaxSize(int maxsize) throws Exception JavaDoc {
282         if (matchFactory == null) {
283             throw new Exception JavaDoc("The matchFactory mandatory!!");
284         }
285         if (maxsize < minSize || maxsize == maxSize) {
286             return;
287         }
288
289         // Determine if we need to adjust the pool
290
if (maxsize < 0) {
291             if (currentWaiters > 0) {
292                 notify();
293             }
294             maxSize = maxsize;
295         } else {
296             if (currentWaiters > 0 && maxSize < maxsize) {
297                 notify();
298             }
299             maxSize = maxsize;
300             adjust();
301         }
302     }
303
304     /**
305      * @return max nb of waiters
306      */

307     public int getMaxWaiters() {
308         return maxWaiters;
309     }
310
311     /**
312      * @param nb max nb of waiters
313      */

314     public void setMaxWaiters(int nb) {
315         maxWaiters = nb;
316     }
317
318     /**
319      * @return waiter timeout in seconds
320      */

321     public int getMaxWaitTime() {
322         return (int) (maxWaitTimeout / 1000L);
323     }
324
325     /**
326      * @param sec max time to wait for a connection, in seconds
327      */

328     public void setMaxWaitTime(int sec) {
329         maxWaitTimeout = sec * 1000L;
330     }
331
332     /**
333      * @see org.objectweb.jonas.resource.pool.api.Pool#getMinSize
334      */

335     public int getMinSize() {
336         return minSize;
337     }
338
339     /**
340      * @see org.objectweb.jonas.resource.pool.api.Pool#setMinSize
341      */

342     public synchronized void setMinSize(int minsize) throws Exception JavaDoc {
343         if (matchFactory == null) {
344             throw new Exception JavaDoc("A matchFactory is mandatory!");
345         }
346         if ((minsize < 0) || (minsize > maxSize) || (minsize == minSize)) {
347             return;
348         }
349         if (minsize < minSize) {
350             minSize = minsize;
351             return;
352         }
353         minSize = minsize;
354         adjust();
355     }
356
357     /**
358      * @return sampling period in sec.
359      */

360     public int getSamplingPeriod() {
361         return samplingPeriod;
362     }
363
364     /**
365      * @param sec sampling period in sec.
366      */

367     public void setSamplingPeriod(int sec) {
368         if (sec > 0) {
369             samplingPeriod = sec;
370             poolMonitor.setSamplingPeriod(sec);
371         }
372     }
373
374     /**
375      * Get the size of the pool
376      * @return int size of the pool
377      */

378     public synchronized int getSize() {
379         return (activeList.size() + freeList.size());
380     }
381
382     /**
383      * @see org.objectweb.jonas.resource.pool.api.Pool#getTimeout
384      */

385     public long getTimeout() {
386         return timeout;
387     }
388
389     /**
390      * @see org.objectweb.jonas.resource.pool.api.Pool#setTimeout
391      */

392     public synchronized void setTimeout(long crto) {
393     }
394
395
396     // ----------------------------------------------------------------
397
// Monitoring Attributes
398
// Each attribute should have a get accessor.
399
// ----------------------------------------------------------------
400

401     /**
402      * maximum nb of busy connections in last sampling period
403      */

404     private int busyMaxRecent = 0;
405
406     /**
407      * @return maximum nb of busy connections in last sampling period
408      */

409     public int getBusyMaxRecent() {
410         return busyMaxRecent;
411     }
412
413     /**
414      * minimum nb of busy connections in last sampling period
415      */

416     private int busyMinRecent = 0;
417
418     /**
419      * @return minimum nb of busy connections in last sampling period
420      */

421     public int getBusyMinRecent() {
422         return busyMinRecent;
423     }
424
425     /**
426      * nb of threads waiting for a Connection
427      */

428     private int currentWaiters = 0;
429
430     /**
431      * @return current number of connection waiters
432      */

433     public int getCurrentWaiters() {
434         return currentWaiters;
435     }
436
437     /**
438      * total number of opened physical connections since the datasource creation.
439      */

440     private int openedCount = 0;
441
442     /**
443      * @return int number of physical jdbc connection opened
444      */

445     public int getOpenedCount() {
446         return openedCount;
447     }
448
449     /**
450      * total nb of physical connection failures
451      */

452     private int connectionFailures = 0;
453
454     /**
455      * @return int number of connection failures on open
456      */

457     public int getConnectionFailures() {
458         return connectionFailures;
459     }
460
461     /**
462      * total nb of connection leaks.
463      * A connection leak occurs when the caller never issues a close method
464      * on the connection.
465      */

466     private int connectionLeaks = 0;
467
468     /**
469      * @return int number of connection leaks
470      */

471     public int getConnectionLeaks() {
472         return connectionLeaks;
473     }
474
475     /**
476      * total number of opened connections since the datasource creation.
477      */

478     private int servedOpen = 0;
479
480     /**
481      * @return int number of connection served
482      */

483     public int getServedOpen() {
484         return servedOpen;
485     }
486
487     /**
488      * total nb of open connection failures because waiter overflow
489      */

490     private int rejectedFull = 0;
491
492     /**
493      * @return int number of open calls that were rejected due to waiter overflow
494      */

495     public int getRejectedFull() {
496         return rejectedFull;
497     }
498
499     /**
500      * total nb of open connection failures because timeout
501      */

502     private int rejectedTimeout = 0;
503
504     /**
505      * @return int number of open calls that were rejected by timeout
506      */

507     public int getRejectedTimeout() {
508         return rejectedTimeout;
509     }
510
511     /**
512      * total nb of open connection failures for any other reason.
513      */

514     private int rejectedOther = 0;
515
516     /**
517      * @return int number of open calls that were rejected
518      */

519     public int getRejectedOther() {
520         return rejectedOther;
521     }
522
523     /**
524      * @return int number of open calls that were rejected
525      */

526     public int getRejectedOpen() {
527         return rejectedFull + rejectedTimeout + rejectedOther;
528     }
529
530     /**
531      * maximum nb of waiters since datasource creation
532      */

533     private int waitersHigh = 0;
534
535     /**
536      * @return maximum nb of waiters since the datasource creation
537      */

538     public int getWaitersHigh() {
539         return waitersHigh;
540     }
541
542     /**
543      * maximum nb of waiters in last sampling period
544      */

545     private int waitersHighRecent = 0;
546
547     /**
548      * @return maximum nb of waiters in last sampling period
549      */

550     public int getWaitersHighRecent() {
551         return waitersHighRecent;
552     }
553
554     /**
555      * total nb of waiters since datasource creation
556      */

557     private int totalWaiterCount = 0;
558
559     /**
560      * @return total nb of waiters since the datasource creation
561      */

562     public int getWaiterCount() {
563         return totalWaiterCount;
564     }
565
566     /**
567      * total waiting time in milliseconds
568      */

569     private long totalWaitingTime = 0;
570
571     /**
572      * @return total waiting time since the datasource creation
573      */

574     public long getWaitingTime() {
575         return totalWaitingTime;
576     }
577
578     /**
579      * max waiting time in milliseconds
580      */

581     private long waitingHigh = 0;
582
583     /**
584      * @return max waiting time since the datasource creation
585      */

586     public long getWaitingHigh() {
587         return waitingHigh;
588     }
589
590     /**
591      * max waiting time in milliseconds in last sampling period
592      */

593     private long waitingHighRecent = 0;
594
595     /**
596      * @return max waiting time in last sampling period
597      */

598     public long getWaitingHighRecent() {
599         return waitingHighRecent;
600     }
601
602     // IMPLEMENTATION OF METHODS FROM THE Pool INTERFACE
603

604     /**
605      * @see org.objectweb.jonas.resource.pool.api.Pool#getResource
606      */

607     public synchronized Object JavaDoc getResource(Object JavaDoc hints)
608         throws Exception JavaDoc {
609
610         if (matchFactory == null) {
611             throw new Exception JavaDoc("The matchFactory mandatory!!");
612         }
613         ManagedConnection JavaDoc res = null;
614         long timetowait = maxWaitTimeout;
615         long starttime = 0;
616         while (res == null) {
617             if (!freeList.isEmpty()) {
618                 try {
619                     if (logger.isLoggable(BasicLevel.DEBUG)) {
620                         logger.log(BasicLevel.DEBUG, "Free entries available");
621                     }
622                     res = (ManagedConnection JavaDoc) matchFactory.matchResource(freeList, hints);
623                     if (res != null) {
624                         freeList.remove(res);
625                         activeList.add(res);
626                     }
627                 } catch (Exception JavaDoc ex) {
628                     if (logger.isLoggable(BasicLevel.DEBUG)) {
629                         logger.log(BasicLevel.DEBUG, "Error from matchResource", ex);
630                     }
631                 }
632             }
633             if (res == null) {
634                 int curSize = activeList.size() + freeList.size();
635                 if (maxSize < 0 || curSize < maxSize) {
636                     res = createResource(hints);
637                     activeList.add(res);
638                 } else if (freeList.size() > 0) {
639                     res = (ManagedConnection JavaDoc) freeList.iterator().next();
640                     matchFactory.releaseResource(res);
641                     res.destroy();
642                     freeList.remove(res);
643                     infoList.remove(res);
644                     // Create a new one and return it
645
res = createResource(hints);
646                     activeList.add(res);
647                 } else {
648                     boolean stoplooping = true;
649                     // Determine if waiting is an option
650
if (timetowait > 0) {
651                         if (currentWaiters < maxWaiters) {
652                             currentWaiters++;
653                             // Store the maximum concurrent waiters
654
if (waiterCount < currentWaiters) {
655                                 waiterCount = currentWaiters;
656                             }
657                             if (starttime == 0) {
658                                 starttime = System.currentTimeMillis();
659                                 if (logger.isLoggable(BasicLevel.DEBUG)) {
660                                     logger.log(BasicLevel.DEBUG, "Wait for a free Connection");
661                                 }
662                             }
663                             try {
664                                 wait(timetowait);
665                             } catch (InterruptedException JavaDoc ign) {
666                                 logger.log(BasicLevel.WARN, "Interrupted");
667                             } finally {
668                                 currentWaiters--;
669                             }
670                             long stoptime = System.currentTimeMillis();
671                             long stillwaited = stoptime - starttime;
672                             timetowait = maxWaitTimeout - stillwaited;
673                             stoplooping = (timetowait <= 0);
674                             if (stoplooping) {
675                                 // We have been woken up by the timeout.
676
totalWaiterCount++;
677                                 totalWaitingTime += stillwaited;
678                                 if (waitingTime < stillwaited) {
679                                     waitingTime = stillwaited;
680                                 }
681                             } else {
682                                 if (!freeList.isEmpty()) {
683                                     // We have been notified by a connection release.
684
if (logger.isLoggable(BasicLevel.DEBUG)) {
685                                         logger.log(BasicLevel.DEBUG, "Notified after " + stillwaited);
686                                     }
687                                     totalWaiterCount++;
688                                     totalWaitingTime += stillwaited;
689                                     if (waitingTime < stillwaited) {
690                                         waitingTime = stillwaited;
691                                     }
692                                 }
693                                 continue;
694                             }
695                         }
696                     }
697                     if (stoplooping && freeList.isEmpty()) {
698                         if (starttime > 0) {
699                             rejectedTimeout++;
700                             logger.log(BasicLevel.WARN, "Cannot create a Connection - timeout");
701                         } else {
702                             rejectedFull++;
703                             logger.log(BasicLevel.WARN, "Cannot create a Connection");
704                         }
705                         throw new Exception JavaDoc("No more connections");
706                     }
707                 }
708             }
709         }
710         infoList.put(res, new PoolItemStats());
711
712         printLists();
713         setItemStats(res);
714         recomputeBusy();
715         return res;
716     }
717
718     /**
719      * Create a resource
720      * @param hints Object to pass to the matchFactory
721      * @return ManagedConnection object returned from the matchFactory
722      * @throws Exception if an exception occured
723      */

724     private ManagedConnection JavaDoc createResource(Object JavaDoc hints) throws Exception JavaDoc {
725         ManagedConnection JavaDoc res = null;
726         try {
727             res = (ManagedConnection JavaDoc) matchFactory.createResource(hints);
728             if (res == null) {
729                 Exception JavaDoc exc = new Exception JavaDoc("A null ManagedConnection was returned.");
730                 throw exc;
731             }
732             openedCount++;
733         } catch (Exception JavaDoc ex) {
734             connectionFailures++;
735             rejectedOther++;
736             if (logger.isLoggable(BasicLevel.DEBUG)) {
737                 logger.log(BasicLevel.DEBUG, "Cannot create new Connection", ex);
738             }
739             throw ex;
740         }
741         if (logger.isLoggable(BasicLevel.DEBUG)) {
742             logger.log(BasicLevel.DEBUG, "Created Resource: " + res);
743         }
744         return res;
745     }
746
747     /**
748      * @see org.objectweb.jonas.resource.pool.api.Pool#releaseResource
749      */

750     public synchronized void releaseResource(Object JavaDoc resource, boolean destroy, boolean adjustment)
751         throws Exception JavaDoc {
752
753         ManagedConnection JavaDoc res = (ManagedConnection JavaDoc) resource;
754         if (matchFactory == null) {
755             throw new Exception JavaDoc("The matchFactory mandatory!!");
756         }
757         if (activeList == null) {
758             throw new Exception JavaDoc("No active resources to releases!!");
759         }
760         if (!activeList.contains(res)) {
761             //Temp fix making the assumption that the item is already released
762
return;
763             //throw new Exception("Attempt to release inactive resource(" + res + ")");
764
}
765         activeList.remove(res);
766         if (!destroy) {
767             freeList.add(res);
768             PoolItemStats pis = (PoolItemStats) infoList.get(res);
769             if (pis != null) {
770                 pis.setTotalConnectionTime(System.currentTimeMillis() - pis.getStartTime());
771             }
772         } else {
773             infoList.remove(res);
774             res.destroy();
775         }
776         // Notify 1 thread waiting for a Connection.
777
if (currentWaiters > 0) {
778             notify();
779         }
780         if (adjustment) {
781             adjust();
782         }
783     }
784
785     /**
786      * @see org.objectweb.jonas.resource.pool.api.Pool#getMatchFactory
787      */

788     public PoolMatchFactory getMatchFactory() {
789         return matchFactory;
790     }
791
792     /**
793      * @see org.objectweb.jonas.resource.pool.api.Pool#setMatchFactory
794      */

795     public synchronized void setMatchFactory(PoolMatchFactory pmf) {
796         matchFactory = pmf;
797     }
798
799     /**
800      * @see org.objectweb.jonas.resource.pool.api.Pool#startMonitor
801      */

802     public void startMonitor() {
803         poolMonitor = new HArrayPoolMonitor(this);
804         poolMonitor.start();
805     }
806
807     /**
808      * @see org.objectweb.jonas.resource.pool.api.Pool#validateMCs
809      */

810     public synchronized void validateMCs() throws Exception JavaDoc {
811         matchFactory.validateResource(freeList);
812     }
813
814     /**
815      * Adjust the pool size, according to poolMax and minSize values.
816      * Also remove old connections in the freeList.
817      * @throws Exception if an exception occurs
818      */

819     public synchronized void adjust() throws Exception JavaDoc {
820         // Remove max aged elements in freelist
821
// - Not more than MAX_REMOVE_FREELIST
822
// - Don't reduce pool size less than minSize
823
//logger.log(BasicLevel.DEBUG, "");
824
int count = activeList.size() - minSize;
825         long curTime = System.currentTimeMillis();
826         // If count is null, a new connection will be recreated just after.
827
if (count >= 0) {
828             if (count > MAX_REMOVE_FREELIST) {
829                 count = MAX_REMOVE_FREELIST;
830             }
831             Vector JavaDoc rList = new Vector JavaDoc();
832             Iterator JavaDoc it = null;
833             for (it = freeList.iterator(); it.hasNext();) {
834                 ManagedConnection JavaDoc res = (ManagedConnection JavaDoc) it.next();
835                 PoolItemStats pis = (PoolItemStats) infoList.get(res);
836                 if (maxAge > 0 && pis != null && pis.getMaxAgeTimeout() > 0
837                         && curTime > pis.getMaxAgeTimeout()) {
838                     rList.add(res);
839                 }
840             }
841             // Bug: 300351 Use the list built above to remove the MCs
842
it = rList.iterator();
843             while (it.hasNext()) {
844                 ManagedConnection JavaDoc res = (ManagedConnection JavaDoc) it.next();
845                 try {
846                     matchFactory.releaseResource(res);
847                 } catch (Exception JavaDoc ex) {
848                     ex.printStackTrace();
849                 }
850                 freeList.remove(res);
851                 try {
852                     res.destroy();
853                 } catch (Exception JavaDoc ex) {
854                     ex.printStackTrace();
855                 }
856             }
857         }
858
859         // Close (physically) connections lost (opened for too long time)
860
curTime = System.currentTimeMillis();
861         Vector JavaDoc aList = new Vector JavaDoc();
862         Iterator JavaDoc it = null;
863         for (it = activeList.iterator(); it.hasNext();) {
864             ManagedConnection JavaDoc res = (ManagedConnection JavaDoc) it.next();
865             PoolItemStats pis = (PoolItemStats) infoList.get(res);
866             if (maxOpentime > 0 && pis != null && pis.getMaxOpenTimeout() > 0
867                     && curTime > pis.getMaxOpenTimeout()) {
868                 aList.add(res);
869             }
870         }
871         it = aList.iterator();
872         while (it.hasNext()) {
873             ManagedConnection JavaDoc item = (ManagedConnection JavaDoc) it.next();
874             logger.log(BasicLevel.WARN, "close a timed out active connection");
875             logger.log(BasicLevel.WARN, "MC = " + item);
876             releaseResource(item, true, false);
877             connectionLeaks++;
878         }
879
880
881         int curSize = activeList.size() + freeList.size();
882         if (maxSize > 0 && maxSize < curSize) {
883             // Removes as many free entries as possible
884
int nbRemove = curSize - maxSize;
885             if (freeList != null) {
886                 while (!freeList.isEmpty() && nbRemove > 0) {
887                     ManagedConnection JavaDoc res = (ManagedConnection JavaDoc) freeList.iterator().next();
888                     matchFactory.releaseResource(res);
889                     res.destroy();
890                     freeList.remove(res);
891                     infoList.remove(res);
892                     nbRemove--;
893                     curSize--;
894                 }
895             }
896         }
897
898         // Recreate more Connections while minSize is not reached
899
ManagedConnection JavaDoc res;
900         while (minSize > curSize) {
901             res = createResource(null);
902             freeList.add(res);
903             infoList.put(res, new PoolItemStats());
904             curSize++;
905         }
906
907         recomputeBusy();
908     }
909
910     /**
911      * compute current min/max busyConnections
912      */

913     public void recomputeBusy() {
914         int busy = getCurrentBusy();
915         if (busyMax < busy) {
916             busyMax = busy;
917         }
918         if (busyMin > busy) {
919             busyMin = busy;
920         }
921     }
922
923     /**
924      * @see org.objectweb.jonas.resource.pool.api.Pool#sampling
925      */

926     public void sampling() throws Exception JavaDoc {
927         //matchFactory.sampling();
928
waitingHighRecent = waitingTime;
929         if (waitingHigh < waitingTime) {
930             waitingHigh = waitingTime;
931         }
932         waitingTime = 0;
933
934         waitersHighRecent = waiterCount;
935         if (waitersHigh < waiterCount) {
936             waitersHigh = waiterCount;
937         }
938         waiterCount = 0;
939
940         busyMaxRecent = busyMax;
941         busyMax = getCurrentBusy();
942         busyMinRecent = busyMin;
943         busyMin = getCurrentBusy();
944     }
945
946     /**
947      * Set the item statistics
948      * @param res Object of the resource
949      */

950     private void setItemStats(Object JavaDoc res) {
951         PoolItemStats pis = (PoolItemStats) infoList.get(res);
952         if (pis != null) {
953             pis.incrementUses();
954             long sTime = System.currentTimeMillis();
955             pis.setStartTime(sTime);
956             if (maxAge > 0 && pis.getMaxAgeTimeout() == 0) {
957                 pis.setMaxAgeTimeout(sTime + (maxAge * 60L * 1000));
958             }
959             if (maxOpentime > 0) {
960                 pis.setMaxOpenTimeout(sTime + (maxOpentime * 60L * 1000));
961             }
962         }
963         servedOpen++;
964     }
965
966     /**
967      * Print information about the pool
968      *
969      */

970     void printLists() {
971         int count = 0;
972         if (logger.isLoggable(BasicLevel.DEBUG)) {
973             logger.log(BasicLevel.DEBUG, "minSize=" + minSize + ", maxSize=" + maxSize
974                                          + ", freeSize=" + freeList.size());
975             logger.log(BasicLevel.DEBUG, "activeList:");
976             if (activeList == null) {
977                 logger.log(BasicLevel.DEBUG, " null");
978             } else {
979                 Iterator JavaDoc it = activeList.iterator();
980                 while (it.hasNext() && ++count < 40) {
981                     logger.log(BasicLevel.DEBUG, " " + (ManagedConnection JavaDoc) it.next());
982                 }
983             }
984             logger.log(BasicLevel.DEBUG, "freeList:");
985             if (freeList == null) {
986                 logger.log(BasicLevel.DEBUG, " null");
987             } else {
988                 count = 0;
989                 Iterator JavaDoc it = freeList.iterator();
990                 while (it.hasNext() && ++count < 40) {
991                     logger.log(BasicLevel.DEBUG, " " + (ManagedConnection JavaDoc) it.next());
992                 }
993             }
994         }
995     }
996
997 }
Popular Tags