1 6 package org.logicalcobwebs.proxool; 7 8 import java.sql.Connection ; 9 import java.sql.SQLException ; 10 import java.util.Collection ; 11 import java.util.Date ; 12 import java.util.HashSet ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 import java.util.Set ; 16 import java.util.TreeSet ; 17 18 import org.logicalcobwebs.concurrent.ReaderPreferenceReadWriteLock; 19 import org.logicalcobwebs.concurrent.WriterPreferenceReadWriteLock; 20 import org.apache.commons.logging.Log; 21 import org.apache.commons.logging.LogFactory; 22 import org.logicalcobwebs.proxool.admin.Admin; 23 import org.logicalcobwebs.proxool.util.FastArrayList; 24 25 32 class ConnectionPool implements ConnectionPoolStatisticsIF { 33 34 37 private static final Log LOG = LogFactory.getLog(ConnectionPool.class); 38 39 44 private Log log; 45 46 private ReaderPreferenceReadWriteLock connectionStatusReadWriteLock = new ReaderPreferenceReadWriteLock(); 47 48 54 private WriterPreferenceReadWriteLock primaryReadWriteLock = new WriterPreferenceReadWriteLock(); 55 56 private static final String [] STATUS_DESCRIPTIONS = {"NULL", "AVAILABLE", "ACTIVE", "OFFLINE"}; 57 58 private static final String MSG_MAX_CONNECTION_COUNT = 59 "Couldn't get connection because we are at maximum connection count and there are none available"; 60 61 62 private List proxyConnections; 63 64 65 private int nextAvailableConnection = 0; 66 67 private long connectionsServedCount = 0; 68 69 private long connectionsRefusedCount = 0; 70 71 72 private int[] connectionCountByState = new int[4]; 73 74 private ConnectionPoolDefinition definition; 75 76 private CompositeConnectionListener compositeConnectionListener = new CompositeConnectionListener(); 77 78 private CompositeStateListener compositeStateListener = new CompositeStateListener(); 79 80 private long timeOfLastRefusal = 0; 81 82 private int upState; 83 84 private static boolean loggedLegend; 85 86 private Admin admin; 87 88 private boolean locked = false; 89 90 private Date dateStarted = new Date (); 91 92 private boolean connectionPoolUp = false; 93 94 98 private Thread shutdownThread; 99 100 private Prototyper prototyper; 101 102 105 private ConnectionResetter connectionResetter; 106 107 private ConnectionValidatorIF connectionValidator; 108 109 110 protected ConnectionPool(ConnectionPoolDefinition definition) throws ProxoolException { 111 112 FastArrayList fal = new FastArrayList(); 116 fal.setFast(true); 117 proxyConnections = fal; 118 119 log = LogFactory.getLog("org.logicalcobwebs.proxool." + definition.getAlias()); 120 connectionResetter = new ConnectionResetter(log, definition.getDriver()); 121 setDefinition(definition); 122 123 connectionValidator = new DefaultConnectionValidator(); 124 125 if (definition.getStatistics() != null) { 126 try { 127 admin = new Admin(definition); 128 } catch (ProxoolException e) { 129 log.error("Failed to initialise statistics", e); 130 } 131 } 132 133 ShutdownHook.init(); 134 } 135 136 137 protected void start() throws ProxoolException { 138 connectionPoolUp = true; 139 prototyper = new Prototyper(this); 140 HouseKeeperController.register(this); 141 } 142 143 147 protected Connection getConnection() throws SQLException { 148 149 String requester = Thread.currentThread().getName(); 150 151 156 157 try { 158 prototyper.quickRefuse(); 159 } catch (SQLException e) { 160 connectionsRefusedCount++; 161 if (admin != null) { 162 admin.connectionRefused(); 163 } 164 log.info(displayStatistics() + " - " + MSG_MAX_CONNECTION_COUNT); 165 timeOfLastRefusal = System.currentTimeMillis(); 166 setUpState(StateListenerIF.STATE_OVERLOADED); 167 throw e; 168 } 169 170 prototyper.checkSimultaneousBuildThrottle(); 171 172 ProxyConnection proxyConnection = null; 173 174 try { 175 176 for (int connectionsTried = 0; connectionsTried < proxyConnections.size(); connectionsTried++) { 178 try { 181 proxyConnection = (ProxyConnection) proxyConnections.get(nextAvailableConnection); 182 } catch (ArrayIndexOutOfBoundsException e) { 183 nextAvailableConnection = 0; 186 proxyConnection = (ProxyConnection) proxyConnections.get(nextAvailableConnection); 187 } catch (IndexOutOfBoundsException e) { 188 nextAvailableConnection = 0; 190 proxyConnection = (ProxyConnection) proxyConnections.get(nextAvailableConnection); 191 } 192 if (proxyConnection != null && proxyConnection.setStatus(ProxyConnectionIF.STATUS_AVAILABLE, ProxyConnectionIF.STATUS_ACTIVE)) { 196 197 if (getDefinition().isTestBeforeUse()) { 199 if (!testConnection(proxyConnection)) { 200 proxyConnection = null; 202 } 203 } 204 if (proxyConnection != null) { 205 nextAvailableConnection++; 206 break; 207 } 208 } else { 209 proxyConnection = null; 210 } 211 nextAvailableConnection++; 212 } 213 if (proxyConnection == null) { 215 try { 216 proxyConnection = prototyper.buildConnection(ProxyConnection.STATUS_ACTIVE, "on demand"); 218 219 if (getDefinition().isTestBeforeUse()) { 221 if (!testConnection(proxyConnection)) { 222 throw new SQLException ("Created a new connection but it failed its test"); 224 } 225 } 226 } catch (SQLException e) { 227 throw e; 228 } catch (ProxoolException e) { 229 log.debug("Couldn't get connection", e); 230 throw new SQLException (e.toString()); 231 } catch (Throwable e) { 232 log.error("Couldn't get connection", e); 233 throw new SQLException (e.toString()); 234 } 235 } 236 237 } catch (SQLException e) { 238 throw e; 239 } catch (Throwable t) { 240 log.error("Problem getting connection", t); 241 throw new SQLException (t.toString()); 242 } finally { 243 if (proxyConnection != null) { 244 connectionsServedCount++; 245 proxyConnection.setRequester(requester); 246 } else { 247 connectionsRefusedCount++; 248 if (admin != null) { 249 admin.connectionRefused(); 250 } 251 timeOfLastRefusal = System.currentTimeMillis(); 252 setUpState(StateListenerIF.STATE_OVERLOADED); 253 } 254 } 255 256 if (proxyConnection == null) { 257 throw new SQLException ("Unknown reason for not getting connection. Sorry."); 258 } 259 260 if (log.isDebugEnabled() && getDefinition().isVerbose()) { 261 log.debug(displayStatistics() + " - Connection #" + proxyConnection.getId() + " served"); 262 } 263 264 proxyConnection.open(); 266 267 return ProxyFactory.getWrappedConnection(proxyConnection); 268 } 269 270 278 private boolean testConnection(ProxyConnectionIF proxyConnection) { 279 if( connectionValidator == null ) { 281 return true; 282 } 283 284 boolean success = connectionValidator.validate(getDefinition(), proxyConnection.getConnection()); 286 287 if( success ) { 288 if (LOG.isDebugEnabled()) { 289 LOG.debug(displayStatistics() + " - Connection #" + proxyConnection.getId() + " tested: OK"); 290 } 291 } 292 else { 293 proxyConnection.setStatus(ProxyConnectionIF.STATUS_NULL); 294 removeProxyConnection(proxyConnection, "it didn't pass the validation", ConnectionPool.REQUEST_EXPIRY, true); 295 } 296 297 return success; 299 } 300 301 307 protected boolean addProxyConnection(ProxyConnectionIF proxyConnection) { 308 boolean added = false; 309 try { 310 acquireConnectionStatusWriteLock(); 311 if (proxyConnection.getDefinition() == getDefinition()) { 312 proxyConnections.add(proxyConnection); 313 connectionCountByState[proxyConnection.getStatus()]++; 314 added = true; 315 } 316 } finally { 317 releaseConnectionStatusWriteLock(); 318 } 319 return added; 320 } 321 322 protected static String getStatusDescription(int status) { 323 try { 324 return STATUS_DESCRIPTIONS[status]; 325 } catch (ArrayIndexOutOfBoundsException e) { 326 return "Unknown status: " + status; 327 } 328 } 329 330 334 protected void putConnection(ProxyConnectionIF proxyConnection) { 335 336 if (admin != null) { 337 long now = System.currentTimeMillis(); 338 long start = proxyConnection.getTimeLastStartActive(); 339 if (now - start < 0) { 340 log.warn("Future start time detected. #" + proxyConnection.getId() + " start = " + new Date (start) 341 + " (" + (now - start) + " milliseconds)"); 342 } else if (now - start > 1000000) { 343 log.warn("Suspiciously long active time. #" + proxyConnection.getId() + " start = " + new Date (start)); 344 } 345 admin.connectionReturned(now - start); 346 } 347 348 if (proxyConnection.isMarkedForExpiry()) { 350 if (proxyConnection.setStatus(ProxyConnectionIF.STATUS_ACTIVE, ProxyConnectionIF.STATUS_NULL)) { 351 expireProxyConnection(proxyConnection, proxyConnection.getReasonForMark(), REQUEST_EXPIRY); 352 } 353 } else { 354 355 if (getDefinition().isTestAfterUse()) { 357 testConnection(proxyConnection); 359 } 360 361 if (!proxyConnection.setStatus(ProxyConnectionIF.STATUS_ACTIVE, ProxyConnectionIF.STATUS_AVAILABLE)) { 363 if (proxyConnection.getStatus() == ProxyConnectionIF.STATUS_AVAILABLE) { 364 log.warn("Unable to close connection " + proxyConnection.getId() 368 + " - I suspect that it has been closed already. Closing it more" 369 + " than once is unwise and should be avoided."); 370 } else { 371 log.warn("Unable to set status of connection " + proxyConnection.getId() 372 + " from " + getStatusDescription(ProxyConnectionIF.STATUS_ACTIVE) 373 + " to " + getStatusDescription(ProxyConnectionIF.STATUS_AVAILABLE) 374 + " because it's state was " + getStatusDescription(proxyConnection.getStatus())); 375 } 376 } 377 } 378 379 if (log.isDebugEnabled() && getDefinition().isVerbose()) { 380 log.debug(displayStatistics() + " - Connection #" + proxyConnection.getId() + " returned (now " 381 + getStatusDescription(proxyConnection.getStatus()) + ")"); 382 } 383 384 } 385 386 387 protected void throwConnection(ProxyConnectionIF proxyConnection, String reason) { 388 expireConnectionAsSoonAsPossible(proxyConnection, reason, true); 389 } 390 391 392 private ProxyConnectionIF getProxyConnection(int i) { 393 return (ProxyConnectionIF) proxyConnections.get(i); 394 } 395 396 400 protected ProxyConnectionIF[] getProxyConnections() { 401 return (ProxyConnectionIF[]) proxyConnections.toArray(new ProxyConnectionIF[proxyConnections.size()]); 402 } 403 404 413 protected void removeProxyConnection(ProxyConnectionIF proxyConnection, String reason, boolean forceExpiry, boolean triggerSweep) { 414 if (forceExpiry || proxyConnection.isNull()) { 416 417 proxyConnection.setStatus(ProxyConnectionIF.STATUS_NULL); 418 419 420 421 try { 422 onDeath(proxyConnection.getConnection()); 423 } catch (SQLException e) { 424 log.error("Problem during onDeath (ignored)", e); 425 } 426 427 try { 429 proxyConnection.reallyClose(); 430 } catch (SQLException e) { 431 log.error(e); 432 } 433 434 try { 435 if (isConnectionPoolUp()) { 437 acquireConnectionStatusWriteLock(); 438 } 439 proxyConnections.remove(proxyConnection); 440 } finally { 441 if (isConnectionPoolUp()) { 442 releaseConnectionStatusWriteLock(); 443 } 444 } 445 446 if (log.isDebugEnabled()) { 447 log.debug(displayStatistics() + " - #" + FormatHelper.formatMediumNumber(proxyConnection.getId()) 448 + " removed because " + reason + "."); 449 } 450 451 if (triggerSweep) { 452 PrototyperController.triggerSweep(getDefinition().getAlias()); 453 } 454 455 } else { 456 log.error(displayStatistics() + " - #" + FormatHelper.formatMediumNumber(proxyConnection.getId()) 457 + " was not removed because isNull() was false."); 458 } 459 } 460 461 protected void expireProxyConnection(ProxyConnectionIF proxyConnection, String reason, boolean forceExpiry) { 462 removeProxyConnection(proxyConnection, reason, forceExpiry, true); 463 } 464 465 469 protected void shutdown(int delay, String finalizerName) throws Throwable { 470 471 final String alias = getDefinition().getAlias(); 472 try { 473 475 476 acquirePrimaryWriteLock(); 477 478 if (connectionPoolUp) { 479 480 connectionPoolUp = false; 481 long startFinalize = System.currentTimeMillis(); 482 shutdownThread = Thread.currentThread(); 483 484 if (delay > 0) { 485 log.info("Shutting down '" + alias + "' pool started at " 486 + dateStarted + " - waiting for " + delay 487 + " milliseconds for everything to stop. [ " 488 + finalizerName + "]"); 489 } else { 490 log.info("Shutting down '" + alias + "' pool immediately [" + finalizerName + "]"); 491 } 492 493 494 495 boolean connectionClosedManually = false; 496 try { 497 498 try { 499 HouseKeeperController.cancel(alias); 500 } catch (ProxoolException e) { 501 log.error("Shutdown couldn't cancel house keeper", e); 502 } 503 504 if (admin != null) { 506 admin.cancelAll(); 507 } 508 509 510 511 if (connectionCountByState[ProxyConnectionIF.STATUS_ACTIVE] != 0) { 512 long endWait = startFinalize + delay; 513 LOG.info("Waiting until " + new Date (endWait) + " for all connections to become inactive (active count is " 514 + connectionCountByState[ProxyConnectionIF.STATUS_ACTIVE] + ")."); 515 while (true) { 516 long timeout = endWait - System.currentTimeMillis(); 517 if (timeout > 0) { 518 synchronized (Thread.currentThread()) { 519 try { 520 Thread.currentThread().wait(timeout); 521 } catch (InterruptedException e) { 522 log.debug("Interrupted whilst sleeping."); 523 } 524 } 525 } 526 int activeCount = connectionCountByState[ProxyConnectionIF.STATUS_ACTIVE]; 527 if (activeCount == 0) { 528 break; 529 } 530 if (System.currentTimeMillis() < endWait) { 531 LOG.info("Still waiting for active count to reach zero (currently " + activeCount + ")."); 532 } else { 533 LOG.warn("Shutdown waited for " 535 + (System.currentTimeMillis() - startFinalize) + " milliseconds for all " 536 + "the connections to become inactive but the active count is still " 537 + activeCount + ". Shutting down anyway."); 538 break; 539 } 540 Thread.sleep(100); 541 } 542 } 543 544 prototyper.cancel(); 545 546 for (int i = proxyConnections.size() - 1; i >= 0; i--) { 548 long id = getProxyConnection(i).getId(); 549 try { 550 connectionClosedManually = true; 551 removeProxyConnection(getProxyConnection(i), "of shutdown", true, false); 552 if (log.isDebugEnabled()) { 553 log.debug("Connection #" + id + " closed"); 554 } 555 } catch (Throwable t) { 556 if (log.isDebugEnabled()) { 557 log.debug("Problem closing connection #" + id, t); 558 } 559 560 } 561 } 562 563 } catch (Throwable t) { 564 log.error("Unknown problem finalizing pool", t); 565 } finally { 566 567 ConnectionPoolManager.getInstance().removeConnectionPool(alias); 568 569 if (log.isDebugEnabled()) { 570 log.info("'" + alias + "' pool has been closed down by " + finalizerName 571 + " in " + (System.currentTimeMillis() - startFinalize) + " milliseconds."); 572 if (!connectionClosedManually) { 573 log.debug("No connections required manual removal."); 574 } 575 } 576 super.finalize(); 577 } 578 } else { 579 if (log.isDebugEnabled()) { 580 log.debug("Ignoring duplicate attempt to shutdown '" + alias + "' pool by " + finalizerName); 581 } 582 } 583 } catch (Throwable t) { 584 log.error(finalizerName + " couldn't shutdown pool", t); 585 } finally { 586 releasePrimaryWriteLock(); 587 } 588 } 589 590 596 public int getAvailableConnectionCount() { 597 return connectionCountByState[ConnectionInfoIF.STATUS_AVAILABLE]; 598 } 599 600 606 public int getActiveConnectionCount() { 607 return connectionCountByState[ConnectionInfoIF.STATUS_ACTIVE]; 608 } 609 610 616 public int getOfflineConnectionCount() { 617 return connectionCountByState[ConnectionInfoIF.STATUS_OFFLINE]; 618 } 619 620 protected String displayStatistics() { 621 622 if (!loggedLegend) { 623 log.info("Proxool statistics legend: \"s - r (a/t/o)\" > s=served, r=refused (only shown if non-zero), a=active, t=total, o=offline (being tested)"); 624 loggedLegend = true; 625 } 626 627 StringBuffer statistics = new StringBuffer (); 628 statistics.append(FormatHelper.formatBigNumber(getConnectionsServedCount())); 629 630 if (getConnectionsRefusedCount() > 0) { 631 statistics.append(" -"); 632 statistics.append(FormatHelper.formatBigNumber(getConnectionsRefusedCount())); 633 } 634 635 statistics.append(" ("); 636 statistics.append(FormatHelper.formatSmallNumber(getActiveConnectionCount())); 637 statistics.append("/"); 638 statistics.append(FormatHelper.formatSmallNumber(getAvailableConnectionCount() + getActiveConnectionCount())); 639 statistics.append("/"); 640 statistics.append(FormatHelper.formatSmallNumber(getOfflineConnectionCount())); 641 statistics.append(")"); 642 643 652 653 return statistics.toString(); 654 } 655 656 protected void expireAllConnections(String reason, boolean merciful) { 657 658 Set pcs = new HashSet (); 662 for (int i = proxyConnections.size() - 1; i >= 0; i--) { 663 pcs.add(proxyConnections.get(i)); 664 } 665 666 Iterator i = pcs.iterator(); 667 while (i.hasNext()) { 668 ProxyConnectionIF pc = (ProxyConnectionIF) i.next(); 669 expireConnectionAsSoonAsPossible(pc, reason, merciful); 670 } 671 } 672 673 protected void expireConnectionAsSoonAsPossible(ProxyConnectionIF proxyConnection, String reason, boolean merciful) { 674 if (proxyConnection.setStatus(ProxyConnectionIF.STATUS_AVAILABLE, ProxyConnectionIF.STATUS_OFFLINE)) { 675 if (proxyConnection.setStatus(ProxyConnectionIF.STATUS_OFFLINE, ProxyConnectionIF.STATUS_NULL)) { 676 expireProxyConnection(proxyConnection, reason, REQUEST_EXPIRY); 678 } 679 } else { 680 682 if (merciful) { 683 proxyConnection.markForExpiry(reason); 687 if (log.isDebugEnabled()) { 688 log.debug(displayStatistics() + " - #" + FormatHelper.formatMediumNumber(proxyConnection.getId()) + " marked for expiry."); 689 } 690 } else { 691 693 expireProxyConnection(proxyConnection, reason, FORCE_EXPIRY); 695 } 696 697 } } 699 700 protected void registerRemovedConnection(int status) { 701 prototyper.connectionRemoved(); 702 connectionCountByState[status]--; 703 } 704 705 711 protected void changeStatus(int oldStatus, int newStatus) { 712 connectionCountByState[oldStatus]--; 714 connectionCountByState[newStatus]++; 715 if (shutdownThread != null && connectionCountByState[ProxyConnectionIF.STATUS_ACTIVE] == 0) { 719 synchronized (shutdownThread) { 720 shutdownThread.notify(); 721 } 722 } 723 724 } 725 726 public long getConnectionsServedCount() { 727 return connectionsServedCount; 728 } 729 730 public long getConnectionsRefusedCount() { 731 return connectionsRefusedCount; 732 } 733 734 protected ConnectionPoolDefinition getDefinition() { 735 return definition; 736 } 737 738 742 protected synchronized void setDefinition(ConnectionPoolDefinition definition) throws ProxoolException { 743 this.definition = definition; 744 745 try { 746 Class.forName(definition.getDriver()); 747 } catch (ClassNotFoundException e) { 748 log.error("Couldn't load class " + definition.getDriver(), e); 749 throw new ProxoolException("Couldn't load class " + definition.getDriver()); 750 } catch (NullPointerException e) { 751 log.error("Definition did not contain driver", e); 752 throw new ProxoolException("Definition did not contain driver"); 753 } 754 755 } 756 757 760 public void setStateListener(StateListenerIF stateListener) { 761 addStateListener(stateListener); 762 } 763 764 public void addStateListener(StateListenerIF stateListener) { 765 this.compositeStateListener.addListener(stateListener); 766 } 767 768 public boolean removeStateListener(StateListenerIF stateListener) { 769 return this.compositeStateListener.removeListener(stateListener); 770 } 771 772 775 public void setConnectionListener(ConnectionListenerIF connectionListener) { 776 addConnectionListener(connectionListener); 777 } 778 779 public void addConnectionListener(ConnectionListenerIF connectionListener) { 780 this.compositeConnectionListener.addListener(connectionListener); 781 } 782 783 public boolean removeConnectionListener(ConnectionListenerIF connectionListener) { 784 return this.compositeConnectionListener.removeListener(connectionListener); 785 } 786 787 788 protected void onBirth(Connection connection) throws SQLException { 789 this.compositeConnectionListener.onBirth(connection); 790 } 791 792 793 protected void onDeath(Connection connection) throws SQLException { 794 this.compositeConnectionListener.onDeath(connection); 795 } 796 797 798 protected void onExecute(String command, long elapsedTime, Exception exception) throws SQLException { 799 if (exception == null) { 800 this.compositeConnectionListener.onExecute(command, elapsedTime); 801 } else { 802 this.compositeConnectionListener.onFail(command, exception); 803 } 804 } 805 806 810 protected boolean isConnectionListenedTo() { 811 return !compositeConnectionListener.isEmpty(); 812 } 813 814 public String toString() { 815 return getDefinition().toString(); 816 } 817 818 public int getUpState() { 819 return upState; 820 } 821 822 823 public void setUpState(int upState) { 824 if (this.upState != upState) { 825 compositeStateListener.upStateChanged(upState); 826 this.upState = upState; 827 } 828 } 829 830 protected Collection getConnectionInfos() { 831 Collection cis = null; 832 cis = new TreeSet (); 833 Iterator i = proxyConnections.iterator(); 834 while (i.hasNext()) { 835 ConnectionInfoIF connectionInfo = (ConnectionInfoIF) i.next(); 836 ConnectionInfo ci = new ConnectionInfo(); 837 ci.setAge(connectionInfo.getAge()); 838 ci.setBirthDate(connectionInfo.getBirthDate()); 839 ci.setId(connectionInfo.getId()); 840 ci.setMark(connectionInfo.getMark()); 841 ci.setRequester(connectionInfo.getRequester()); 842 ci.setStatus(connectionInfo.getStatus()); 843 ci.setTimeLastStartActive(connectionInfo.getTimeLastStartActive()); 844 ci.setTimeLastStopActive(connectionInfo.getTimeLastStopActive()); 845 ci.setDelegateUrl(connectionInfo.getDelegateUrl()); 846 ci.setProxyHashcode(connectionInfo.getProxyHashcode()); 847 ci.setDelegateHashcode(connectionInfo.getDelegateHashcode()); 848 String [] sqlCalls = connectionInfo.getSqlCalls(); 849 for (int j = 0; j < sqlCalls.length; j++) { 850 ci.addSqlCall(sqlCalls[j]); 851 } 852 cis.add(ci); 853 } 854 return cis; 855 } 856 857 863 public boolean expireConnection(long id, boolean forceExpiry) { 864 boolean success = false; 865 ProxyConnection proxyConnection = null; 866 867 for (int connectionsTried = 0; connectionsTried < proxyConnections.size(); connectionsTried++) { 869 try { 872 proxyConnection = (ProxyConnection) proxyConnections.get(nextAvailableConnection); 873 } catch (IndexOutOfBoundsException e) { 874 nextAvailableConnection = 0; 875 proxyConnection = (ProxyConnection) proxyConnections.get(nextAvailableConnection); 876 } 877 878 if (proxyConnection.getId() == id) { 879 proxyConnection.setStatus(ProxyConnectionIF.STATUS_AVAILABLE, ProxyConnectionIF.STATUS_OFFLINE); 881 proxyConnection.setStatus(ProxyConnectionIF.STATUS_OFFLINE, ProxyConnectionIF.STATUS_NULL); 882 removeProxyConnection(proxyConnection, "it was manually killed", forceExpiry, true); 883 success = true; 884 break; 885 } 886 887 nextAvailableConnection++; 888 } 889 890 if (!success) { 891 if (log.isDebugEnabled()) { 892 log.debug(displayStatistics() + " - couldn't find " + FormatHelper.formatMediumNumber(proxyConnection.getId()) 893 + " and I've just been asked to expire it"); 894 } 895 } 896 897 return success; 898 } 899 900 public Log getLog() { 901 return log; 902 } 903 904 908 protected void initialiseConnectionResetter(Connection connection) { 909 connectionResetter.initialise(connection); 910 } 911 912 917 protected boolean resetConnection(Connection connection, String id) { 918 return connectionResetter.reset(connection, id); 919 } 920 921 924 public Date getDateStarted() { 925 return dateStarted; 926 } 927 928 932 protected Admin getAdmin() { 933 return admin; 934 } 935 936 protected boolean isLocked() { 937 return locked; 938 } 939 940 protected void lock() { 941 locked = true; 942 } 943 944 protected void unlock() { 945 locked = false; 946 } 947 948 952 protected void acquirePrimaryReadLock() throws InterruptedException { 953 primaryReadWriteLock.readLock().acquire(); 962 } 971 972 975 protected void releasePrimaryReadLock() { 976 primaryReadWriteLock.readLock().release(); 983 } 984 985 991 protected void acquirePrimaryWriteLock() throws InterruptedException { 992 primaryReadWriteLock.writeLock().acquire(); 1003 } 1023 1024 1027 protected void releasePrimaryWriteLock() { 1028 primaryReadWriteLock.writeLock().release(); 1029 } 1036 1037 1042 protected boolean isConnectionPoolUp() { 1043 return connectionPoolUp; 1044 } 1045 1046 protected static final boolean FORCE_EXPIRY = true; 1047 1048 protected static final boolean REQUEST_EXPIRY = false; 1049 1050 1054 protected long getTimeOfLastRefusal() { 1055 return timeOfLastRefusal; 1056 } 1057 1058 protected void acquireConnectionStatusWriteLock() { 1059 try { 1060 connectionStatusReadWriteLock.writeLock().acquire(); 1066 } catch (InterruptedException e) { 1072 log.error("Couldn't acquire connectionStatus write lock", e); 1073 } 1074 } 1075 1076 protected void releaseConnectionStatusWriteLock() { 1077 connectionStatusReadWriteLock.writeLock().release(); 1078 } 1084 1085 protected void acquireConnectionStatusReadLock() { 1086 try { 1087 connectionStatusReadWriteLock.readLock().acquire(); 1088 } catch (InterruptedException e) { 1089 log.error("Couldn't acquire connectionStatus read lock", e); 1090 } 1091 } 1092 1093 protected boolean attemptConnectionStatusReadLock(long msecs) { 1094 try { 1095 return connectionStatusReadWriteLock.readLock().attempt(msecs); 1096 } catch (InterruptedException e) { 1097 log.error("Couldn't acquire connectionStatus read lock", e); 1098 return false; 1099 } 1100 } 1101 1102 protected void releaseConnectionStatusReadLock() { 1103 connectionStatusReadWriteLock.readLock().release(); 1104 } 1106 1107 protected Prototyper getPrototyper() { 1108 return prototyper; 1109 } 1110 1111 public long getConnectionCount() { 1112 return getPrototyper().getConnectionCount(); 1113 } 1114} 1115 1116 1419 | Popular Tags |