From: Brian Candler Date: 2003-03-13T06:04:24+09:00 Subject: Re: Threads and DRb 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.