Как остановить 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