robust socket reconnect?

M

Martin Pirker

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::eek:pen(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? :)


tnx!
Martin
 
R

Robert Klemme

Martin Pirker said:
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::eek:pen(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::eek:pen(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 :))

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,235
Latest member
Top Crypto Podcasts_

Latest Threads

Top