Ich möchte in der Lage sein, ein Ruby-Programm zu schreiben, das neu starten kann, ohne seine Socket-Verbindungen fallen zu lassen.Wie mache ich dauerhafte Netzwerk-Sockets unter Unix in Ruby?
0
A
Antwort
1
Dieses Programm ruft die Startseite von Google auf und wenn Sie es dann über CTRL-C SIG_INT übergeben, startet es das Programm neu und liest die Ausgabe der Homepage aus der geöffneten Socket mit Google.
#!/usr/bin/ruby
#simple_connector.rb
require 'socket'
puts "Started."
if ARGV[0] == "restart"
sock = IO.open(ARGV[1].to_i)
puts sock.read
exit
else
sock = TCPSocket.new('google.com', 80)
sock.write("GET /\n")
end
Signal.trap("INT") do
puts "Restarting..."
exec("ruby simple_connector.rb restart #{sock.fileno}")
end
while true
sleep 1
end
0
Sie sprechen über Netzwerk-Sockets, nicht UNIX-Sockets, nehme ich an?
Ich bin nicht sicher, dass dies Ihren Anforderungen entspricht, aber die Art, wie ich es tun würde, ist durch die Trennung der Netzwerk-und Logikteil, nur den Logikteil neu starten, dann verbinden Sie den Logikteil mit dem Netzwerk-Teil.
Beim Neustart: simple_connector.rb: 8: in 'initialisieren ': Bad Dateideskriptor (Errno :: EBADF) von simple_connector.rb: 8: in' open' von simple_connector.rb: 8: in ' ' –
Paul
Von http://www.ruby-doc.org/core-2.1.2/IO.html#method-i-close_on_exec-3D Ruby setzt standardmäßig seit Ruby close-on-exec Flags aller Dateideskriptoren 2.0.0. Sie müssen also nicht selbst festlegen. Das Deaktivieren eines Close-on-Exec-Flags kann außerdem zu einem Dateideskriptorverlust führen, wenn ein anderer Thread fork() und exec() (z. B. über die Methode system) verwendet. Wenn Sie wirklich eine Datei-Deskriptor-Vererbung für den Kind-Prozess benötigen, verwenden Sie das Argument von spawn() wie fd => fd. – ryantm
Was ich getan habe - habe dein Beispiel ohne Änderungen genommen. Könnten Sie ein Beispiel geben, wie man mit der Close-on-Exec-Flagge richtig umgehen kann? Soll ich es einfach auf "True" setzen? – Paul