Q:

How to give a timeout to an FTP connection

The story behind:
Old script written in ruby 1.8.6 that opens a connection to a ftp and download a configuration file. For a specific client with a windows ftp server the script just hangs. The log stops writing after it opens the connection to the ftp.
It's an old script, it's in ruby and I'm not an expert on it.
What I tried:
So I tried this implementation of a timeout to check if an ftp connection hangs out with this code
Timeout::timeout(5) {
ftp = Net::FTP.new(host,pass,host)
}

The problem is that this isn't working. My guess is that the interpreter stops on opening the connection and the timeout doesn't kill the connection because the interpreter is stuck.
Is it possible that that's the problem?
Could you tell me if there is maybe an alternative solution or if I'm doing something wrong?
More information about it:
This problem happens like once in a while during a month. Like at most twice. The client sent us the ftp server logs but nothing seems wrong on that side. It's just that the FTP hangs there for no reason at all...

A:

I'm not sure if it hangs indefinitely. If not, the best way would be to try and capture the error code when/if it eventually times out. That would give a bit more info for analysis.
Some possible workarounds below.
Timeouts using Process.fork
However in the meantime you might switch to running the FTP task in another process instead, and using timeout on that. This will prevent the ruby global interpreter lock from disabling a possible timeout event like you suspect now.
Something like this:
child = Process.fork do
  # Run the whole FTP task in here...
  ftp = Net::FTP.new(...)
  ...
end

# Timeout handling is done in the parent process
begin
  Timeout::timeout(...) do
    Process.wait(child)
  end 
rescue Timeout::Error
  # Terminate child in case of timeout
  Process.kill("KILL", child)
end

Timeouts using SystemTimer
Another option, since you're running ruby 1.8.6, would be to take a look at SystemTimer, which tries to get around the limitations of the ruby 1.8 Timeout implementation.

