Imagine 2 servers, exchanging data every minute, so a good idea is
to just leave a connection open.
But sometimes the net goes strange ways, connection is lost and one
has to reconnect.
That would be done like...
t = Thread.new(....) do |...|
begin
socket = TCPSocket::open(someip,someport)
loop do
...
whatever
...
break if done
end
rescue *ErrorsOnSocket => err # socket errors, see ruby-talk:127627
socket.close # cleanup
sleep 60 # 1 min recovery
retry # reconnect
rescue Exception => ex # general bug
puts "BUG in xyz!"
puts "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
raise
ensure
socket.close
end
end
- Is the cleanup by just doing a socket.close the correct way? Are really
all Ruby internal data structures cleaned up afterwards and we don't
silently leak file descriptors and/or bet on the gc to clean up (soon)?
- Anybody else had the same problem - any (more sophisticated) code to
showcase?
"Martin Pirker" <crf@sbox.tu-graz.ac.at> schrieb im Newsbeitrag news:4203e766$0$8024$3b214f66@aconews.univie.ac.at...
Imagine 2 servers, exchanging data every minute, so a good idea is
to just leave a connection open.
But sometimes the net goes strange ways, connection is lost and one
has to reconnect.
That would be done like...
t = Thread.new(....) do |...|
begin
socket = TCPSocket::open(someip,someport)
loop do
...
whatever
...
break if done
end
rescue *ErrorsOnSocket => err # socket errors, see ruby-talk:127627
socket.close # cleanup
sleep 60 # 1 min recovery
retry # reconnect
rescue Exception => ex # general bug
puts "BUG in xyz!"
puts "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
raise
ensure
socket.close
end
end
- Is the cleanup by just doing a socket.close the correct way? Are really
all Ruby internal data structures cleaned up afterwards and we don't
silently leak file descriptors and/or bet on the gc to clean up (soon)?
- Anybody else had the same problem - any (more sophisticated) code to
showcase?
I'd structure the code a bit differently:
t = Thread.new(....) do |...|
begin
TCPSocket::open(someip,someport) do |socket|
loop do
...
whatever
...
break if done
end
end
rescue *ErrorsOnSocket => err # socket errors, see ruby-talk:127627
# no close because that is done by the block already
sleep 60 # 1 min recovery
retry # reconnect
# I'd put this general code at a much higher level as
# you rethrow anyway:
rescue Exception => ex # general bug
puts "BUG in xyz!"
puts "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
raise
end
end
Now the code is significantly shorter and cleaner (when you remove my comments and the other code :-))