commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Phil Steitz <>
Subject Re: [pool] equal instances
Date Sat, 11 Jun 2011 07:44:11 GMT
On 6/10/11 2:38 PM, Mark Thomas wrote:
> On 10/06/2011 22:33, Gary Gregory wrote:
>> On Jun 10, 2011, at 13:47, Mark Thomas <> wrote:
>>> On 09/06/2011 17:47, Phil Steitz wrote:
>>>> I guess I "want it both ways" here.  We already have a use case for
>>>> tracking instances - abandoned connection tracking in DBCP and
>>>> *lots* of requests and practical uses for holding references to
>>>> instances in circulation (mostly from dbcp, but I recall some from
>>>> people managing socket pools or message queue pools).
>>>> I know I flip/flopped on this - initially thinking it was a
>>>> reasonable expectation for factories to produce equals-discernible
>>>> instances.  But I am afraid it will be the source of hard to find
>>>> bugs and I can see the argument on the other side - i.e., a pool
>>>> should be perfectly happy managing indiscernible objects.  I never
>>>> agreed with Leibniz [1] - he he.
>>>> As you pointed out, Mark, 1.x gets around this problem by wrapping /
>>>> unwrapping but that strategy makes identity-checking awkward.  I
>>>> will think about this some more, but a hybrid strategy where
>>>> _allObjects becomes a HashBag (steal from [collections]) used for
>>>> quick checking and we add _allInstances  to hold wrapped instances.
>>>> Could be nonsense, but something along these lines might work.
>>> I've done some testing and under heavy load (10 threads concurrently
>>> creating 1000000 objects each) on a 8 core machine I saw zero
>>> duplicates. With this in mind I think I can do the following for pool 2:
>>> - have calls to PoolableObjectFactory#makeObject() check
>>> System#idenityHashcode() and if a duplicate is detected discard that
>>> object and ask the factory for a new one;
>> With a retry limit to avoid infinite loops.
> Indeed.
>> Is this a feature that should be in a subclass or a toggle? Or do we
>> want it baked it?
> I think it is going to have to be baked in. We have requirements that
> mean we need to track all the objects and we need a scalable solution
> for doing that. However we slice it, that is going to come down to
> hashes and we need to prevent collisions.
> Mark
>> Gary
>>> - use some simple wrapper based on identityHashcode around objects in
>>> the idle object pool and the all objects map
>>> - when an object is returned, use identityHashcode to map it back to the
>>> right object in the all object pool
>>> The requirement this places on PoolableObjectFactories is that they must
>>> produce objects with identityHashcodes that only rarely have collisions.
>>> Since this is under JVM control and my test case shows this is rare, I'm
>>> happy with this.
>>>> The important thing at this point is to agree on what invariants we
>>>> expect [pool] and user factories to maintain.  Since I have already
>>>> changed my mind once on this, and I understand the practical
>>>> arguments in favor of staying with the setup now in trunk (equal
>>>> instances not allowed), I would like to hear what others have to say
>>>> on this.
>>> I think we can have it both ways this time :)
>>> I'll leave this a little while before I do any coding to give folks a
>>> chance to comment.

I have looked at this some more and I think we have two choices,
depending on how much we want to be able to do in terms of
monitoring and instance management.  The simplest solution is to
enable only holding references to instances checked out to clients,
but no tracking of last active times, etc. by the pool itself
(leaving this to the pooled objects themselves, as
AbandonedObjectPool does now).  That could be done with less
ambitious _allObjects and PoolableObject classes.  Actually,
_allObjects would go away, replaced by a List of _circulatingObjects
(like AbandonedObjectPool trace) and PoolableObject would really
only maintain state for idle instances or instances undergoing
lifecycle transitions.

If we want to be able to track things like last active time (as the
trunk code now enables), we need to be able to identify returning
objects uniquely.  That means either we impose the factory
discernibility requirement or use system identity hashcodes.

I would like to keep the monitoring / management options open, so my
vote is for the second option.  I wonder, though, if it makes sense
to keep the base implementation simple (and a little faster) and
restrictive and provide the equals-tolerant functionality in a
subclass or via a config option.


>>> Mark
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail:
>>> For additional commands, e-mail:
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail:
>> For additional commands, e-mail:
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message