On Wed, Mar 12, 2003 at 06:13:46PM +0900, Robert Klemme wrote:
> Things I don't understand:
> 
> Why do you introduce method alive?  Are there conditions under which
> an instance in the pool can die?  If not, you could check sanity when
> you take back an instance and put it into the pool.

Sure, I didn't see much difference in checking sanity before or after the
call though. The instance in the pool itself can't "die", but it could get
into a state where it is easier just to reinitialise it.

Thinking about this again, maybe it makes sense to check sanity only after
an exception has been raised. In that case, the sanity check can be
something reasonably active: e.g.

  def alive?
    @dbh.select_one("select 123 from dual") == 123
  end

If that returns false or an exception, then you can be pretty sure that the
instance has a problem, and it needs re-initialising.

Perhaps even cleverer would be to have a separate thread for putting new
objects into the pool, which means you can rate-limit them to one every
second (say)

> Why do you rededine the set of methods to invoke method_missing?  This
> happens anyway if a method is not implemented.

It doesn't work with DRb. DRb validates method calls explicitly and raises
an exception if they are not present: in drb/drb.rb see
'check_insecure_method', which is called from its own 'method_missing'

So to keep DRb happy, the pool object has to have real methods corresponding
to the ones in the pool objects.

You don't need to list the methods explicitly in the facade in cases where
method_missing is sufficient though.

> Room for improvement:
> 
> I'd change the design in a way that the pool and the facade are
> separated.  This is orthogonal functionality and by extracting the
> pool functionality to another class the design becomes cleaner and
> more modular, hence improved reusability.

Sounds reasonable, how do you suggest: (facade) has-a (pool) ?
I can't think of a good way to express that though.

> The @poolnotempty.wait(@mutex) should be in a loop because with only
> one element in the pool and two threads waiting and both are signalled
> only one can fetch the element and the other has to continue waiting.
> Normally this can't occur in your example

Even if it did, wouldn't that be the correct behaviour? i.e. two threads are
waiting on an empty pool, the cv is signalled when one object is put back
into the pool (which allows one of the waiting threads to take it back out
again). When a second object is put back into the pool the cv will be
signalled again, so the second waiting thread will be woken. Or am I missing
a sequence which causes this to fail?

> You can look at some stuff I put here for threading purposes:
> http://www.rubygarden.org/ruby?MultiThreading

Nice introduction. I found 'ObjectPoolingAndThreading' before, but the code
given assumed that it was spawning fresh threads itself - which doesn't work
where some other process is spawning them.

Cheers,

Brian.