Getting Started With Ruby dRuby (Drb)
dRuby is a distributed object system for Ruby. It allows an object in one Ruby process to invoke methods on an object in another Ruby process on the same or a different machine.
The Ruby standard library contains the core classes of the dRuby package.
Because it's really hard to find a good example that is NOT the usual "we'll create a tuplespace" one, I decided to put something up.
This example contains 3 conponents:
a) "rinda": this component is the point where the servers announce theit services and the clients receive information about the servers. Servers and clients automatically find the server thanks to UDP broadcasts
b) the server: basically a wrapper arround a "regular" class file that looks for the rinda server, registers the service there once it has found it and provides the interface to the "regular" class file over the network
c) the client:
rinda:
require 'rinda/ring' require 'rinda/tuplespace' # start DRb DRb.start_service # Create a TupleSpace to hold named services, and start running Rinda::RingServer.new Rinda::TupleSpace.new puts "started rinda service" # Wait until the user explicitly kills the server. DRb.thread.join
The Server
require 'drb' require 'rinda/ring' # expand the load path puts "creating the service" # creating my service my_service = SomeClass.new #making it available via DRB (local IP gets detected automatically) drb_wrapper = DRb.start_service(nil, my_service) puts "looking for rinda server" ring_server = Rinda::RingFinger.primary puts "Found it!--> #{ring_server.__drburi}" puts "Registering my service" name = `hostname` #will be checked every 5 seconds renewer = Rinda::SimpleRenewer.new(5) tuple = [:name, my_service, drb_wrapper, "Monitoring Service on #{name}"] ring_server.write(tuple, renewer) puts "Registered and running!" DRb.thread.join
The Client
require 'drb' require 'rinda/ring' puts "Getting available Servers" DRb.start_service ring_server = Rinda::RingFinger.primary services = ring_server.read_all [:name, nil, nil, nil] puts "Services on #{ring_server.__drburi}" puts "Amount: #{services.size}" #create an array of hashes services.map!{|service| {:object => service[1], :uri => service[2].__drburi, :description => service[3]} } #sort them according to IP/URI services.sort{|srv1, srv2| srv1[:uri] <=> srv2[:uri]}
if you want to execute a function, just use it like a regular object:
bla = Drbobject.new(nil,service[:object]) bla.some_method