2016-06-17 10 views
0

Zunächst einmal bin ich ein Anfänger in Ruby und nicht sehr vertraut mit der Art, wie Ruby den Code verwaltet und es funktioniert, so erwarte ich das Problem, ich bin nicht wissen, wie zu verwenden Rubin richtig.
Das Problem, das ich habe, ist ein Deadlock, aber ich verwende keine Threads in meinem Programm. Außerdem tritt der Fehler nur einmal bei 1000 bis 1500 Funktionsaufrufen auf, was es sehr schwierig macht, zu lokalisieren und zu korrigieren.
die komplette Fehlermeldung, wenn das Problem auftritt:
Ruby: open verursacht einen Deadlock

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

der Link zum kompletten Programm finden Sie hier: https://github.com/Hellfire01/MangaScrap
Die Frage zu den 3 verschiedenen Methoden geschieht, die offen zu verwenden, hier ist derjenige, dieses Mal abgestürzt:

# 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 

Hier ist der Link der Datei: https://github.com/Hellfire01/MangaScrap/blob/master/sources/utils.rb

Was ich gerne wissen würde:
- Wie kann ich diesen Fehler beheben?
- Wenn ich diesen Fehler nicht beheben kann, gibt es Alternativen zu Open-Uri, die ich verwenden kann?

Jede Hilfe ist sehr willkommen

+1

FYI, der Grund für Ein Thread-Fehler trotz der Verwendung von Threads ist, dass die Ruby-Timeout-Bibliothek von net/http verwendet wird (wiederum von Open-Uri verwendet), und Timeout verwendet Threads –

+1

Ja, ich habe gesse so viel, aber ich weiß immer noch nicht, wie zu beheben Das Problem:/ –

+1

[curb] (https://github.com/taf2/curb) ist viel angenehmer zu arbeiten als Raw Net :: HTTP. – tadman

Antwort

2

Sie sind nicht alle Ausnahmen hier zu kontrollieren. Wenn nach rescue nichts angegeben ist, bedeutet das, dass Sie StandardError fangen, was nicht die Wurzel der Ausnahmenhierarchie ist.

Wenn Sie sicherstellen möchten, sind Sie alle Ausnahmen zu kontrollieren und versuchen Sie es erneut eine URL zu öffnen (oder was auch immer Verhalten, wenn Sie möchten), was Sie tun möchten, ist: rescue Exception => error