/ / Ruby: open provoca un deadlock: ruby, timeout, deadlock, open-uri

Ruby: open provoca un deadlock: ruby, timeout, deadlock, open-uri


Prima di tutto, sono un principiante in Ruby e non ho molta familiarità con il modo in cui Ruby gestisce il codice e lo fa funzionare, quindi mi aspetto che il problema sia che non so come usare correttamente ruby.
Il problema che sto avendo è un punto morto, ma non lo sonousando qualsiasi thread nel mio programma. Inoltre, l'errore si verifica solo una volta ogni 1000-1500 chiamate di funzione, rendendo molto difficile individuare e correggere.
Ecco il messaggio di errore completo quando si verifica il problema:

/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>"

il link al programma completo è qui: https://github.com/Hellfire01/MangaScrap
Il problema si verifica con i 3 diversi metodi che utilizzano aperto, ecco quello che si è bloccato questa volta:

# 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

Ecco il link del file: https://github.com/Hellfire01/MangaScrap/blob/master/sources/utils.rb

Cosa mi piacerebbe sapere:
- Come posso risolvere questo errore?
- Se non riesco a correggere questo errore, ci sono alternative a open-uri che posso usare?

Qualsiasi aiuto è il benvenuto

risposte:

2 per risposta № 1

Non stai rilevando tutte le eccezioni qui. Quando nulla viene specificato dopo rescuesignifica che stai prendendo StandardError che non è alla base della gerarchia delle eccezioni.

Se vuoi assicurarti di averlo preso tutti eccezioni e riprovare aprendo un url (o qualsiasi altro comportamento ti piaccia), quello che vuoi fare è: rescue Exception => error