1 23 24 29 30 31 package com.sun.ejb.containers.util.pool; 32 33 import java.util.*; 34 35 import com.sun.ejb.containers.ContainerFactoryImpl; 36 import java.util.logging.*; 37 import java.util.TimerTask ; 38 import com.sun.logging.*; 39 40 import com.sun.enterprise.util.Utility; 41 import com.sun.ejb.containers.EJBContextImpl; 42 43 import com.sun.enterprise.util.threadpool.Servicable; 44 import com.sun.ejb.containers.util.ContainerWorkPool; 45 46 61 62 63 public class NonBlockingPool 64 extends AbstractPool 65 { 66 67 private String poolName; 68 private TimerTask poolTimerTask; 69 protected boolean addedResizeTask = false; 70 protected boolean addedIdleBeanWork = false; 71 protected boolean inResizing = false; 72 private boolean maintainSteadySize = false; 73 74 private int resizeTaskCount; 75 private int timerTaskCount; 76 77 protected NonBlockingPool() { 78 } 79 80 public NonBlockingPool(String poolName, ObjectFactory factory, 81 int steadyPoolSize, int resizeQuantity, 82 int maxPoolSize, int idleTimeoutInSeconds, 83 ClassLoader loader) 84 { 85 this.poolName = poolName; 86 initializePool(factory, steadyPoolSize, resizeQuantity, maxPoolSize, 87 idleTimeoutInSeconds, loader); 88 } 89 90 protected void initializePool(ObjectFactory factory, int steadyPoolSize, 91 int resizeQuantity, int maxPoolSize, int idleTimeoutInSeconds, 92 ClassLoader loader) 93 { 94 list = new ArrayList(); 95 96 this.factory = factory; 97 this.steadyPoolSize = (steadyPoolSize <= 0) ? 0 : steadyPoolSize; 98 this.resizeQuantity = (resizeQuantity <= 0) ? 0 : resizeQuantity; 99 this.maxPoolSize = (maxPoolSize <= 0) 100 ? Integer.MAX_VALUE : maxPoolSize; 101 this.steadyPoolSize = (this.steadyPoolSize > this.maxPoolSize) 102 ? this.maxPoolSize : this.steadyPoolSize; 103 this.idleTimeoutInSeconds = 104 (idleTimeoutInSeconds <= 0) ? 0 : idleTimeoutInSeconds; 105 106 this.containerClassLoader = loader; 107 108 this.maintainSteadySize = (this.steadyPoolSize > 0); 109 if ((this.idleTimeoutInSeconds > 0) && (this.resizeQuantity > 0)) { 110 try { 111 this.poolTimerTask = new PoolResizeTimerTask(); 112 ContainerFactoryImpl.getTimer().scheduleAtFixedRate 113 (poolTimerTask, idleTimeoutInSeconds*1000, 114 idleTimeoutInSeconds*1000); 115 if(_logger.isLoggable(Level.FINE)) { 116 _logger.log(Level.FINE, 117 "[Pool-" + poolName + "]: Added PoolResizeTimerTask..."); 118 } 119 } catch (Throwable th) { 120 _logger.log(Level.WARNING,"[Pool-" + 121 poolName + "]: Could not add" 122 + " PoolTimerTask. Continuing anyway...", th); 123 } 124 } 125 } 126 127 128 public void setContainerClassLoader(ClassLoader loader) { 129 this.containerClassLoader = loader; 130 } 131 132 140 public Object getObject(boolean canWait, Object param) 141 throws PoolException 142 { 143 return getObject(param); 144 } 145 146 public Object getObject(long maxWaitTime, Object param) 147 throws PoolException 148 { 149 return getObject(param); 150 } 151 152 public Object getObject(Object param) 153 { 154 boolean toAddResizeTask = false; 155 Object obj = null; 156 synchronized (list) { 157 int size = list.size(); 158 if (size > steadyPoolSize) { 159 poolSuccess++; 160 return list.remove(size-1); 161 } else if (size > 0) { 162 poolSuccess++; 163 if ((maintainSteadySize) && (addedResizeTask == false)) { 164 toAddResizeTask = addedResizeTask = true; 165 obj = list.remove(size-1); 166 } else { 167 return list.remove(size-1); 168 } 169 } else { 170 if ((maintainSteadySize) && (addedResizeTask == false)) { 171 toAddResizeTask = addedResizeTask = true; 172 } 173 createdCount++; } 175 } 176 177 if (toAddResizeTask) { 178 addResizeTaskForImmediateExecution(); 179 } 180 181 if (obj != null) { 182 return obj; 183 } 184 185 try { 186 return factory.create(param); 187 } catch (RuntimeException th) { 188 synchronized (list) { 189 createdCount--; 190 } 191 throw th; 192 } 193 } 194 195 private void addResizeTaskForImmediateExecution() { 196 try { 197 ReSizeWork work = new ReSizeWork(); 198 ContainerWorkPool.addLast(work); 199 if(_logger.isLoggable(Level.FINE)) { 200 _logger.log(Level.FINE, 201 "[Pool-" + poolName + "]: Added PoolResizeTimerTask..."); 202 } 203 resizeTaskCount++; 204 } catch (Exception ex) { 205 synchronized (list) { 206 addedResizeTask = false; 207 } 208 if(_logger.isLoggable(Level.WARNING)) { 209 _logger.log(Level.WARNING, 210 "[Pool-"+poolName+"]: Cannot perform " 211 + " pool resize task", ex); 212 } 213 } 214 } 215 216 221 public void returnObject(Object object) { 222 synchronized (list) { 223 if (list.size() < maxPoolSize) { 224 list.add(object); 225 return; 226 } else { 227 destroyedCount++; 228 } 229 } 230 231 try { 232 factory.destroy(object); 233 } catch (Exception ex) { 234 _logger.log(Level.FINE, "exception in returnObj", ex); 235 } 236 } 237 238 246 public void destroyObject(Object object) { 247 synchronized (list) { 248 destroyedCount++; 249 } 250 251 try { 252 factory.destroy(object); 253 } catch (Exception ex) { 254 _logger.log(Level.FINE, "exception in destroyObject", ex); 255 } 256 } 257 258 262 protected void preload(int count) { 263 264 ArrayList instances = new ArrayList(count); 265 try { 266 for (int i=0; i<count; i++) { 267 instances.add(factory.create(null)); 268 } 269 } catch (Exception ex) { 270 } 272 273 int sz = instances.size(); 274 if (sz == 0) { 275 return; 276 } 277 synchronized (list) { 278 for (int i=0; i<sz; i++) { 279 list.add(instances.get(i)); 280 } 281 createdCount += sz; 282 } 283 } 284 285 289 public void prepopulate(int count) { 290 this.steadyPoolSize = (count <= 0) ? 0 : count; 291 this.steadyPoolSize = (this.steadyPoolSize > this.maxPoolSize) 292 ? this.maxPoolSize : this.steadyPoolSize; 293 294 if (this.steadyPoolSize > 0) { 295 preload(this.steadyPoolSize); 296 } 297 298 } 299 300 303 public void close() { 304 synchronized (list) { 305 if (poolTimerTask != null) { 306 try { 307 poolTimerTask.cancel(); 308 if(_logger.isLoggable(Level.FINE)) { 309 _logger.log(Level.FINE, 310 "[Pool-"+poolName+"]: Cancelled pool timer task " 311 + " at: " + (new java.util.Date ())); 312 } 313 } catch (Throwable th) { 314 } 316 } 317 318 if(_logger.isLoggable(Level.FINE)) { 319 _logger.log(Level.FINE,"[Pool-"+poolName+"]: Destroying " 320 + list.size() + " beans from the pool..."); 321 } 322 323 ClassLoader origLoader = 326 Utility.setContextClassLoader(containerClassLoader); 327 328 Object [] array = list.toArray(); 329 for (int i=0; i<array.length; i++) { 330 try { 331 destroyedCount++; 332 try { 333 factory.destroy(array[i]); 334 } catch (Throwable th) { 335 _logger.log(Level.FINE, "exception in close", th); 336 } 337 } catch (Throwable th) { 338 _logger.log(Level.WARNING, 339 "[Pool-"+poolName+"]: Error while destroying", th); 340 } 341 } 342 if(_logger.isLoggable(Level.FINE)) { 343 _logger.log(Level.FINE,"Pool-"+poolName+"]: Pool closed...."); 344 } 345 list.clear(); 346 347 Utility.setContextClassLoader(origLoader); 348 } 349 350 this.list = null; 352 this.factory = null; 353 this.poolTimerTask = null; 354 this.containerClassLoader = null; 355 356 } 357 358 protected void remove(int count) { 359 ArrayList removeList = new ArrayList(); 360 synchronized (list) { 361 int size = list.size(); 362 for (int i=0; (i<count) && (size > 0); i++) { 363 removeList.add(list.remove(--size)); 364 destroyedCount++; 365 } 366 } 367 368 int sz = removeList.size(); 369 for (int i=0; i<sz; i++) { 370 try { 371 factory.destroy(removeList.get(i)); 372 } catch (Throwable th) { 373 _logger.log(Level.FINE, "exception in remove", th); 374 } 375 } 376 } 377 378 protected void removeIdleObjects() { 379 } 380 381 protected void doResize() { 382 383 final Thread currentThread = Thread.currentThread(); 385 final ClassLoader previousClassLoader = 386 currentThread.getContextClassLoader(); 387 final ClassLoader ctxClassLoader = containerClassLoader; 388 389 long startTime = 0; 390 boolean enteredResizeBlock = false; 391 try { 392 393 java.security.AccessController.doPrivileged( 394 new java.security.PrivilegedAction () { 395 public java.lang.Object run() { 396 currentThread.setContextClassLoader(ctxClassLoader); 397 return null; 398 } 399 }); 400 401 if(_logger.isLoggable(Level.FINE)) { 402 _logger.log(Level.FINE, 403 "[Pool-"+poolName+"]: Resize started at: " 404 + (new java.util.Date ())+" steadyPoolSize ::"+steadyPoolSize 405 + " resizeQuantity ::"+resizeQuantity+" maxPoolSize ::" + 406 maxPoolSize ); 407 } 408 startTime = System.currentTimeMillis(); 409 410 ArrayList removeList = new ArrayList(); 411 int populateCount = 0; 412 synchronized (list) { 413 if (inResizing == true) { 414 return; 415 } 416 417 enteredResizeBlock = true; 418 inResizing = true; 419 420 int curSize = list.size(); 421 422 if (curSize > steadyPoolSize) { 423 424 if ((idleTimeoutInSeconds <= 0) || 426 (resizeQuantity <= 0)) { 427 return; 428 } 429 int victimCount = 430 (curSize > (steadyPoolSize + resizeQuantity) ) 431 ? resizeQuantity : (curSize - steadyPoolSize); 432 long allowedIdleTime = System.currentTimeMillis() - 433 idleTimeoutInSeconds*1000; 434 if(_logger.isLoggable(Level.FINE)) { 435 _logger.log(Level.FINE, 436 "[Pool-"+poolName+"]: Resize:: reducing " 437 + " pool size by: " + victimCount); 438 } 439 for (int i=0; i<victimCount; i++) { 440 EJBContextImpl ctx = (EJBContextImpl) list.get(0); 443 if (ctx.getLastTimeUsed() <= allowedIdleTime) { 444 removeList.add(list.remove(0)); 445 destroyedCount++; 446 } else { 447 break; 448 } 449 } 450 } else if (curSize < steadyPoolSize) { 451 452 if (maintainSteadySize == false) { 454 return; 455 } 456 457 if (resizeQuantity <= 0) { 458 populateCount = steadyPoolSize - curSize; 459 } else { 460 while ((curSize + populateCount) < steadyPoolSize) { 461 populateCount += resizeQuantity; 462 } 463 if ((curSize + populateCount) > maxPoolSize) { 464 populateCount -= (curSize + populateCount) - maxPoolSize; 465 } 466 } 467 } 468 } 469 470 if (removeList.size() > 0) { 471 int sz = removeList.size(); 472 for (int i=0; i<sz; i++) { 473 try { 474 factory.destroy(removeList.get(i)); 475 } catch (Throwable th) { 476 _logger.log(Level.FINE, "exception in doResize", th); 477 } 478 } 479 } 480 481 if (populateCount > 0) { 482 484 if(_logger.isLoggable(Level.FINE)) { 485 _logger.log(Level.FINE, 486 "[Pool-"+poolName+"]: Attempting to preload " 487 + populateCount + " beans. CurSize/MaxPoolSize: " 488 + list.size() + "/" + maxPoolSize); 489 } 490 491 preload(populateCount); 492 493 if(_logger.isLoggable(Level.FINE)) { 494 _logger.log(Level.FINE, 495 "[Pool-"+poolName+"]: After preload " 496 + "CurSize/MaxPoolSize: " 497 + list.size() + "/" + maxPoolSize); 498 } 499 } 500 501 502 } catch (Throwable th) { 503 _logger.log(Level.WARNING, 504 "[Pool-"+poolName+"]: Exception during reSize", th); 505 506 } finally { 507 508 if (enteredResizeBlock) { 509 synchronized (list) { 510 inResizing = false; 511 } 512 } 513 514 java.security.AccessController.doPrivileged( 515 new java.security.PrivilegedAction () { 516 public java.lang.Object run() { 517 currentThread.setContextClassLoader(previousClassLoader); 518 return null; 519 } 520 }); 521 } 522 523 long endTime = System.currentTimeMillis(); 524 if(_logger.isLoggable(Level.FINE)) { 525 _logger.log(Level.FINE, 526 "[Pool-"+poolName+"]: Resize completed at: " 527 + (new java.util.Date ()) + "; after reSize: " + 528 getAllAttrValues()); 529 _logger.log(Level.FINE, "[Pool-"+poolName+"]: Resize took: " 530 + ((endTime-startTime)/1000.0) + " seconds."); 531 } 532 } 533 534 public String getAllAttrValues() { 535 StringBuffer sbuf = new StringBuffer ("[Pool-"+poolName+"] "); 536 sbuf.append("CC=").append(createdCount).append("; ") 537 .append("DC=").append(destroyedCount).append("; ") 538 .append("CS=").append(list.size()).append("; ") 539 .append("SS=").append(steadyPoolSize).append("; ") 540 .append("MS=").append(maxPoolSize).append(";"); 541 return sbuf.toString(); 542 } 543 544 private class ReSizeWork 545 implements Servicable 546 { 547 public void prolog() { 548 } 549 550 public void service() { 551 run(); 552 } 553 554 public void epilog() { 555 } 556 557 public void run() { 558 try { 559 doResize(); 560 } catch (Exception ex) { 561 _logger.log(Level.WARNING, 562 "[Pool-"+poolName+"]: Exception during reSize", ex); 563 } finally { 564 synchronized (list) { 565 addedResizeTask = false; 566 } 567 } 568 } 569 } 570 571 private class IdleBeanWork 572 implements Servicable 573 { 574 public void prolog() { 575 } 576 577 public void service() { 578 run(); 579 } 580 581 public void epilog() { 582 } 583 584 public void run() { 585 try { 586 doResize(); 587 } catch (Exception ex) { 588 } finally { 589 addedIdleBeanWork = false; 590 } 591 } 592 } 593 594 private class PoolResizeTimerTask 595 extends java.util.TimerTask 596 { 597 Object lock; 598 599 PoolResizeTimerTask() {} 600 601 PoolResizeTimerTask(Object lock) { 602 this.lock = lock; 603 } 604 605 public void run() { 606 607 try { 608 if (addedIdleBeanWork == true) { 609 return; 610 } 611 IdleBeanWork work = new IdleBeanWork(); 612 ContainerWorkPool.addLast(work); 613 addedIdleBeanWork = true; 614 } catch (Exception ex) { 615 _logger.log(Level.WARNING, 616 "[Pool-"+poolName+"]: Cannot perform " 617 + " pool idle bean cleanup", ex); 618 } 619 620 } 621 } 623 } 624 | Popular Tags |