From: Jeff Moore Date: 2008-09-10T07:14:50+09:00 Subject: Re: Rinda: random ECONNREFUSED error Andreas Sun wrote: >> I always end up using: >> >> >> finger=Rinda::RingFinger.new([BROADCAST_ADDRESS]) >> >> remote_tuplespace=finger.lookup_ring_any >> >> for the client and service code... >> > > This seems works. Thank you. > > You've got me looked at the RingFinger class. The default broadcast > address list is ['', 'localhost']. It is that '' > that returns uri from other localhost's ports or other machines in my > network, somewhat in a non deterministic order, thus primary is non > deterministic. I tried to find out what this mean and it > seems to bring me to the topic of socket itself, which I'm not familiar > with. > > Now, if the default broadcast address list is reversed, that is > 'localhost' is the first address, then you'll always get the same > primary (from my quick, loosely test). Any idea why it is set up as it > is? > > Thanks again for the solution > -andre I wish I knew for certain...I spent some time looking at it a few months back and couldn't work my way through the sequence of execution with any satisfaction. Through testing I noticed that for my version (Ubuntu 7/Ruby 1.8.6 p36) the instance variable @primary wasn't set unless I forced a call to lookup_ring_any which then set & returned the primary instance (and so the code above). I could never get the @rings array to populate with any secondary servers so I suspect there are some other issues with how broadcasts are being processed, not necessarily within the Rinda code but that may be possible as well. If you look at the RingerFinger initialize method, you see that if you use nil for the broadcast address 'localhost' is used. This lead me to conclude that the default for the class variable @@broadcast_list (i.e. ['', 'localhost']) was likely just a stub meant to be overridden but I'm willing to admit that there may be implications that have escaped me. In practice, I've found that you need to provide a broadcast address if you're actually distributing the services across multiple machines so that finger knows which interface to send the broadcast packets to. This isn't terribly limiting if your machines share a LAN segment or VLAN but it can require a bit more work at the router/switch level if this isn't the case. Also worth noting is line 2 in lib/ring.rb: # Note: Rinda::Ring API is unstable. My current thinking is that may just be easier to write a simple TupleSpace server (or pair) to provide service location and supply their addresses in a config file to all service providers and clients especially since you would appear to need to provide a minimal configuration (the broadcast address) at any rate. I've been testing this approach and it appears to be solid so far... -- Posted via http://www.ruby-forum.com/.