/ / Ruby: open causa um deadlock - ruby, timeout, deadlock, open-uri

Ruby: open causa um deadlock - ruby, timeout, deadlock, open-uri


Em primeiro lugar, sou um iniciante em Ruby e não estou muito familiarizado com a maneira como Ruby gerencia o código e o faz funcionar, então espero que o problema seja eu não saber como usar o Ruby corretamente.
O problema que estou tendo é um impasse, mas nãousando qualquer thread em meu programa. Além disso, o erro ocorre apenas uma vez a cada 1.000 a 1.500 chamadas de função, tornando muito difícil localizar e corrigir.
Esta é a mensagem de erro completa quando o problema ocorre:

/usr/lib/ruby/2.3.0/timeout.rb:95:in `join": No live threads left. Deadlock? (fatal)
from /usr/lib/ruby/2.3.0/timeout.rb:95:in `ensure in block in timeout"
from /usr/lib/ruby/2.3.0/timeout.rb:95:in `block in timeout"
from /usr/lib/ruby/2.3.0/timeout.rb:101:in `timeout"
from /usr/lib/ruby/2.3.0/net/http.rb:878:in `connect"
from /usr/lib/ruby/2.3.0/net/http.rb:863:in `do_start"
from /usr/lib/ruby/2.3.0/net/http.rb:852:in `start"
from /usr/lib/ruby/2.3.0/open-uri.rb:319:in `open_http"
from /usr/lib/ruby/2.3.0/open-uri.rb:737:in `buffer_open"
from /usr/lib/ruby/2.3.0/open-uri.rb:212:in `block in open_loop"
from /usr/lib/ruby/2.3.0/open-uri.rb:210:in `catch"
from /usr/lib/ruby/2.3.0/open-uri.rb:210:in `open_loop"
from /usr/lib/ruby/2.3.0/open-uri.rb:151:in `open_uri"
from /usr/lib/ruby/2.3.0/open-uri.rb:717:in `open"
from /usr/lib/ruby/2.3.0/open-uri.rb:35:in `open"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/utils.rb:85:in `get_pic"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_download.rb:87:in `page_link"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_download.rb:116:in `chapter_link"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_download.rb:142:in `chapter"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_update.rb:57:in `block in MF_manga_missing_chapters"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_update.rb:45:in `reverse_each"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_update.rb:45:in `MF_manga_missing_chapters"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/mangafox/MF_update.rb:80:in `MF_update"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:5:in `update_manga"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:15:in `block in update_all"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:14:in `each"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:14:in `update_all"
from /home/mat/travail_perso/RUBY/MangaScrapp_github/sources/update.rb:22:in `update"
from ./MangaScrap.rb:28:in `<main>"

o link para o programa completo está aqui: https://github.com/Hellfire01/MangaScrap
O problema acontece com os 3 métodos diferentes que usam open, aqui está o que falhou desta vez:

# conect to link and download picture
def get_pic(link)
safe_link = link.gsub(/[[]]/) { "%%%s" % $&.ord.to_s(16) }
tries ||= 20
begin
page = open(safe_link, "User-Agent" => "Ruby/#{RUBY_VERSION}")
rescue URI::InvalidURIError => error
puts "Warning : bad url"
puts link
puts "message is : " + error.message
return nil
rescue => error
if tries > 0
tries -= 1
sleep(0.2)
retry
else
puts "could not get picture " + safe_link + " after " + $nb_tries.to_s + " tries"
puts "message is : " + error.message
return nil
end
end
sleep(0.2)
return page
end

Aqui está o link do arquivo: https://github.com/Hellfire01/MangaScrap/blob/master/sources/utils.rb

O que eu gostaria de saber:
- Como posso corrigir esse erro?
- Se eu não conseguir consertar esse erro, há alternativas para abrir o uri que eu possa usar?

Qualquer ajuda é bem vinda

Respostas:

2 para resposta № 1

Você não está capturando todas as exceções aqui. Quando nada é especificado após rescue, significa que você está pegando StandardError que não está na raiz da hierarquia de exceções.

Se você quiser ter certeza de que está pegando todos exceções e tente abrir novamente um url (ou qualquer comportamento que desejar), o que você deseja fazer é: rescue Exception => error