You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Phil Steitz <ph...@gmail.com> on 2021/11/14 18:29:15 UTC
[pool] GenericKeyedObjectPool liveness
Looking at POOL-350, I realized that we don't really have a coherent
strategy for handling liveness issues in GKOP. We have been playing
whack-a-mole with problems resulting from two facts about how GKOP works:
1. There are two capacity constraints that bind on individual keyed
pools at different times: total instance count and total per key.
2. Borrowers waiting on keyed pools have no way to know when capacity
exists to create new instances. They have to wait for new instances
to be added to the LinkedBlockingDeques that they are waiting on.
To (partially) work around 2, we added two methods. First, clearOldest,
called by borrowObject when no instances are available for the given
key, creates make capacity by clearing the oldest idle instances across
all of the keyed pools. This makes it less likely that a borrower will
park waiting when overall capacity exists to create an instance under
the desired key. Second, reuseCapacity, called by returnObject and
invalidateObject, tries to create an instance in the most heavily loaded
pool that can add an instance. These both help reduce the incidence of
borrowers waiting when instances could be created to serve them, but
they don't handle all cases and as reported in POOL-350, when there are
a lot of pools, they can cause performance problems.
I think we need to agree on some principles before continuing to patch
liveness issues in GKOP. I hope we can lazily agree with:
0) Users should be able to turn off all optimizations that look across
keyed pools (e.g. reuseCapacity, clearOdest). With these things turned
off, liveness at the individual keyed pool level should work like GOP
(failed validations, invalidate, etc trigger creates under the same key).
1) New borrowers should not take precedence over waiting threads when
capacity exists to create new instances.
2) When configured to globally optimize resources (new config option),
GKOP should decide on each return, invalidate, evict (anything that
passivates or destroys an instance) where to allocate the newly
available capacity. How exactly this works should be configurable.
None of these are true in the code today. Note that 2) means that when
instances are returned, they may not be added to their returning idle
instance pools. That is basically what clearOldest is doing ad hoc only
for new borrowers.
Please anyone interested - especially users - let me know what you think
of 0)-2). If we can agree on them, we can refactor to make the code
consistent with the principles.
Phil
Re: [pool] GenericKeyedObjectPool liveness
Posted by Phil Steitz <ph...@gmail.com>.
On 11/16/21 6:34 AM, Gary Gregory wrote:
> Hi Phil,
>
> My only concern is what exactly is (my emphasis) "When configured to
> *globally* optimize resources (new config option),"?
>
> Is this a static variable somewhere? I hope it would not because I do not
> want to debug a customer set up one day where where one corner of an app needs
> one setting and another a different one.
This would be a suitably named config property - possibly several or an
enum-valued thing. GKOP half does this now in an inconsistent and not
client-fair way. What I mean by "globally optimize resources" is the
kind of thing that clearOldest does - trying to use "idle" capacity in
keyed pools to meet the needs of borrowers waiting on other keys. The
situation you describe above is present now and is the cause of a lot of
the liveness issues reported and hacks like clearOldest and
reuseCapacity. I am not sure how best to set up explicit configs, but
what we have now is neither consistent nor even well-documented. I
would at least like to allow users to turn off attempts at global
optimization entirely. That would certainly improve throughput in GKOPs
that don't care about optimizing across pools.
Phil
>
> TY!
> Gary
>
>
> On Sun, Nov 14, 2021 at 1:29 PM Phil Steitz <ph...@gmail.com> wrote:
>
>> Looking at POOL-350, I realized that we don't really have a coherent
>> strategy for handling liveness issues in GKOP. We have been playing
>> whack-a-mole with problems resulting from two facts about how GKOP works:
>>
>> 1. There are two capacity constraints that bind on individual keyed
>> pools at different times: total instance count and total per key.
>> 2. Borrowers waiting on keyed pools have no way to know when capacity
>> exists to create new instances. They have to wait for new instances
>> to be added to the LinkedBlockingDeques that they are waiting on.
>>
>> To (partially) work around 2, we added two methods. First, clearOldest,
>> called by borrowObject when no instances are available for the given
>> key, creates make capacity by clearing the oldest idle instances across
>> all of the keyed pools. This makes it less likely that a borrower will
>> park waiting when overall capacity exists to create an instance under
>> the desired key. Second, reuseCapacity, called by returnObject and
>> invalidateObject, tries to create an instance in the most heavily loaded
>> pool that can add an instance. These both help reduce the incidence of
>> borrowers waiting when instances could be created to serve them, but
>> they don't handle all cases and as reported in POOL-350, when there are
>> a lot of pools, they can cause performance problems.
>>
>> I think we need to agree on some principles before continuing to patch
>> liveness issues in GKOP. I hope we can lazily agree with:
>>
>> 0) Users should be able to turn off all optimizations that look across
>> keyed pools (e.g. reuseCapacity, clearOdest). With these things turned
>> off, liveness at the individual keyed pool level should work like GOP
>> (failed validations, invalidate, etc trigger creates under the same key).
>> 1) New borrowers should not take precedence over waiting threads when
>> capacity exists to create new instances.
>> 2) When configured to globally optimize resources (new config option),
>> GKOP should decide on each return, invalidate, evict (anything that
>> passivates or destroys an instance) where to allocate the newly
>> available capacity. How exactly this works should be configurable.
>>
>> None of these are true in the code today. Note that 2) means that when
>> instances are returned, they may not be added to their returning idle
>> instance pools. That is basically what clearOldest is doing ad hoc only
>> for new borrowers.
>>
>> Please anyone interested - especially users - let me know what you think
>> of 0)-2). If we can agree on them, we can refactor to make the code
>> consistent with the principles.
>>
>> Phil
>>
>>
>>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org
Re: [pool] GenericKeyedObjectPool liveness
Posted by Gary Gregory <ga...@gmail.com>.
Hi Phil,
My only concern is what exactly is (my emphasis) "When configured to
*globally* optimize resources (new config option),"?
Is this a static variable somewhere? I hope it would not because I do not
want to debug a customer set up one day where one corner of an app needs
one setting and another a different one.
TY!
Gary
On Sun, Nov 14, 2021 at 1:29 PM Phil Steitz <ph...@gmail.com> wrote:
> Looking at POOL-350, I realized that we don't really have a coherent
> strategy for handling liveness issues in GKOP. We have been playing
> whack-a-mole with problems resulting from two facts about how GKOP works:
>
> 1. There are two capacity constraints that bind on individual keyed
> pools at different times: total instance count and total per key.
> 2. Borrowers waiting on keyed pools have no way to know when capacity
> exists to create new instances. They have to wait for new instances
> to be added to the LinkedBlockingDeques that they are waiting on.
>
> To (partially) work around 2, we added two methods. First, clearOldest,
> called by borrowObject when no instances are available for the given
> key, creates make capacity by clearing the oldest idle instances across
> all of the keyed pools. This makes it less likely that a borrower will
> park waiting when overall capacity exists to create an instance under
> the desired key. Second, reuseCapacity, called by returnObject and
> invalidateObject, tries to create an instance in the most heavily loaded
> pool that can add an instance. These both help reduce the incidence of
> borrowers waiting when instances could be created to serve them, but
> they don't handle all cases and as reported in POOL-350, when there are
> a lot of pools, they can cause performance problems.
>
> I think we need to agree on some principles before continuing to patch
> liveness issues in GKOP. I hope we can lazily agree with:
>
> 0) Users should be able to turn off all optimizations that look across
> keyed pools (e.g. reuseCapacity, clearOdest). With these things turned
> off, liveness at the individual keyed pool level should work like GOP
> (failed validations, invalidate, etc trigger creates under the same key).
> 1) New borrowers should not take precedence over waiting threads when
> capacity exists to create new instances.
> 2) When configured to globally optimize resources (new config option),
> GKOP should decide on each return, invalidate, evict (anything that
> passivates or destroys an instance) where to allocate the newly
> available capacity. How exactly this works should be configurable.
>
> None of these are true in the code today. Note that 2) means that when
> instances are returned, they may not be added to their returning idle
> instance pools. That is basically what clearOldest is doing ad hoc only
> for new borrowers.
>
> Please anyone interested - especially users - let me know what you think
> of 0)-2). If we can agree on them, we can refactor to make the code
> consistent with the principles.
>
> Phil
>
>
>