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