1 23 package com.sun.enterprise.resource; 24 25 import java.util.*; 26 27 import javax.resource.ResourceException ; 28 import javax.resource.spi.ManagedConnection ; 29 import javax.transaction.*; 30 import java.util.logging.*; 31 import com.sun.logging.*; 32 33 import javax.naming.Context ; 34 import javax.naming.NamingException ; 35 import com.sun.enterprise.Switch; 36 import com.sun.enterprise.connectors.*; 37 import com.sun.enterprise.distributedtx.*; 38 import com.sun.enterprise.util.i18n.StringManager; 39 40 48 public abstract class AbstractResourcePool implements MonitorableResourcePool { 49 50 protected static StringManager localStrings = 51 StringManager.getManager(AbstractResourcePool.class); 52 53 protected ArrayList resources; 54 55 58 protected ArrayList free; 59 60 protected long idletime; 62 63 protected String name; 64 65 protected ResourceSpec resourceSpec; 67 protected ResourceAllocator allocator; 70 71 73 protected int maxPoolSize; 75 protected int steadyPoolSize; 77 protected int resizeQuantity; 79 protected int maxWaitTime; 82 protected boolean failAllConnections = false; 83 84 protected boolean matchConnections = false; 85 86 protected boolean poolInitialized = false; 87 88 protected Timer timer; 89 90 protected TimerTask resizerTask; 92 93 protected boolean monitoringEnabled; 95 protected PoolCounters poolCounters = null; 96 97 protected boolean validation = false; 98 102 103 protected LinkedList waitQueue = new LinkedList(); 104 105 protected boolean lazyConnectionAssoc_; 106 protected boolean lazyConnectionEnlist_; 107 protected boolean associateWithThread_; 108 protected boolean connectionLeakTracing_; 109 110 private boolean selfManaged_; 111 112 private boolean validateAtmostEveryIdleSecs = false; 115 116 117 private boolean inTx() { 118 com.sun.enterprise.ComponentInvocation inv = 119 Switch.getSwitch().getInvocationManager().getCurrentInvocation(); 120 if (inv == null) { 121 throw new com.sun.enterprise.InvocationException(); 122 } 123 Transaction tran = inv.getTransaction(); 124 return (tran != null); 125 } 126 127 public AbstractResourcePool(String poolName) throws PoolingException{ 128 this.name = poolName; 129 setPoolConfiguration(); 130 monitoringEnabled = false; 131 resources = new ArrayList(maxPoolSize); 132 free = new ArrayList(maxPoolSize); 133 } 134 135 static Logger _logger = LogDomains.getLogger(LogDomains.RSR_LOGGER); 136 137 private void setPoolConfiguration() throws PoolingException{ 138 Context ic = Switch.getSwitch().getNamingManager().getInitialContext(); 139 ConnectorConnectionPool poolResource; 140 try { 141 String jndiNameOfPool = ConnectorAdminServiceUtils. 142 getReservePrefixedJNDINameForPool(name); 143 poolResource = (ConnectorConnectionPool)ic.lookup( jndiNameOfPool ); 144 } catch (NamingException ex) { 145 throw new PoolingException(ex); 146 } 147 idletime = Integer.parseInt(poolResource.getIdleTimeoutInSeconds()) * 1000; 148 maxPoolSize = Integer.parseInt(poolResource.getMaxPoolSize()); 149 steadyPoolSize = Integer.parseInt(poolResource.getSteadyPoolSize()); 150 151 if (maxPoolSize < steadyPoolSize ) { 152 maxPoolSize = steadyPoolSize; 153 } 154 resizeQuantity = Integer.parseInt(poolResource.getPoolResizeQuantity()); 155 156 maxWaitTime = Integer.parseInt(poolResource.getMaxWaitTimeInMillis()); 157 if (maxWaitTime < 0) { 159 maxWaitTime = 0; 160 } 161 162 failAllConnections = poolResource.isFailAllConnections(); 163 matchConnections = poolResource.matchConnections(); 164 validation = poolResource.isIsConnectionValidationRequired(); 165 lazyConnectionAssoc_ = poolResource.isLazyConnectionAssoc(); 166 lazyConnectionEnlist_ = poolResource.isLazyConnectionEnlist(); 167 associateWithThread_ = poolResource.isAssociateWithThread(); 168 connectionLeakTracing_ = poolResource.isConnectionLeakTracing(); 169 validateAtmostEveryIdleSecs = poolResource.isValidateAtmostEveryIdleSecs(); 170 } 171 172 173 protected synchronized void initPool(ResourceSpec resourceSpec, 176 ResourceAllocator allocator) 177 throws PoolingException { 178 179 if (poolInitialized) { 180 return; 181 } 182 183 this.resourceSpec = resourceSpec; 184 this.allocator = allocator; 185 186 createResources(steadyPoolSize); 187 188 if (idletime > 0) { 190 scheduleResizerTask(); 191 } 192 poolInitialized = true; 193 } 194 195 199 private void scheduleResizerTask() { 200 if (resizerTask != null) { 201 resizerTask.cancel(); 203 resizerTask = null; 204 } 205 206 resizerTask = new Resizer(); 207 208 if (timer == null){ 209 timer = Switch.getSwitch().getTimer(); 210 } 211 212 timer.scheduleAtFixedRate(resizerTask, idletime, idletime); 213 if (_logger.isLoggable( Level.FINEST ) ) { 214 _logger.finest("schduled resizer task"); 215 } 216 } 217 218 219 222 synchronized 223 public void addResource(ResourceSpec spec, 224 ResourceHandle h) { 225 if (_logger.isLoggable( Level.FINE ) ) { 226 _logger.log(Level.FINE,"Pool: resource added: " + spec + "," + h); 227 } 228 ResourceState state = new ResourceState(); 230 resources.add(h); 231 h.setResourceState(state); 232 state.setEnlisted(false); 233 state.setBusy(true); 234 235 } 236 237 247 public ResourceHandle getResource(ResourceSpec spec, 248 ResourceAllocator alloc, 249 Transaction tran) throws PoolingException { 250 253 275 ResourceHandle result = null; 276 277 long startTime = 0; 278 long elapsedWaitTime = 0; 279 long remainingWaitTime = 0; 280 281 Object waitMonitor = new Object (); 282 283 if (maxWaitTime > 0) { 284 startTime = System.currentTimeMillis(); 285 } 286 287 while (true) { 288 result = internalGetResource(spec, alloc, tran); 290 291 if (result != null) { 292 if (monitoringEnabled) { 294 poolCounters.incrementNumConnAcquired(); 295 elapsedWaitTime = System.currentTimeMillis() - startTime; 296 poolCounters.setWaitTime(elapsedWaitTime); 297 } 298 299 300 break; 303 } else { 304 if (maxWaitTime > 0) { 306 elapsedWaitTime = System.currentTimeMillis() - startTime; 307 if (elapsedWaitTime < maxWaitTime) { 308 remainingWaitTime = maxWaitTime - elapsedWaitTime; 310 } else { 311 if (monitoringEnabled) { 313 poolCounters.incrementNumConnTimedOut(); 314 } 315 String msg = localStrings.getString( 316 "poolmgr.no.available.resource", 317 "No available resource. Wait-time expired."); 318 throw new PoolingException(msg); 319 } 320 } 321 322 synchronized (waitMonitor) { 323 synchronized (waitQueue) { 324 waitQueue.addLast(waitMonitor); 325 } 326 try { 327 if (_logger.isLoggable( Level.FINE) ) { 328 _logger.log(Level.FINE,"Resource Pool: getting on wait queue"); 329 } 330 waitMonitor.wait(remainingWaitTime); 332 333 } catch (InterruptedException ex) { 334 break; 336 } 337 338 synchronized( waitQueue ) { 342 waitQueue.remove(waitMonitor); 343 } 344 } 345 } 346 } 347 348 alloc.fillInResourceObjects(result); 349 return result; 350 } 351 352 protected abstract ResourceHandle prefetch( ResourceSpec spec, 356 ResourceAllocator alloc, Transaction tran ); 357 358 protected ResourceHandle internalGetResource(ResourceSpec spec, 359 ResourceAllocator alloc, 360 Transaction tran) throws PoolingException { 361 if (!poolInitialized) { 362 initPool(spec, alloc); 363 } 364 ResourceHandle result = null; 365 366 result = prefetch( spec, alloc, tran ); 367 if ( result != null ) { 368 return result; 369 } 370 371 try { 372 if (tran != null && alloc.shareableWithinComponent() ) { 375 J2EETransaction j2eetran = (J2EETransaction) tran; 376 Set set = (Set) j2eetran.getResources(name); 378 if (set != null) { 379 Iterator iter = set.iterator(); 380 while (iter.hasNext()) { 381 ResourceHandle h = (ResourceHandle) iter.next(); 382 if (h.hasConnectionErrorOccurred()) { 383 iter.remove(); 384 continue; 385 } 386 387 ResourceState state = h.getResourceState(); 388 399 if (h.getResourceAllocator().shareableWithinComponent() && 400 ( state.isFree() || spec.isXA())) { 401 if (matchConnections) { 402 if ( !alloc.matchConnection( h )) { 403 if (monitoringEnabled){ 404 poolCounters.incrementNumConnNotSuccessfullyMatched(); 405 } 406 continue; 407 } 408 if (h.hasConnectionErrorOccurred() ) { 409 if ( failAllConnections ) { 410 result = null; 414 break; 415 } 416 iter.remove(); 417 continue; 418 } 419 if (monitoringEnabled){ 420 poolCounters.incrementNumConnSuccessfullyMatched(); 421 } 422 } 423 state.setBusy(true); 424 result = h; 425 break; 426 } 427 } 428 } 429 } 430 } catch(ClassCastException e) { 431 _logger.log(Level.FINE, "Pool: getResource : " + 432 "transaction is not J2EETransaction but a " + tran.getClass().getName() , e); 433 } 434 435 436 if (result == null) { 438 result = getUnenlistedResource(spec, alloc, tran); 439 if ((result != null) && monitoringEnabled) { 442 poolCounters.incrementNumConnUsed(); 443 } 444 } 445 return result; 446 447 } 448 449 455 synchronized protected ResourceHandle getUnenlistedResource(ResourceSpec spec, 456 ResourceAllocator alloc, 457 Transaction tran) throws PoolingException { 458 459 ResourceHandle result = null; 465 466 Iterator iter = free.iterator(); 467 while (iter.hasNext()) { 468 boolean matched = false; 469 ResourceHandle h = (ResourceHandle) iter.next(); 470 if (h.hasConnectionErrorOccurred()) { 471 iter.remove(); 472 continue; 473 } 474 475 if ( h.isAssociated() ) { 478 continue; 480 } 481 482 boolean connectionValid = true; 483 484 long timeSinceValidation = System.currentTimeMillis() - h.getLastValidated(); 485 if (validation || (validateAtmostEveryIdleSecs && timeSinceValidation > idletime)) { 486 if (!alloc.isConnectionValid(h)) { 487 connectionValid = false; 488 } else { 489 h.setLastValidated(System.currentTimeMillis()); 490 } 491 } 492 493 if (connectionValid) { 494 if (matchConnections) { 495 matched = alloc.matchConnection(h); 496 if (monitoringEnabled) { 497 if (matched) { 498 poolCounters.incrementNumConnSuccessfullyMatched(); 499 } else { 500 poolCounters.incrementNumConnNotSuccessfullyMatched(); 501 } 502 } 503 } else { 504 matched = true; } 506 } 507 508 if (h.hasConnectionErrorOccurred() || !connectionValid) { 509 if (failAllConnections) { 510 result = createSingleResourceAndAdjustPool(alloc, spec); 511 break; 513 } else { 514 iter.remove(); 515 continue; 516 } 517 } 518 519 if (matched) { 520 result = h; 521 break; 522 } 523 524 } 525 526 if (result != null) { 527 ResourceState state = result.getResourceState(); 529 state.setBusy(true); 530 free.remove(result); 531 } else { 532 if(resources.size() < steadyPoolSize ){ 533 createResources(steadyPoolSize - resources.size()); 536 if(free.size() != 0){ 537 result = (ResourceHandle)free.remove(0); 538 ResourceState state = result.getResourceState(); 539 state.setBusy(true); 540 } 541 } 542 else if (resources.size() < maxPoolSize) { 543 result = alloc.createResource(); 547 addResource(spec, result); 548 if ( monitoringEnabled ) { 549 poolCounters.incrementNumConnCreated(); 550 } 551 } 552 } 553 554 return result; 555 } 556 557 566 protected ResourceHandle createSingleResourceAndAdjustPool( 567 ResourceAllocator alloc, ResourceSpec spec) 568 throws PoolingException 569 { 570 if ( free.size() != 0 ) { 571 ResourceHandle rHandle = (ResourceHandle) free.get(0); 575 resources.remove( rHandle ); 576 free.remove( rHandle ); 577 } 578 ResourceHandle result = alloc.createResource(); 579 addResource( spec, result ); 580 alloc.fillInResourceObjects( result ); 581 if ( monitoringEnabled ) { 582 poolCounters.incrementNumConnCreated(); 583 } 584 585 return result; 586 587 } 588 589 592 593 private synchronized void createResources(int size) throws PoolingException { 595 for (int i = 0; i < size; i++) { 596 createResourceAndAddToPool(); 597 } 598 } 599 600 601 protected void destroyResource(ResourceHandle resourceHandle) { 602 try { 603 resourceHandle.getResourceAllocator().destroyResource(resourceHandle); 604 } catch (Exception ex) { 605 _logger.log(Level.WARNING,"poolmgr.destroy_resource_failed"); 606 if (_logger.isLoggable( Level.FINE ) ) { 607 _logger.log(Level.FINE,"poolmgr.destroy_resource_failed",ex); 608 } 609 } finally { 610 if (monitoringEnabled) { 611 poolCounters.incrementNumConnDestroyed(); 612 if (resourceHandle.getResourceState().isBusy()){ 613 poolCounters.decrementNumConnUsed(true); 615 } else { 616 poolCounters.decrementNumConnFree(); 618 } 619 } 620 } 621 } 622 623 627 public void resourceClosed(ResourceHandle h) 628 throws IllegalStateException { 629 if (_logger.isLoggable( Level.FINE ) ) { 630 _logger.log(Level.FINE,"Pool: resourceClosed: " + h); 631 } 632 633 ResourceState state = getResourceState(h); 634 if (state == null || state.isBusy() == false) { 635 throw new IllegalStateException ("state is null : " + (state == null) 636 + " ::: state.isBusy() : " + state.isBusy() ); 637 } 638 639 state.setBusy(false); state.touchTimestamp(); 641 642 if (state.isUnenlisted()) { 643 freeUnenlistedResource(h); 644 if(monitoringEnabled){ 646 poolCounters.decrementNumConnUsed(false); 647 } 648 } 649 650 if (monitoringEnabled){ 651 poolCounters.incrementNumConnReleased(); 652 } 653 654 if (_logger.isLoggable( Level.FINE ) ) { 655 _logger.log(Level.FINE,"Pool: resourceFreed: " + h); 656 } 657 } 658 659 protected synchronized void freeUnenlistedResource(ResourceHandle h) { 660 661 free.add(h); 663 notifyWaitingThreads(); 664 } 665 666 synchronized 667 public void resourceErrorOccurred(ResourceHandle h) 668 throws IllegalStateException { 669 logFine("Pool: resourceErrorOccurred: " + h); 670 671 if ( failAllConnections ) { 672 doFailAllConnectionsProcessing(); 673 return; 674 } 675 676 if (monitoringEnabled) { 677 poolCounters.incrementNumConnFailedValidation(1); 678 } 679 ResourceState state = getResourceState(h); 680 690 696 if (state == null) { 697 throw new IllegalStateException (); 698 } 699 700 702 resources.remove(h); 713 destroyResource(h); 714 } 715 716 private void doFailAllConnectionsProcessing() { 717 logFine(" @@@@ doFailAllConnectionsProcessing entered"); 718 cancelResizerTask(); 719 if ( monitoringEnabled ) { 720 poolCounters.incrementNumConnFailedValidation(resources.size()); 721 } 722 723 emptyPool(); 724 try { 725 createResources(steadyPoolSize); 726 } catch(PoolingException pe) { 727 logFine( "in doFailAllConnectionsProcessing couldn't create steady resources"); 729 } 730 scheduleResizerTask(); 731 logFine(" @@@@ doFailAllConnectionsProcessing done - created new resources"); 732 733 } 734 735 739 public void resourceEnlisted(Transaction tran, ResourceHandle resource) 740 throws IllegalStateException { 741 try { 742 J2EETransaction j2eetran = (J2EETransaction) tran; 743 Set set = (Set) j2eetran.getResources(name); 744 if (set == null) { 745 set = new HashSet(); 746 j2eetran.setResources(set, name); 747 } 748 set.add(resource); 749 } catch(ClassCastException e) { 750 _logger.log(Level.FINE, "Pool: resourceEnlisted:" + 751 "transaction is not J2EETransaction but a " + tran.getClass().getName() , e); 752 } 753 ResourceState state = getResourceState(resource); 754 state.setEnlisted(true); 755 if (_logger.isLoggable( Level.FINE ) ) { 756 _logger.log(Level.FINE,"Pool: resourceEnlisted: " + resource); 757 } 758 } 759 760 763 synchronized 764 public void transactionCompleted(Transaction tran, int status) 765 throws IllegalStateException { 766 try { 767 J2EETransaction j2eetran = (J2EETransaction) tran; 768 Set set = (Set) j2eetran.getResources(name); 769 if (set == null) return; 770 771 Iterator iter = set.iterator(); 772 while (iter.hasNext()) { 773 ResourceHandle resource = (ResourceHandle) iter.next(); 774 ResourceState state = getResourceState(resource); 775 state.setEnlisted(false); 776 if ( isResourceUnused(resource) ){ 778 free.add(resource); 779 if(monitoringEnabled){ 780 poolCounters.decrementNumConnUsed(false); 781 } 782 } 783 iter.remove(); 784 notifyWaitingThreads(); 785 if (_logger.isLoggable( Level.FINE ) ) { 786 _logger.log(Level.FINE,"Pool: transactionCompleted: " + resource); 787 } 788 } 789 } catch (ClassCastException e) { 790 _logger.log(Level.FINE, "Pool: transactionCompleted: " + 791 "transaction is not J2EETransaction but a " + tran.getClass().getName() , e); 792 } 793 } 794 795 protected boolean isResourceUnused(ResourceHandle h){ 796 return getResourceState(h).isFree(); 797 } 798 799 protected void notifyWaitingThreads() { 800 Object waitMonitor = null; 802 synchronized (waitQueue) { 803 if (waitQueue.size() > 0) { 804 waitMonitor = waitQueue.removeFirst(); 805 } 806 } 807 if (waitMonitor != null) { 808 synchronized (waitMonitor) { 809 waitMonitor.notify(); 810 } 811 } 812 } 813 814 819 public int getNumThreadWaiting() { 820 return waitQueue.size(); 821 } 822 823 826 public long getNumConnFailedValidation() { 827 return poolCounters.numConnFailedValidation; 828 } 829 830 834 public long getNumConnTimedOut() { 835 return poolCounters.numConnTimedOut; 836 } 837 838 841 public synchronized long getNumConnFree() { 842 return poolCounters.currNumConnFree; 843 } 844 845 public long getMaxNumConnFree(){ 846 return poolCounters.maxNumConnFree; 847 } 848 849 public long getMinNumConnFree(){ 850 if (poolCounters.minNumConnFree != Long.MAX_VALUE) { 851 return poolCounters.minNumConnFree; 852 } else { 853 return 0; 854 } 855 } 856 857 860 public synchronized long getNumConnInUse() { 861 return poolCounters.currNumConnUsed; 862 } 863 864 868 public long getMaxNumConnUsed() { 869 return poolCounters.maxNumConnUsed; 870 } 871 872 873 public long getCurrentConnRequestWaitTime(){ 875 return poolCounters.currConnectionRequestWait; 876 } 877 878 public long getMaxConnRequestWaitTime(){ 879 return poolCounters.maxConnectionRequestWait; 880 } 881 882 public long getMinConnRequestWaitTime(){ 883 if(poolCounters.minConnectionRequestWait != Long.MAX_VALUE) { 884 return poolCounters.minConnectionRequestWait; 885 } else { 886 return 0; 887 } 888 } 889 890 public long getTotalConnectionRequestWaitTime() { 891 return poolCounters.totalConnectionRequestWait; 892 } 893 894 public long getMinNumConnUsed(){ 895 if (poolCounters.minNumConnUsed != Long.MAX_VALUE) { 896 return poolCounters.minNumConnUsed; 897 } else { 898 return 0; 899 } 900 } 901 902 public long getNumConnCreated(){ 903 return poolCounters.numConnCreated; 904 } 905 906 public long getNumConnDestroyed(){ 907 return poolCounters.numConnDestroyed; 908 } 909 910 public long getNumConnAcquired() { 911 return poolCounters.numConnAcquired; 912 } 913 914 public long getNumConnReleased() { 915 return poolCounters.numConnReleased; 916 } 917 918 public long getNumConnSuccessfullyMatched(){ 919 return poolCounters.numConnSuccessfullyMatched; 920 } 921 922 public long getNumConnNotSuccessfullyMatched(){ 923 return poolCounters.numConnNotSuccessfullyMatched; 924 } 925 926 927 929 934 synchronized public void resizePool(boolean forced) { 935 936 943 synchronized (waitQueue) { 944 if (waitQueue.size() > 0) { 945 return; 946 } 947 } 948 949 if(validation){ 950 _logger.log(Level.FINE, "CP.Resizer.Validation-Turned-On"); 951 removeInvalidResources(); 952 } 953 954 int overSize = resources.size() - steadyPoolSize; 957 958 if (overSize > 0) { 959 int numResourcesToBeDestroyed = 960 (resizeQuantity < overSize ? resizeQuantity : overSize); 961 962 ResourceHandle h; 963 ResourceState state; 964 965 Iterator iter = free.iterator(); 966 long currentTime = System.currentTimeMillis(); 968 969 while ( (numResourcesToBeDestroyed > 0) && iter.hasNext()) { 970 h = (ResourceHandle) iter.next(); 971 state = getResourceState(h); 972 if (forced || (currentTime - state.getTimestamp() > idletime)) { 973 resources.remove(h); 975 destroyResource(h); 976 iter.remove(); 977 numResourcesToBeDestroyed--; 978 } 979 } 980 } 981 983 if (resources.size() < steadyPoolSize) { 986 for (int i = resources.size(); i < steadyPoolSize; i++) { 989 try { 990 createResourceAndAddToPool(); 991 } catch (PoolingException ex) { 992 _logger.log(Level.WARNING, 993 "resource_pool.resize_pool_error", 994 (ex.getMessage() != null ? ex.getMessage() : " ") ); 995 continue; 996 } 997 } 998 } 999 1000 if (_logger.isLoggable(Level.FINE)) { 1001 _logger.log(Level.FINE,"Pool: Name = " + name); 1002 _logger.log(Level.FINE,"Pool: Resource held: " 1003 + resources.size()); 1004 } 1005 } 1006 1007 1012 private void removeInvalidResources() { 1013 try { 1014 Set freeManagedConnections = new HashSet(); 1016 for (Iterator iter = free.iterator(); iter.hasNext();) { 1017 ResourceHandle element = (ResourceHandle) iter.next(); 1018 freeManagedConnections.add(element.getResource()); 1019 } 1020 1021 _logger.log(Level.FINE, "Sending to RA a set of free connections " + 1022 "of size", new Integer (freeManagedConnections.size())); 1023 1024 Set invalidManagedConnections = 1026 this.allocator.getInvalidConnections(freeManagedConnections); 1027 1028 if (invalidManagedConnections != null) { 1032 _logger.log(Level.FINE, "Received from RA invalid connections # ", 1033 new Integer (invalidManagedConnections.size())); 1034 1035 for (Iterator iter = invalidManagedConnections.iterator(); 1036 iter.hasNext();) { 1037 ManagedConnection invalidManagedConnection = 1038 (ManagedConnection )iter.next(); 1039 for (Iterator freeResourcesIter = free.iterator(); 1040 freeResourcesIter.hasNext();) { 1041 ResourceHandle handle = 1042 (ResourceHandle) freeResourcesIter.next(); 1043 if (invalidManagedConnection.equals 1044 (handle.getResource())) { 1045 resources.remove(handle); 1046 destroyResource(handle); 1047 freeResourcesIter.remove(); 1048 } 1049 } 1050 } 1051 } else { 1052 _logger.log(Level.FINE, "RA does not support " + 1053 "ValidatingManagedConnectionFactory"); 1054 } 1055 } catch (ResourceException re) { 1056 _logger.log(Level.FINE, "ResourceException while trying to " + 1057 "get invalid connections from MCF", re); 1058 } catch (Exception e) { 1059 _logger.log(Level.FINE, "Exception while trying " + 1060 "to get invalid connections from MCF", e); 1061 } 1062 } 1063 1064 private ResourceState getResourceState(ResourceHandle h) { 1065 return h.getResourceState(); 1066 } 1067 1068 synchronized public void emptyPool() { 1069 logFine("EmptyPool: Name = " + name); 1070 1071 Iterator iter = resources.iterator(); 1072 while(iter.hasNext()) { 1073 ResourceHandle h = (ResourceHandle) iter.next(); 1074 destroyResource(h); 1075 } 1076 free.clear(); 1077 resources.clear(); 1078 } 1079 1080 synchronized public void emptyFreeConnectionsInPool() { 1081 if (_logger.isLoggable(Level.FINE)) { 1082 _logger.fine( "Emptying free connections in pool : " + name ); 1083 } 1084 Iterator iter = free.iterator(); 1085 while( iter.hasNext() ) { 1086 ResourceHandle h = (ResourceHandle) iter.next(); 1087 resources.remove( h ); 1088 destroyResource( h ); 1089 } 1090 free.clear(); 1091 } 1092 1093 class Resizer extends TimerTask { 1094 public void run() { 1095 1096 if (_logger.isLoggable( Level.FINE ) ) { 1097 _logger.log(Level.FINE,"AbstractResourcePool: resize pool " 1098 + name); 1099 } 1100 resizePool(false); 1101 } 1102 } 1103 1104 public String toString() { 1105 StringBuffer sb = new StringBuffer ("Pool ["); 1106 sb.append(name); 1107 sb.append("] PoolSize="); 1108 sb.append(resources.size()); 1109 sb.append(" FreeResources="); 1110 sb.append(free.size()); 1111 sb.append(" QueueSize="); 1112 sb.append(waitQueue.size()); 1113 sb.append(" matching="); 1114 sb.append( (matchConnections ? "on" : "off") ); 1115 sb.append(" validation="); 1116 sb.append( (validation ? "on" : "off") ); 1117 return sb.toString(); 1118 } 1119 1120 1121 public boolean isMonitoringEnabled() { 1122 return monitoringEnabled; 1123 } 1124 public void disableMonitoring() { 1125 monitoringEnabled = false; 1126 } 1127 1128 public void setMonitoringEnabledHigh() { 1129 logFine("Enabling monitoring to level : HIGH"); 1130 int numConnFree = (this.poolInitialized) ? this.free.size() : this.steadyPoolSize; 1131 if ( poolCounters == null ){ 1132 poolCounters = new HighPoolCounters(numConnFree); 1133 } 1134 poolCounters.reset(numConnFree); 1135 monitoringEnabled = true; 1136 } 1137 1138 public void setMonitoringEnabledLow() { 1139 logFine("Enabling monitoring to level : LOW"); 1140 if ( poolCounters == null ){ 1141 poolCounters = new LowPoolCounters(0); 1142 } 1143 poolCounters.reset(0); 1144 monitoringEnabled = true; 1145 } 1146 1147 1156 public synchronized void reconfigPoolProperties( ConnectorConnectionPool poolResource ) 1157 throws PoolingException 1158 { 1159 int _idleTime = Integer.parseInt(poolResource.getIdleTimeoutInSeconds()) 1160 * 1000; 1161 if (_idleTime != idletime && _idleTime != 0) { 1162 scheduleResizerTask(); 1163 } 1164 if (_idleTime == 0 ) { 1165 cancelResizerTask(); 1167 } 1168 1169 idletime = _idleTime; 1170 1171 1172 resizeQuantity = Integer.parseInt(poolResource.getPoolResizeQuantity()); 1173 1174 maxWaitTime = Integer.parseInt(poolResource.getMaxWaitTimeInMillis()); 1175 if (maxWaitTime < 0) { 1177 maxWaitTime = 0; 1178 } 1179 1180 validation = poolResource.isIsConnectionValidationRequired(); 1181 failAllConnections = poolResource.isFailAllConnections(); 1182 matchConnections = poolResource.matchConnections(); 1183 lazyConnectionAssoc_ = poolResource.isLazyConnectionAssoc(); 1184 lazyConnectionEnlist_ = poolResource.isLazyConnectionEnlist(); 1185 associateWithThread_ = poolResource.isAssociateWithThread(); 1186 connectionLeakTracing_ = poolResource.isConnectionLeakTracing(); 1187 1188 if ( ! isSelfManaged() ) { 1191 int _maxPoolSize = Integer.parseInt(poolResource.getMaxPoolSize()); 1192 if (_maxPoolSize < maxPoolSize ) { 1193 int toKill = resources.size() - _maxPoolSize; 1200 1201 killExtraResources( toKill ); 1202 } 1203 1204 if (_maxPoolSize < steadyPoolSize ) { 1205 maxPoolSize = steadyPoolSize; 1206 } else { 1207 maxPoolSize = _maxPoolSize; 1208 } 1209 1210 int _steadyPoolSize = Integer.parseInt( 1211 poolResource.getSteadyPoolSize()); 1212 if ( _steadyPoolSize > steadyPoolSize ) { 1213 increaseSteadyPoolSize( _steadyPoolSize ); 1214 } 1215 1216 if (_steadyPoolSize > maxPoolSize ) { 1217 steadyPoolSize = maxPoolSize; 1218 } else { 1219 steadyPoolSize = _steadyPoolSize; 1220 } 1221 } 1222 1223 } 1224 1225 1230 private void killExtraResources(int numToKill) { 1231 cancelResizerTask(); 1232 1233 Iterator iter = free.iterator(); 1234 for( int i = 0; iter.hasNext() && i < numToKill ; i++ ) { 1235 ResourceHandle h = (ResourceHandle) iter.next(); 1236 ResourceState s = getResourceState(h); 1237 resources.remove(h); 1238 destroyResource( h ); 1239 iter.remove(); 1240 } 1241 1242 scheduleResizerTask(); 1243 } 1244 1245 1249 private void increaseSteadyPoolSize( int newSteadyPoolSize ) 1250 throws PoolingException 1251 { 1252 cancelResizerTask(); 1253 for (int i = resources.size(); i < newSteadyPoolSize; i++) { 1254 createResourceAndAddToPool(); 1255 } 1256 scheduleResizerTask(); 1257 } 1258 1259 1262 private void createResourceAndAddToPool() throws PoolingException { 1263 ResourceHandle resourceHandle = allocator.createResource(); 1264 addResource(resourceSpec, resourceHandle); 1266 1267 getResourceState(resourceHandle).setBusy(false); 1270 free.add(resourceHandle); 1271 1272 if ( monitoringEnabled ) { 1273 poolCounters.incrementNumConnCreated(); 1274 } 1275 } 1276 1277 1280 public void switchOnMatching() { 1281 matchConnections = true; 1282 } 1283 1284 1289 public String getPoolName() { 1290 return name; 1291 } 1292 1293 public synchronized void cancelResizerTask() { 1294 1295 if (_logger.isLoggable( Level.FINE ) ) { 1296 _logger.finest("Cancelling resizer"); 1297 } 1298 if (resizerTask != null ) { 1299 resizerTask.cancel(); 1300 } 1301 resizerTask = null; 1302 1303 if (timer != null){ 1304 timer.purge(); 1305 } 1306 } 1307 1308 1309 public synchronized void dumpPoolStatus() { 1310 _logger.log(Level.INFO, "Name of pool :" + name); 1311 _logger.log(Level.INFO, "Free connections :" + free.size()); 1312 _logger.log(Level.INFO, "Total connections :" + resources.size()); 1313 _logger.log(Level.INFO, "Pool's matching is :" + matchConnections); 1314 _logger.log(Level.INFO, "Free Table is :" + free); 1315 _logger.log(Level.INFO, "Resource Table is :" + resources); 1316 } 1317 1318 public PoolCounters getPoolCounters(){ 1320 return this.poolCounters; 1321 } 1322 1323 private void logFine( String msg ) { 1324 if ( _logger.isLoggable( Level.FINE) ) { 1325 _logger.fine( msg ); 1326 } 1327 } 1328 1329 public int getMaxPoolSize() { 1331 return maxPoolSize; 1332 } 1333 1334 public int getSteadyPoolSize() { 1335 return steadyPoolSize; 1336 } 1337 1338 1339 public void setMaxPoolSize( int size ) { 1340 if ( size < resources.size() ) { 1341 synchronized( this ) { 1342 int toKill = resources.size() - size; 1343 if ( toKill > 0 ) { 1344 try { 1345 killExtraResources( toKill ); 1346 } catch( Exception re ) { 1347 if (_logger.isLoggable(Level.FINE) ) { 1349 _logger.fine( "setMaxPoolSize:: killExtraResources " + 1350 "throws exception: " + re.getMessage() ); 1351 } 1352 } 1353 } 1354 } 1355 } 1356 maxPoolSize = size; 1357 } 1358 1359 public void setSteadyPoolSize( int size ) { 1360 steadyPoolSize = size; 1361 } 1362 1363 public void setSelfManaged( boolean selfManaged ) { 1364 logFine( "Setting selfManaged to : " +selfManaged+" in pool : "+name ); 1365 selfManaged_ = selfManaged; 1366 } 1367 1368 protected boolean isSelfManaged() { 1369 return selfManaged_; 1370 } 1371 1372 class PoolCounters { 1373 long numConnFailedValidation = 0; 1376 long numConnTimedOut = 0; 1377 long numConnAcquired = 0; 1378 long numConnReleased = 0; 1379 1380 long maxNumConnUsed = 0; long minNumConnUsed = Long.MAX_VALUE; 1382 long currNumConnUsed = 0; 1383 1384 long currConnectionRequestWait = 0; 1386 long maxConnectionRequestWait = 0; 1387 long minConnectionRequestWait = Long.MAX_VALUE; 1388 long totalConnectionRequestWait = 0; 1390 long maxNumConnFree = 0; 1391 long minNumConnFree = Long.MAX_VALUE; 1392 long currNumConnFree = 0; 1393 1394 long numConnCreated = 0; 1395 long numConnDestroyed = 0; 1396 1397 long numConnSuccessfullyMatched = 0; 1398 long numConnNotSuccessfullyMatched = 0; 1399 1400 PoolCounters(int freePoolSize) { 1401 currNumConnFree = freePoolSize; 1402 } 1403 1404 1405 protected void reset(int freePoolSize) { 1406 maxNumConnUsed = 0; 1407 minNumConnUsed = Long.MAX_VALUE; 1408 currNumConnUsed = 0; 1409 1410 numConnFailedValidation = 0; 1411 numConnTimedOut = 0; 1412 1413 maxConnectionRequestWait = 0; 1414 minConnectionRequestWait = Long.MAX_VALUE; 1415 totalConnectionRequestWait = 0; 1416 1417 maxNumConnFree = 0; 1418 minNumConnFree = Long.MAX_VALUE; 1419 currNumConnFree = freePoolSize; 1420 1421 numConnCreated = 0; 1422 numConnDestroyed = 0; 1423 1424 numConnSuccessfullyMatched = 0; 1425 numConnNotSuccessfullyMatched = 0; 1426 } 1427 1428 protected synchronized void setWaitTime(long elapsedWaitTime) {} 1429 protected synchronized void incrementNumConnUsed(){} 1430 protected synchronized void decrementNumConnUsed(boolean isConnectionDestroyed){} 1431 protected synchronized void decrementNumConnFree(){} 1432 protected void setNumConnUsed(long numConnInUse){} 1433 protected void setNumConnFree(long numConnFree){} 1434 protected void incrementNumConnCreated(){} 1435 protected void incrementNumConnDestroyed(){} 1436 protected void incrementNumConnMatched() {} 1437 protected void incrementNumConnNotMatched() {} 1438 protected void incrementNumConnAcquired() {} 1439 protected void incrementNumConnTimedOut() {} 1440 protected void incrementNumConnReleased() {} 1441 protected void incrementNumConnFailedValidation(int incr) {} 1442 protected void incrementNumConnSuccessfullyMatched() {} 1443 protected void incrementNumConnNotSuccessfullyMatched() {} 1444 1445 public String toString(){ 1446 String str = "PoolCounters: "; 1447 str += "\n numConnFailedValidation = " + numConnFailedValidation; 1448 str += "\n numConnTimedOut = " + numConnTimedOut; 1449 str += "\n numConnAcquired = " + numConnAcquired; 1450 str += "\n numConnReleased = " + numConnReleased; 1451 1452 str += "\n maxNumConnUsed = " + maxNumConnUsed; 1453 str += "\n minNumConnUsed = " + minNumConnUsed; 1454 str += "\n currNumConnUsed = " + currNumConnUsed; 1455 1456 str += "\n maxConnectionRequestWait = " + maxConnectionRequestWait; 1457 str += "\n minConnectionRequestWait = " + minConnectionRequestWait; 1458 str += "\n maxNumConnFree = = " + maxNumConnFree; 1459 str += "\n minNumConnFree = " + minNumConnFree; 1460 1461 str += "\n currNumConnFree = " + currNumConnFree; 1462 str += "\n numConnCreated = " + numConnCreated; 1463 str += "\n numConnDestroyed = " + numConnDestroyed; 1464 1465 str += "\n numConnSuccessfullyMatched = " + numConnSuccessfullyMatched; 1466 str += "\n numConnNotSuccessfullyMatched = " + numConnNotSuccessfullyMatched; 1467 return str; 1468 } 1469 } 1470 1471 class LowPoolCounters extends PoolCounters { 1472 1473 LowPoolCounters( int freePoolSize ) { 1474 super( freePoolSize ); 1475 } 1476 1477 @Override 1478 protected void incrementNumConnCreated(){ 1479 numConnCreated++; 1480 } 1481 1482 @Override 1483 protected void incrementNumConnDestroyed(){ 1484 numConnDestroyed++; 1485 } 1486 1487 @Override 1488 protected synchronized void incrementNumConnUsed(){ 1489 this.setNumConnUsed(++this.currNumConnUsed); 1490 this.setNumConnFree(--this.currNumConnFree); 1491 } 1492 1493 @Override 1494 protected synchronized void decrementNumConnUsed(boolean isConnectionDestroyed){ 1497 this.setNumConnUsed(--this.currNumConnUsed); 1498 1499 if (isConnectionDestroyed) { 1500 if((poolCounters.currNumConnFree + poolCounters.currNumConnUsed) 1504 < steadyPoolSize) { 1505 this.setNumConnFree(++this.currNumConnFree); 1506 } 1507 } else { 1508 this.setNumConnFree(++this.currNumConnFree); 1512 } 1513 } 1514 1515 @Override 1518 protected synchronized void decrementNumConnFree(){ 1519 if((poolCounters.currNumConnFree + poolCounters.currNumConnUsed) 1522 > steadyPoolSize) 1523 this.setNumConnFree(--this.currNumConnFree); 1524 } 1525 1526 @Override 1527 protected void setNumConnUsed(long numConnInUse){ 1528 if ( numConnInUse > maxNumConnUsed ) { 1530 maxNumConnUsed = numConnInUse; 1531 } 1532 if ( numConnInUse < minNumConnUsed ) { 1534 if (numConnInUse <= 0) { 1535 minNumConnUsed = 0; 1536 } else { 1537 minNumConnUsed = numConnInUse; 1538 } 1539 } 1540 this.currNumConnUsed = numConnInUse; 1542 } 1543 1544 @Override 1545 protected void setNumConnFree(long numConnFree){ 1546 if ( numConnFree > maxNumConnFree ) { 1548 maxNumConnFree = numConnFree; 1549 } 1550 1551 if ( numConnFree < minNumConnFree ) { 1553 if (numConnFree <= 0) { 1554 minNumConnFree = 0; 1555 } else { 1556 minNumConnFree = numConnFree; 1557 } 1558 } 1559 1560 this.currNumConnFree = (numConnFree >= 0) ? numConnFree : 0; 1562 } 1563 } 1564 1565 class HighPoolCounters extends LowPoolCounters { 1566 1567 HighPoolCounters( int freePoolSize ) { 1568 super( freePoolSize ); 1569 } 1570 1571 @Override 1572 public synchronized void setWaitTime(long elapsedWaitTime) { 1573 currConnectionRequestWait = elapsedWaitTime; 1575 if (elapsedWaitTime > maxConnectionRequestWait) 1576 maxConnectionRequestWait= elapsedWaitTime; 1577 if (elapsedWaitTime < minConnectionRequestWait) 1579 minConnectionRequestWait = elapsedWaitTime; 1580 totalConnectionRequestWait += elapsedWaitTime; 1581 } 1582 1583 @Override 1584 protected void incrementNumConnAcquired() { 1585 numConnAcquired++; 1586 } 1587 1588 @Override 1589 protected void incrementNumConnTimedOut() { 1590 numConnTimedOut++; 1591 } 1592 1593 @Override 1594 protected void incrementNumConnReleased() { 1595 numConnReleased++; 1596 } 1597 1598 @Override 1599 protected void incrementNumConnFailedValidation( int incr ) { 1600 numConnFailedValidation += incr; 1601 } 1602 1603 @Override 1604 protected void incrementNumConnSuccessfullyMatched() { 1605 numConnSuccessfullyMatched++; 1606 } 1607 1608 @Override 1609 protected void incrementNumConnNotSuccessfullyMatched() { 1610 numConnNotSuccessfullyMatched++; 1611 } 1612 } 1613 1614} 1615 | Popular Tags |