2014-11-11 7 views
5

ich dieses einfache Beispiel haben:Eröffnung mehrere Threads mit watir-WebDriver Ergebnisse in 'Connection refused' Fehler

require 'watir-webdriver' 

arr = [] 
sites = [ 
"www.google.com", 
"www.bbc.com", 
"www.cnn.com", 
"www.gmail.com" 
] 

sites.each do |site| 
    arr << Thread.new { 
     b = Watir::Browser.new :chrome 
     b.goto site 
     puts b.url 
     b.close 
    } 
end 
arr.each {|t| t.join} 

Jedes Mal, wenn ich dieses Skript ausführen, bekomme ich

ruby/2.1.0/net/http.rb:879:in `initialize': Connection refused - connect(2) for "127.0.0.1"  port 9517 (Errno::ECONNREFUSED) 

oder eine der Browser schließt unerwartet auf mindestens einem der Threads.

auf der anderen seite, wenn ich sleep 2 am ende jedes schleifenzyklus eingestellt habe, läuft alles reibungslos! Irgendeine Idee warum ist das?

muss etwas im Zusammenhang mit Verständnis sein, wie Threads arbeiten ...

Antwort

5

Sie sind im Grunde eine Racebedingung zwischen den Instanzen des Browsers zu schaffen, um die offen Port watir-WebDriver zu verbinden finden. In diesem Fall erkennt Ihre erste Instanz des Browsers, dass Port 9517 geöffnet ist und eine Verbindung zu ihm herstellt. Da Sie diese Instanzen parallel starten, denkt Ihre zweite Instanz auch, dass Port 9517 geöffnet ist und versucht, eine Verbindung herzustellen. Aber oops, dieser Port wird bereits von der ersten Browser-Instanz verwendet. Deshalb erhalten Sie diesen besonderen Fehler.

Dies erklärt auch, warum die sleep 2 das Problem behebt. Die erste Browserinstanz verbindet sich mit Port 9517 und der Ruhezustand bewirkt, dass die zweite Browserinstanz erkennt, dass 9517 genommen wurde. Sie verbindet dann auf Port 9518.

EDIT

Sie können sehen, wie diese mit Selenium::WebDriver::Chrome::Service#initialize (here) implementiert, die Selenium::WebDriver::PortProber (here) nennt. PortProber bestimmt, wie der Webtreiber bestimmt, welcher Port offen ist.

+0

Danke. Es ist jetzt klar. – MichaelR

+0

So läuft mir eine ähnliche Situation, während ich Websites crawle, und wenn ich zu viele Arbeiter damit werfe, bekomme ich die gleichen Fehler. Gibt es eine Möglichkeit, die anfängliche Verbindung zwischen dem Browser und dem offenen Port zu "schützen", so dass es gewährleistet ist? Langsamer zu sein ist kein Problem, aber Schlafen funktioniert nicht, wenn ich eine riesige Schlange habe und die Zeit, die es braucht, um jeden Job zu erledigen, ist etwas zufällig. Unweigerlich werde ich in dieses Problem fallen .... – kindofgreat

+0

I Ich vermute, ich könnte die Browser geöffnet lassen und zu neuen URLs wechseln, um eine Browser-Instanz für jede URL zu öffnen und zu schließen. Also könnte ich einfach eine bestimmte Anzahl von gleichzeitigen Arbeitern haben, sagen wir 10, und eine lange genug Schlafperiode zwischen diesen 10 haben, um die Dinge zu beginnen, dann sind die Arbeiter Instanzen innerhalb dieser zehn Arbeiter. Nicht ganz so elegant, und ein bisschen komplizierter zu skalieren ... – kindofgreat

Verwandte Themen