Bear with me on this one...
The pool implementation splits pools into two parts: a provider of new
objects (PoolableObjectFactory) and a pooling behaviour (Pool). This is
a good idea, since this allows separation of content and behaviour: the
same source of poolable objects can be used in a round-robin or stacked
behaviour.
Now, in the current implementation, when the pool runs dry, the active
pooling behaviour can do one of three things: wait, create a new one, or
fail. For example: GenericObjectPool has settings to specify what
behaviour should be used: WHEN_EXHAUSTED_BLOCK, WHEN_EXHAUSTED_GROW,
WHEN_EXHAUSTED_FAIL. Behaviour 1 and 3 are straight forward, but "GROW"
is what I am having problems with.
If we consider GROW behaviour in the current implementation, we can look
at this as two sets inside the pool: one set with actively pooled
objects (those managed by the pool and on this pool the max active, etc
applies) and a second set with so far unpooled objects. The unpooled
objects may not even be instantiated, but theoretically they exists.
When the pool runs dry in GROW behaviour and thus needs a new object,
one object is moved from the unpooled set to the pooled set.
I consider this two-set setup an implementation detail: conceptually the
pool consist of both the actively pooled and unpooled objects, the user
of the pool just request a new object and the pool then must figure out
how to get one and whether or not to juggle between the sets.
Now to my point: in the current implementation this GROW behaviour ONLY
applies to the pooled objects set. An that is IMHO incorrect. What
should happen is: if the pooled objects set has run dry must ALWAYS try
to fetch from the unpooled set, only if the unpooled set also has run
dry, then the pool must decided wheter to BLOCK or WAIT. So it does not
matter if the pooled set ran dry, BOTH set must have run dry in order to
BLOCK or WAIT. Currently the StackedObjectPool goes into a very CPU
consuming busy-waiting loop, and the GenericObjectPool just acceps null
as the value.
As state above, the behaviour should be applied on the combined set, not
just the pooled set. Initially it seems that the behaviour should be
extended to the unpooled set, however if you consider this for a moment
longer, it turns out that the GROW behavour is actually not needed.
Given that the implementation detail of the pooled and unpooled sets is
of no concern to the user of the pool, he has no business in defining if
a pool should GROW. Either the pool is infinite (the factory can endless
continue creating new objects) or it is not. If the pool is infinite,
BLOCK and WAIT are of no concern. If the pool is not infinite and runs
dry, the pool can either WAIT for an object to be returned or FAIL.
There is no GROW.
So, to summarize:
- Pools handle the pooled object set according to specs (max active, min
active, etc).
- Pool always GROW, its is the factory that decides if there is a new
object available or not.
- If the factory says there is no more object (the pool ran dry), then
the pool decides if it will WAIT or FAIL.
- The pool may decide that certain pooled objects are returned to the
unpool set (destroy), when for example the "max active" is overflow.
Now, tell me if I see this wrong or not. As said before: currently the
StackedObjectPool goes CPU mongol on a dry pool and the
GenericObjectPool just returns null. I currently consider both
implementations seriously bugged.
Tom
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]