Source Code Cross Referenced for Prototyper.java in  » Database-JDBC-Connection-Pool » proxool » org » logicalcobwebs » proxool » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database JDBC Connection Pool » proxool » org.logicalcobwebs.proxool 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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 java.sql.Connection;
009:        import java.sql.SQLException;
010:
011:        import org.apache.commons.logging.Log;
012:        import org.apache.commons.logging.LogFactory;
013:
014:        /**
015:         * Responsible for prototyping connections for all pools
016:         * @version $Revision: 1.14 $, $Date: 2006/03/23 11:44:57 $
017:         * @author bill
018:         * @author $Author: billhorsman $ (current maintainer)
019:         * @since Proxool 0.8
020:         */
021:        public class Prototyper {
022:
023:            private ConnectionPool connectionPool;
024:
025:            private Log log = LogFactory.getLog(Prototyper.class);
026:
027:            private long connectionCount;
028:
029:            private final Object lock = new Integer(1);
030:
031:            private boolean sweepNeeded = true;
032:
033:            /** This allows us to have a unique ID for each connection */
034:            private long nextConnectionId = 1;
035:
036:            /**
037:             * Calling {@link #cancel} will set this to true and stop all
038:             * current prototyping immediately
039:             */
040:            private boolean cancel;
041:
042:            /**
043:             * The number of connections currently being made (actually in
044:             * progress)
045:             */
046:            private int connectionsBeingMade;
047:
048:            /**
049:             * The builder that will create *real* connections for us.
050:             * Currently initialized to the default implementation until we fully
051:             * support pluggable ConnectionBuilders
052:             */
053:            private ConnectionBuilderIF connectionBuilder = new DefaultConnectionBuilder();
054:
055:            public Prototyper(ConnectionPool connectionPool) {
056:                this .connectionPool = connectionPool;
057:                this .log = connectionPool.getLog();
058:            }
059:
060:            protected boolean isSweepNeeded() {
061:                return sweepNeeded;
062:            }
063:
064:            protected void triggerSweep() {
065:                sweepNeeded = true;
066:            }
067:
068:            /**
069:             * Trigger prototyping immediately
070:             * @return true if something was prototyped
071:             */
072:            protected boolean sweep() {
073:
074:                boolean somethingDone = false;
075:                try {
076:
077:                    while (!cancel && connectionPool.isConnectionPoolUp()) {
078:
079:                        //                if (log.isDebugEnabled()) {
080:                        //                    log.debug("Prototyping");
081:                        //                }
082:
083:                        String reason = null;
084:                        if (connectionCount >= getDefinition()
085:                                .getMaximumConnectionCount()) {
086:                            // We don't want to make any more that the maximum
087:                            break;
088:                        } else if (connectionCount < getDefinition()
089:                                .getMinimumConnectionCount()) {
090:                            reason = "to achieve minimum of "
091:                                    + getDefinition()
092:                                            .getMinimumConnectionCount();
093:                        } else if (connectionPool.getAvailableConnectionCount() < getDefinition()
094:                                .getPrototypeCount()) {
095:                            reason = "to keep "
096:                                    + getDefinition().getPrototypeCount()
097:                                    + " available";
098:                        } else {
099:                            // Nothing to do
100:                            break;
101:                        }
102:
103:                        ProxyConnectionIF freshlyBuiltProxyConnection = null;
104:                        try {
105:                            // If it has been shutdown then we should just stop now.
106:                            if (!connectionPool.isConnectionPoolUp()) {
107:                                break;
108:                            }
109:                            freshlyBuiltProxyConnection = buildConnection(
110:                                    ConnectionInfoIF.STATUS_AVAILABLE, reason);
111:                            somethingDone = true;
112:                        } catch (Throwable e) {
113:                            log.error("Prototype", e);
114:                            // If there's been an exception, perhaps we should stop
115:                            // prototyping for a while.  Otherwise if the database
116:                            // has problems we end up trying the connection every 2ms
117:                            // or so and then the log grows pretty fast.
118:                            break;
119:                            // Don't wory, we'll start again the next time the
120:                            // housekeeping thread runs.
121:                        }
122:                        if (freshlyBuiltProxyConnection == null) {
123:                            // That's strange. No double the buildConnection() method logged the
124:                            // error, but we should have build a connection here.
125:                        }
126:                    }
127:                } catch (Throwable t) {
128:                    log.error("Unexpected error", t);
129:                }
130:
131:                return somethingDone;
132:            }
133:
134:            /**
135:             * Build a new connection
136:             * @param status the initial status it will be created as (this allows us
137:             * to create it as {@link ConnectionInfoIF#STATUS_ACTIVE ACTIVE} and avoid
138:             * another thread grabbing it before we can)
139:             * @param creator for log audit
140:             * @return the new connection
141:             */
142:            protected ProxyConnection buildConnection(int status, String creator)
143:                    throws SQLException, ProxoolException {
144:
145:                long id = 0;
146:                synchronized (lock) {
147:
148:                    // Check that we are allowed to make another connection
149:                    if (connectionCount >= getDefinition()
150:                            .getMaximumConnectionCount()) {
151:                        throw new ProxoolException("ConnectionCount is "
152:                                + connectionCount
153:                                + ". Maximum connection count of "
154:                                + getDefinition().getMaximumConnectionCount()
155:                                + " cannot be exceeded.");
156:                    }
157:
158:                    checkSimultaneousBuildThrottle();
159:
160:                    connectionsBeingMade++;
161:                    connectionCount++;
162:                    id = nextConnectionId++;
163:                }
164:
165:                ProxyConnection proxyConnection = null;
166:                Connection realConnection = null;
167:
168:                try {
169:                    // get a new *real* connection
170:                    final ConnectionPoolDefinition definition = connectionPool
171:                            .getDefinition();
172:                    realConnection = connectionBuilder
173:                            .buildConnection(definition);
174:
175:                    // build a proxy around it
176:
177:                    //TODO BRE: the connection builder has made a new connection using the information
178:                    // supplied in the ConnectionPoolDefinition. That's where it got the URL...
179:                    // The ProxyConnection is passed the ConnectionPoolDefinition as well so it doesn't 
180:                    // need the url in its constructor...
181:                    String url = definition.getUrl();
182:                    proxyConnection = new ProxyConnection(realConnection, id,
183:                            url, connectionPool, definition, status);
184:
185:                    try {
186:                        connectionPool.onBirth(realConnection);
187:                    } catch (Exception e) {
188:                        log.error("Problem during onBirth (ignored)", e);
189:                    }
190:
191:                    //TODO BRE: the actual pool of connections is maintained by the ConnectionPool. I'm not 
192:                    // very happy with the idea of letting the Prototyper add the newly build connection 
193:                    // into the pool itself. It should rather be the pool that does it, after it got a new 
194:                    // connection from the Prototyper. This would clearly separate the responsibilities: 
195:                    // ConnectionPool maintains the pool and its integrity, the Prototyper creates new 
196:                    // connections when instructed. 
197:                    boolean added = connectionPool
198:                            .addProxyConnection(proxyConnection);
199:                    if (log.isDebugEnabled()) {
200:                        StringBuffer out = new StringBuffer(connectionPool
201:                                .displayStatistics());
202:                        out.append(" - Connection #");
203:                        out.append(proxyConnection.getId());
204:                        if (getDefinition().isVerbose()) {
205:                            out.append(" (");
206:                            out.append(Integer.toHexString(proxyConnection
207:                                    .hashCode()));
208:                            out.append(")");
209:                        }
210:                        out.append(" created ");
211:                        out.append(creator);
212:                        out.append(" = ");
213:                        out.append(ConnectionPool
214:                                .getStatusDescription(proxyConnection
215:                                        .getStatus()));
216:                        if (getDefinition().isVerbose()) {
217:                            out.append(" -> ");
218:                            out.append(getDefinition().getUrl());
219:                            out.append(" (");
220:                            out.append(Integer.toHexString(proxyConnection
221:                                    .getConnection().hashCode()));
222:                            out.append(") by thread ");
223:                            out.append(Thread.currentThread().getName());
224:                        }
225:                        log.debug(out);
226:                        if (!added) {
227:                            out = new StringBuffer(connectionPool
228:                                    .displayStatistics());
229:                            out.append(" - Connection #");
230:                            out.append(proxyConnection.getId());
231:                            out
232:                                    .append(" has been discarded immediately because the definition it was built with is out of date");
233:                            log.debug(out);
234:                        }
235:                    }
236:                    if (!added) {
237:                        proxyConnection.reallyClose();
238:                    }
239:
240:                } catch (SQLException e) {
241:                    // log.error(displayStatistics() + " - Couldn't initialise connection #" + proxyConnection.getId() + ": " + e);
242:                    throw e;
243:                } catch (RuntimeException e) {
244:                    if (log.isDebugEnabled()) {
245:                        log.debug("Prototyping problem", e);
246:                    }
247:                    throw e;
248:                } catch (Throwable t) {
249:                    if (log.isDebugEnabled()) {
250:                        log.debug("Prototyping problem", t);
251:                    }
252:                    throw new ProxoolException(
253:                            "Unexpected prototyping problem", t);
254:                } finally {
255:                    synchronized (lock) {
256:                        if (proxyConnection == null) {
257:                            // If there has been an exception then we won't be using this one and
258:                            // we need to decrement the counter
259:                            connectionCount--;
260:                        }
261:                        connectionsBeingMade--;
262:                    }
263:
264:                }
265:
266:                return proxyConnection;
267:            }
268:
269:            /**
270:             * This needs to be called _everytime_ a connection is removed.
271:             */
272:            protected void connectionRemoved() {
273:                connectionCount--;
274:            }
275:
276:            /**
277:             * Checks whether we are currently already building too many connections
278:             * @throws SQLException if the throttle has been reached
279:             */
280:            protected void checkSimultaneousBuildThrottle() throws SQLException {
281:                // Check we aren't making too many simultaneously
282:                if (connectionsBeingMade > getDefinition()
283:                        .getSimultaneousBuildThrottle()) {
284:                    throw new SQLException(
285:                            "We are already in the process of making "
286:                                    + connectionsBeingMade
287:                                    + " connections and the number of simultaneous builds has been throttled to "
288:                                    + getDefinition()
289:                                            .getSimultaneousBuildThrottle());
290:                }
291:            }
292:
293:            /**
294:             * The total number of  connections, including those being built right
295:             * now
296:             * @return connectionCount;
297:             */
298:            public long getConnectionCount() {
299:                return connectionCount;
300:            }
301:
302:            /**
303:             * Utility method
304:             * @return definition
305:             */
306:            private ConnectionPoolDefinitionIF getDefinition() {
307:                return connectionPool.getDefinition();
308:            }
309:
310:            /**
311:             * Cancel all current prototyping
312:             */
313:            public void cancel() {
314:                cancel = true;
315:            }
316:
317:            /**
318:             * The alias of the pool we are prototyping for
319:             * @return alias
320:             */
321:            public String getAlias() {
322:                return getDefinition().getAlias();
323:            }
324:
325:            /**
326:             * Give a quick answer to whether we should attempt to build a connection. This can be quicker
327:             * if we are massively overloaded rather than cycling through each connection in the pool to
328:             * see if it's free
329:             * @throws SQLException if it is a waste of time even trying to get a connaction. Just because this method
330:             * doesn't throw an exception it doesn't guarantee that one will be available. There is a slight
331:             * risk that we might tell the client to give up when a connection could become available in the next few
332:             * milliseconds but our policy is to refuse connections quickly when overloaded.
333:             */
334:            public void quickRefuse() throws SQLException {
335:                if (connectionCount >= getDefinition()
336:                        .getMaximumConnectionCount()
337:                        && connectionPool.getAvailableConnectionCount() < 1) {
338:                    throw new SQLException(
339:                            "Couldn't get connection because we are at maximum connection count ("
340:                                    + connectionCount
341:                                    + "/"
342:                                    + getDefinition()
343:                                            .getMaximumConnectionCount()
344:                                    + ") and there are none available");
345:                }
346:            }
347:        }
348:
349:        /*
350:         Revision history:
351:         $Log: Prototyper.java,v $
352:         Revision 1.14  2006/03/23 11:44:57  billhorsman
353:         More information when quickly refusing
354:
355:         Revision 1.13  2006/01/18 14:40:01  billhorsman
356:         Unbundled Jakarta's Commons Logging.
357:
358:         Revision 1.12  2006/01/16 23:10:41  billhorsman
359:         Doh. /Do/ decrement connectionCount if we didn't make one.
360:
361:         Revision 1.11  2005/10/02 12:36:30  billhorsman
362:         New quickRefuse() method checks whether we are overloaded without checking whole pool for an available connection.
363:
364:         Revision 1.10  2005/05/04 16:27:54  billhorsman
365:         Check to see whether a new connection was really added to the pool.
366:
367:         Revision 1.9  2004/03/25 22:02:15  brenuart
368:         First step towards pluggable ConnectionBuilderIF & ConnectionValidatorIF.
369:         Include some minor refactoring that lead to deprecation of some PrototyperController methods.
370:
371:         Revision 1.7  2003/09/30 18:39:08  billhorsman
372:         New test-before-use, test-after-use and fatal-sql-exception-wrapper-class properties.
373:
374:         Revision 1.6  2003/09/11 10:44:54  billhorsman
375:         Catch throwable not just exception during creation of connection
376:         (this will catch ClassNotFoundError too)
377:
378:         Revision 1.5  2003/04/10 08:22:33  billhorsman
379:         removed some very frequent debug
380:
381:         Revision 1.4  2003/03/11 14:51:52  billhorsman
382:         more concurrency fixes relating to snapshots
383:
384:         Revision 1.3  2003/03/10 23:43:10  billhorsman
385:         reapplied checkstyle that i'd inadvertently let
386:         IntelliJ change...
387:
388:         Revision 1.2  2003/03/10 15:26:47  billhorsman
389:         refactoringn of concurrency stuff (and some import
390:         optimisation)
391:
392:         Revision 1.1  2003/03/05 18:42:33  billhorsman
393:         big refactor of prototyping and house keeping to
394:         drastically reduce the number of threads when using
395:         many pools
396:
397:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.