how to stop a Rinda ring server in ruby

338 Views Asked by At

i'm wondering how can i stop a Rinda ring server, besides killing its process.

i'v checked ring.rb shipped with my ruby 1.9.3, and found the RingServer lacks api to stop itself. It opens an UDPSocket in initialize(), but it dose not contain any code to close that socket.

anybody knows it? thanks ahead. :D

1

There are 1 best solutions below

2
Gary S. Weaver On

Rinda is part of Distributed Ruby (DRb), so if the goal were to just stop all Rinda and other DRb services, you could do:

DRb.stop_service

If you use that, then in your Rinda service code (the looping method), you need to rescue DRb::DRbConnError to avoid problems trying to write to the TupleSpace, according to: http://www.ruby-forum.com/topic/97023

Not a Rinda service, but here is a simple example I tested that stops a DRb service. It just uses DRb (no Rinda) in Ruby 1.9.3, modified slightly from the example here: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/drb/rdoc/DRb.html

server.rb

#!/usr/local/bin/ruby
require 'drb/drb'
URI="druby://localhost:8787"
class StopAndGiveTimeServer
  def get_current_time
    DRb.stop_service
    return Time.now
  end
end
FRONT_OBJECT=StopAndGiveTimeServer.new
$SAFE = 1 # disable eval() and friends
DRb.start_service(URI, FRONT_OBJECT)
DRb.thread.join

client.rb

#!/usr/local/bin/ruby
require 'drb/drb'
SERVER_URI="druby://localhost:8787"
DRb.start_service
timeserver = DRbObject.new_with_uri(SERVER_URI)
puts timeserver.get_current_time

Update: It sounds like you want to monkey patch the ring server to close the socket.

Just create a way to get the existing socket via monkey patch:

module Rinda
  class RingServer
    attr_accessor :soc
  end
end

Then you can keep the instance of the ringserver in an instance variable, e.g. @ringserver, and use it to access the socket to close it, set a new socket, etc. e.g.

def bind_to_different_port(port)
  begin
    @ringserver.soc.close
  rescue => e
    puts "#{e.message}\n\t#{e.backtrace.join("\n\t")}"
  end
  @ringserver.soc=UDPSocket.open
  @ringserver.soc.bind('', port)
end

Or skip the attr_accessor and just add a method to RingServer and call a method or two on the RingServer to close, open, bind the socket.

To see how it uses the socket in Ruby 1.9.3: https://github.com/ruby/ruby/blob/v1_9_3_374/lib/rinda/ring.rb