Automatically Discovering DRb Services with Rinda

Credit: James Edward Gray II

Problem

You want to distribute Ruby code across your local network without hardcoding the clients with the addresses of the servers.

Solution

Using Rubys standard Rinda library, its easy to provide zero-configuration networking for clients and services. With Rinda, machines can discover DRb services without providing any addresses. All you need is a running RingServer on the local network:

	#!/usr/bin/ruby
	# rinda_server.rb

	require 
inda/ring # for RingServer
	require 
inda/tuplespace # for TupleSpace

	DRb.start_service

	# Create a TupleSpace to hold named services, and start running.
	Rinda::RingServer.new(Rinda::TupleSpace.new)

	DRb.thread.join

Discussion

The RingServer provides automatic service detection for DRb servers. Any machine on your local network can find the local RingServer without knowing its address. Once its found the server, a client can look up services and use them, not having to know the addresses of the DRb servers that host them.

To find the Rinda server, a client broadcasts a UDP packet asking for the location of a RingServer. All computers on the local network will get this packet, and if a computer is running a RingServer, it will respond with its address. A server can use the RingServer to register services; a client can use the RingServer to look up services.

A RingServer object keeps a service listing in a shared TupleSpace (see Recipe 16.12). Each service has a corresponding tuple with four members:

  • The literal symbol :name, which indicates that the tuple is an entry in the RingServer namespace.
  • The symbol of a Ruby class, indicating the type of the service.
  • The DRbObject shared by the service.
  • A string description of the service.

By retrieving this TupleSpace remotely, you can look up services as tuples and advertise your own services. Lets advertise an object (a simple TupleSpace) tHRough the RingServer under the name :TupleSpace:

	#!/usr/bin/ruby
	# share_a_tuplespace.rb

	require  
rinda/ring # for RingFinger and SimpleRenewer
	require  
rinda/tuplespace # for TupleSpace

	DRb.start_service
	ring_server = Rinda::RingFinger.primary

	# Register our TupleSpace service with the RingServer
	ring_server.write( [:name, :TupleSpace, Rinda::TupleSpace.new, Tuple Space],
	 Rinda::SimpleRenewer.new )
	
	DRb.thread.join

The SimpleRenewer sent in with the namespace listing lets the RingServer periodically check whether the service has expired.

Now we can write clients that find this service by querying the RingServer, without having to know which machine it lives on. All we need to know is the name of the service:

	#!/usr/bin/ruby
	# use_a_tuplespace.rb

	require 
inda/ring # for RingFinger
	require 
inda/tuplespace # for TupleSpaceProxy

	DRb.start_service
	ring_server = Rinda::RingFinger.primary

	# Ask the RingServer for the advertised TupleSpace.
	ts_service = ring_server.read([:name, :TupleSpace, nil, nil])[2]
	tuplespace = Rinda::TupleSpaceProxy.new(ts_service)

	# Now we can use the object normally:
	tuplespace.write([:data, rand(100)])
	puts "Data is #{tuplespace.read([:data, nil]).last}."
	# Data is 91.

These two programs locate each other without needing hardcoded IP addresses. Addresses are still being used under the covers, but the address to the Rinda server is discovered automatically through UDP, and all the other addresses are kept in the Rinda server.

Rinda::RingFinger.primary stores the first RingServer to respond to your Ruby processs UDP packet. If your local network is running more than one RingServer, the first one to respond might not be the one with the service you want, so you should probably only run one RingServer on your network. If you do have more than one RingServer, you can iterate over them with Rinda::RingFinger#each.

See Also

  • Recipe 16.12, "Creating a Shared "Whiteboard"
  • Recipe 16.18, "A Remote-Controlled Jukebox"
  • Eric Hodel has a Rinda::RingServer tutorial at http://segment7.net/projects/ruby/drb/rinda/ringserver.html


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net