I want my program to be constantly checking if an element is presenting (always checking for it), however when I try to check the HTML in another different thread I get read_nonblock error and/or a stream closed error ( couldn't find explanation in the internet) so I created this program to verify wtf is happening.
require 'watir'
require 'thread'
profile = Selenium::WebDriver::Firefox::Profile.new
profile['permissions.default.image'] = 2
profile['media.autoplay.enabled'] = false
browser = Watir::Browser.new :firefox, profile: profile
threads = Array.new
threads[0] = Thread.new do
loop do
begin
sleep(3)
puts browser.url
browser.goto("https://monip.org")
rescue
puts "thread 1 encountered an error"
end
end
end
threads[1] = Thread.new do
loop do
begin
if browser.url == "https://monip.org"
puts "hi"
end
rescue
puts "thread 2 encountered an error"
end
end
end
threads.each do |e|
e.join
end
I'd get
thread 1 encountered an error
thread 2 encountered an error
thread 2 encountered an error
thread 1 encountered an error
thread 1 encountered an error
about:blank
thread 2 encountered an error
thread 1 encountered an error
thread 1 encountered an error
thread 1 encountered an error
thread 2 encountered an error
thread 1 encountered an error
thread 2 encountered an error
of course any other solution would be nice, this is what I though of but couldn't write it with code .. Is it possible to make the program wait/check if it can control/communicate with the browser for a certain set of seconds. or reserve the browser for itself for a period of time I'd use "sleep". or allow the 2 threads to control the browser at once.
EDIT: I was able to get the desired behaviour by using "mutex"
this is how the code would look
require 'watir'
require 'thread'
profile = Selenium::WebDriver::Firefox::Profile.new
profile['permissions.default.image'] = 2
profile['media.autoplay.enabled'] = false
mutex = Mutex.new
browser = Watir::Browser.new :firefox, profile: profile
threads = Array.new
threads[0] = Thread.new do
loop do
sleep(0.1)
begin
mutex.synchronize do
puts "#{Time.now.ctime} #{browser.url}"
browser.goto("https://monip.org")
end
rescue
puts "#{Time.now.ctime} thread 1 encountered an error"
end
end
end
threads[1] = Thread.new do
loop do
sleep(0.1)
begin
mutex.synchronize do
if browser.url == "https://monip.org/" || browser.url == "https://monip.org"
puts "#{Time.now.ctime} hi"
end
end
rescue
puts "#{Time.now.ctime} thread 2 encountered an error"
end
end
end
threads[0].join
threads[1].join
the output is
Fri Jan 5 13:49:36 2018 about:blank
Fri Jan 5 13:49:37 2018 hi
Fri Jan 5 13:49:37 2018 https://monip.org/
Fri Jan 5 13:49:37 2018 hi
Fri Jan 5 13:49:37 2018 https://monip.org/
Fri Jan 5 13:49:37 2018 hi
Fri Jan 5 13:49:37 2018 https://monip.org/
Fri Jan 5 13:49:38 2018 hi
Fri Jan 5 13:49:38 2018 https://monip.org/
Fri Jan 5 13:49:38 2018 hi
Fri Jan 5 13:49:38 2018 https://monip.org/
Fri Jan 5 13:49:38 2018 hi
Fri Jan 5 13:49:38 2018 https://monip.org/
Fri Jan 5 13:49:38 2018 hi
Fri Jan 5 13:49:38 2018 https://monip.org/
Fri Jan 5 13:49:39 2018 hi
Fri Jan 5 13:49:39 2018 https://monip.org/
Fri Jan 5 13:49:39 2018 hi
Fri Jan 5 13:49:39 2018 https://monip.org/
Fri Jan 5 13:49:39 2018 hi
Fri Jan 5 13:49:39 2018 https://monip.org/
Fri Jan 5 13:49:40 2018 hi
Fri Jan 5 13:49:40 2018 https://monip.org/
Fri Jan 5 13:49:40 2018 hi
Fri Jan 5 13:49:40 2018 https://monip.org/
as you can see in the timestamps, we are checking constantly and respectively without raising any error
You simply can't let them both use the browser at the same time.
Problem 1: Your script will never output "hi" because the url is actually "https://monip.org/", not "https://monip.org".
Problem 2: You may want to be "constantly" checking for this element (I assume some sort of dialog or something), because once it appears, you'll need to do something. But by checking constantly, you are essentially ensuring that the thread that is actually doing things is going to be interrupted. Most likely checking once every second (or even 2-10 seconds) will be more than enough.
Problem 3: As I stated at the beginning, you can't let them use the browser at the same time. You'll need to implement some sort of locking procedure to prevent this behavior.