Как остановить Rinda кольцевой сервер в ruby

Мне интересно, как я могу остановить кольцевой сервер Rinda, кроме как убить его процесс.

Я проверил ring.rb, поставляемый с моим ruby ​​1.9.3, и обнаружил, что RingServer не хватает API для остановки. Он открывает UDPSocket в initialize(), но он не содержит никакого кода для закрытия этого сокета.

кто-нибудь знает это? спасибо вперед:D

1 ответ

Rinda является частью Distributed Ruby (DRb), поэтому, если бы целью было просто остановить все Rinda и другие службы DRb, вы могли бы сделать:

DRb.stop_service

Если вы используете это, то в вашем сервисном коде Rinda (метод зацикливания) вам нужно спасти DRb::DRbConnError чтобы избежать проблем, пытаясь написать в TupleSpace, по адресу: http://www.ruby-forum.com/topic/97023

Не служба Rinda, но вот простой пример, который я протестировал, который останавливает службу DRb. Он просто использует DRb (без Rinda) в Ruby 1.9.3, слегка модифицированный из приведенного здесь примера: 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

Обновление: Похоже, вы хотите, чтобы обезьяна исправила кольцевой сервер, чтобы закрыть сокет.

Просто создайте способ получить существующий сокет через патч обезьяны:

module Rinda
  class RingServer
    attr_accessor :soc
  end
end

Затем вы можете сохранить экземпляр ringserver в переменной экземпляра, например, @ringserver и использовать его для доступа к сокету, чтобы закрыть его, установить новый сокет и т. д., например

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

Или пропустите attr_accessor и просто добавьте метод в RingServer и вызовите один или два метода на RingServer, чтобы закрыть, открыть и связать сокет.

Чтобы увидеть, как он использует сокет в Ruby 1.9.3: https://github.com/ruby/ruby/blob/v1_9_3_374/lib/rinda/ring.rb

Другие вопросы по тегам