Mark Thomas wrote:
Phil Steitz wrote:
I just saw this in one of my load tests

[java] java.util.NoSuchElementException
    [java]     at java.util.LinkedList.remove(LinkedList.java:644)
    [java]     at java.util.LinkedList.removeFirst(LinkedList.java:134)
    [java]     at
org.apache.commons.pool.impl.GenericKeyedObjectPool.allocate(GenericKeyedObjectPool.java:1248)

    [java]     at
org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1091)


Looks to me like before entering the permit-dispensing block, we need to
make sure there are latches left to be served in the allocation queue.

Having looked at the code I don't see what you mean. Pretty much all of
allocate() is inside a if (!_allocationQueue.isEmpty()) block. I'm
having trouble seeing how you managed to hit this bug.
Now that I look at it again,  the continue should force a recheck.
IIRC what is going on,  this should happen (so could be unit-tested)
when there are n threads waiting and m instances in one of the pools,
with n < = m < maxActive, so they all get served from the idle pool, but
there is still capacity to create.

Could you elaborate on how you think this occurred?
Now that I look carefully at the code, I don't understand it. The continue after the first block should force a recheck. I got 9 instances of this in a run using commons-performance, with the config below. There are 10 client threads in the test and the 9 exceptions happen right at the beginning of the test.

Platform is mac OS jdk 1.6


 As an aside, did
your test environment include the change in r778357?
Yes.

<configuration>

 <factory>
   <activate-latency>20</activate-latency>
   <destroy-latency>20</destroy-latency>
   <make-latency>40</make-latency>
   <passivate-latency>10</passivate-latency>
   <validate-latency>20</validate-latency>
   <waiter-latency>10</waiter-latency>
 </factory>

 <pool>
   <!-- GenericObjectPool, AbandonedObjectPool, GenericKeyedObjectPool
        StackObjectPool, StackKeyedObjectPool, SoftReferenceObjectPool -->
   <type>GenericKeyedObjectPool</type>
   <max-active>20</max-active>
   <max-idle>5</max-idle>
   <min-idle>1</min-idle>
   <max-wait>-1</max-wait>
   <!-- block, fail, or grow -->
   <exhausted-action>block</exhausted-action>
   <test-on-borrow>true</test-on-borrow>
   <test-on-return>true</test-on-return>
   <time-between-evictions>1000</time-between-evictions>
   <tests-per-eviction>3</tests-per-eviction>
   <idle-timeout>500</idle-timeout>
   <test-while-idle>true</test-while-idle>
   <lifo>true</lifo>
   <!-- Ignored unless pool type a KeyedObjectPool -->
   <max-active-per-key>10</max-active-per-key>
   <sampling-rate>0.1</sampling-rate>
 </pool>

 <!-- Ignored unless pool type is AbandonedObjectPool -->
 <abandoned-config>
   <log-abandoned>false</log-abandoned>
   <remove-abandoned>false</remove-abandoned>
   <abandoned-timeout>-1</abandoned-timeout>
 </abandoned-config>

 <run>
   <iterations>10000</iterations>
   <clients>10</clients>
   <delay-min>20</delay-min>
   <delay-max>100</delay-max>
   <delay-sigma>50</delay-sigma>
   <!-- constant, gaussian, or poisson -->
   <delay-type>poisson</delay-type>
   <!-- none, linear, random -->
   <ramp-type>linear</ramp-type>
   <ramp-period>5000</ramp-period>
   <peak-period>2000</peak-period>
   <trough-period>5000</trough-period>
   <!-- none, oscillating (others?)-->
   <cycle-type>oscillating</cycle-type>
 </run>

</configuration>

Cheers,

Mark



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to