001: /*
002: * This software is released under a licence similar to the Apache Software Licence.
003: * See org.logicalcobwebs.proxool.package.html for details.
004: * The latest version is available at http://proxool.sourceforge.net
005: */
006: package org.logicalcobwebs.proxool;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.logicalcobwebs.proxool.util.FastArrayList;
011:
012: import java.util.HashMap;
013: import java.util.List;
014: import java.util.Map;
015: import java.util.Iterator;
016:
017: /**
018: * Schedules when to run the house keeper
019: * @version $Revision: 1.6 $, $Date: 2006/01/18 14:40:01 $
020: * @author bill
021: * @author $Author: billhorsman $ (current maintainer)
022: * @since Proxool 0.8
023: */
024: public class HouseKeeperController {
025:
026: private static final Log LOG = LogFactory
027: .getLog(HouseKeeperController.class);
028:
029: private static Map houseKeepers = new HashMap();
030:
031: private static List houseKeeperList = new FastArrayList();
032:
033: private static int houseKeeperIndex = 0;
034:
035: private static List houseKeeperThreads = new FastArrayList();
036:
037: private static final Object LOCK = new Integer(1);
038:
039: private static HouseKeeper getHouseKeeper(String alias)
040: throws ProxoolException {
041: final HouseKeeper houseKeeper = (HouseKeeper) houseKeepers
042: .get(alias);
043: if (houseKeeper == null) {
044: throw new ProxoolException(
045: "Tried to use an unregistered house keeper '"
046: + alias + "'");
047: }
048: return houseKeeper;
049: }
050:
051: /**
052: * Get the next house keeper that needs to be run
053: * @return the house keeper to run, or null if there is nothing to do.
054: */
055: protected static HouseKeeper getHouseKeeperToRun() {
056: HouseKeeper houseKeeper = null;
057: synchronized (LOCK) {
058: for (int i = 0; i < houseKeeperList.size(); i++) {
059: HouseKeeper hk = null;
060: try {
061: hk = (HouseKeeper) houseKeeperList
062: .get(houseKeeperIndex);
063: if (hk.isSweepDue()) {
064: houseKeeper = hk;
065: break;
066: }
067: houseKeeperIndex++;
068: } catch (IndexOutOfBoundsException e) {
069: houseKeeperIndex = 0;
070: }
071: }
072: }
073: return houseKeeper;
074: }
075:
076: protected static void sweepNow(String alias) {
077: try {
078: getHouseKeeper(alias).sweep();
079: } catch (ProxoolException e) {
080: LOG.error("Couldn't run house keeper for " + alias, e);
081: }
082: }
083:
084: /**
085: * Schedule a regular triggerSweep
086: * @param connectionPool identifies the pool
087: */
088: protected static void register(ConnectionPool connectionPool) {
089: String alias = connectionPool.getDefinition().getAlias();
090: LOG.debug("Registering '" + alias + "' house keeper");
091: HouseKeeper houseKeeper = new HouseKeeper(connectionPool);
092: synchronized (LOCK) {
093: houseKeepers.put(alias, houseKeeper);
094: houseKeeperList.add(houseKeeper);
095:
096: if (houseKeeperThreads.size() == 0) {
097: HouseKeeperThread hkt = new HouseKeeperThread(
098: "HouseKeeper");
099: LOG.debug("Starting a house keeper thread");
100: hkt.start();
101: houseKeeperThreads.add(hkt);
102: }
103: }
104: }
105:
106: /**
107: * Stop all house keeper threads.
108: */
109: protected static void shutdown() {
110: synchronized (LOCK) {
111: Iterator i = houseKeeperThreads.iterator();
112: while (i.hasNext()) {
113: HouseKeeperThread hkt = (HouseKeeperThread) i.next();
114: LOG.info("Stopping " + hkt.getName() + " thread");
115: hkt.cancel();
116: }
117: houseKeeperThreads.clear();
118: }
119: }
120:
121: /**
122: * cancel a house keeper for a pool. This doens't stop the house keeper
123: * thread.
124: * @param alias identifies the pool
125: * @throws ProxoolException if we couldn't find the house keeper (if it had
126: * already been cancelled for instance).
127: */
128: protected static void cancel(String alias) throws ProxoolException {
129: HouseKeeper hk = getHouseKeeper(alias);
130: houseKeepers.remove(alias);
131: houseKeeperList.remove(hk);
132: }
133:
134: }
135:
136: /*
137: Revision history:
138: $Log: HouseKeeperController.java,v $
139: Revision 1.6 2006/01/18 14:40:01 billhorsman
140: Unbundled Jakarta's Commons Logging.
141:
142: Revision 1.5 2004/06/02 20:38:32 billhorsman
143: More robust round robin of house keepers.
144:
145: Revision 1.4 2004/03/26 15:58:56 billhorsman
146: Fixes to ensure that house keeper and prototyper threads finish after shutdown.
147:
148: Revision 1.3 2003/03/10 23:43:10 billhorsman
149: reapplied checkstyle that i'd inadvertently let
150: IntelliJ change...
151:
152: Revision 1.2 2003/03/10 15:26:46 billhorsman
153: refactoringn of concurrency stuff (and some import
154: optimisation)
155:
156: Revision 1.1 2003/03/05 18:42:33 billhorsman
157: big refactor of prototyping and house keeping to
158: drastically reduce the number of threads when using
159: many pools
160:
161: */
|