Ruby Net :: FTP超时线程

我试图通过使用线程FTP连接来加速多个FTP下载。 我的问题是我总是有线程挂起。 我正在寻找一种干净的方式来告诉FTP它需要重试ftp事务,或者至少知道FTP连接何时挂起。

在下面的代码中,我正在线程化5/6个单独的FTP连接,其中每个线程都有一个预期下载的文件列表。 当脚本完成时,一些线程挂起并且无法连接。 我使用变量@last_updated来表示上次成功下载的时间。 如果当前时间+ 20秒超过@last_updated,则终止剩余的线程。 有没有更好的办法?

threads = [] max_thread_pool = 5 running_threads = 0 Thread.abort_on_exception = true existing_file_count = 0 files_downloaded = 0 errors = [] missing_on_the_server = [] @last_updated = Time.now if ids.length > 0 ids.each_slice(ids.length / max_thread_pool) do |id_set| threads < %#{p} > #{progress}/#{total} > Got file: #{local_path}" rescue errors < ftp response: #{ftp.last_response}" puts errors.last if ftp.last_response_code.to_i == 550 # Add the missing file to the missing list missing_on_the_server << errors.last.match(/\d{5,}-\d{1,2}\.jpg/)[0] end end else puts "found file: #{local_path}" existing_file_count += 1 end end puts "closing FTP connection #{thread_num}" ftp.close end # close thread end end # If @last_updated has not been updated on the server in over 20 seconds, wait 3 seconds and check again while Time.now < @last_updated + 20 do sleep 3 end # threads are hanging so joining the threads does not work. threads.each { |t| t.kill } 

对我有用的诀窍是使用ruby的Timeout.timeout来确保FTP连接没有挂起。

 begin Timeout.timeout(10) do ftp.getbinaryfile(rmls_path, local_path) end # ... rescue Timeout::Error errors << "#{thread_num}> File download timed out for: #{rmls_path}" puts errors.last rescue errors << "unable to get file > ftp reponse: #{ftp.last_response}" # ... end 

挂起的FTP下载导致我的线程似乎挂起。 既然线程不再挂起,我可以使用更合适的方式来处理线程:

 threads.each { |t| j.join } 

而不是丑陋的:

 # If @last_updated has not been updated on the server in over 20 seconds, wait 3 seconds and check again while Time.now < @last_updated + 20 do sleep 3 end # threads are hanging so joining the threads does not work. threads.each { |t| t.kill }