0

I'm using distributed ruby so that I can save the selenium web-driver object in one script and use the same object in the next script when I run the clients I get an error indicating that #<Drb::DRbConnError: connection closed>.

Has anyone tried this or how do we overcome this issue?

Below are my scripts

Server.rb

require 'drb/drb'

# The URI for the server to connect to
URI="druby://localhost:8787"

# Allows sharing of variables between component runs
class TestScope
  # class variable
  @@variables = {}

  def save_variable(key, value)
      @@variables.store(key, value)
  end

  def get_variable(key)
    return @@variables[key]
  end

  def get_size
    return @@variables.size
  end 
end

# The object that handles requests on the server
FRONT_OBJECT=TestScope.new

DRb.start_service(URI, FRONT_OBJECT, safe_level: 1, verbose: true)
# Wait for the drb server thread to finish before exiting.
DRb.thread.join

Client1.rb

require 'drb/drb'
require 'selenium-webdriver'

# The URI to connect to
SERVER_URI="druby://localhost:8787"

# Start a local DRbServer to handle callbacks.

# Not necessary for this small example, but will be required
# as soon as we pass a non-marshallable object as an argument
# to a dRuby call.

# Note: this must be called at least once per process to take any effect.
# This is particularly important if your application forks.
DRb.start_service

test_scope = DRbObject.new_with_uri(SERVER_URI)

driver = Selenium::WebDriver::Driver.for :firefox
driver.navigate.to "http://www.google.com"

puts "Saving the driver object to the test scope"
test_scope.save_variable('driver', driver)

Client2.rb

require 'drb/drb'
require 'selenium-webdriver'

# The URI to connect to
SERVER_URI="druby://localhost:8787"

# Start a local DRbServer to handle callbacks.

# Not necessary for this small example, but will be required
# as soon as we pass a non-marshallable object as an argument
# to a dRuby call.

# Note: this must be called at least once per process to take any effect.
# This is particularly important if your application forks.
DRb.start_service

test_scope = DRbObject.new_with_uri(SERVER_URI)

puts "Fetching the driver object from the test scope"
driver1 = test_scope.get_variable('driver')
driver1.navigate.to "http://www.yahoo.com"
  • fwiw: I ran these minus the selenium lines and they work for me. – Stephen Crosby Sep 28 '21 at 20:56
  • It looks like we cannot share objects between clients, I observe the following error when I try to do so.. .../ruby-2.3.3-i386/lib/ruby/2.3.0/drb/drb.rb:745:in `rescue in block in open': druby://IITP050:55363 - # (DRb::DRbConnError) – Vishwanath Heddoori Sep 29 '21 at 04:34
  • @StephenCrosby: I feel that this scenario may not be supported. i.e. Sharing objects between clients. if the object is created on the server, then it can be shared between different clients. However, if the object is created by one client, it cannot be used on another. Thoughts? – Vishwanath Heddoori Sep 29 '21 at 10:10
  • Not sure exactly what you're trying to do, but this works for example: # client 1 test_scope.save_variable('driver', 1) => 1 # client 2 test_scope.get_variable('driver') => 1 – Stephen Crosby Sep 29 '21 at 19:03
  • Yes, the integers and the strings get stored but if you try to store the object created on client1 script and use the same in client2 script. It wont work. I confirmed that if we need an object to be shared across various clients, then the definition has to be on the dRb server. Thanks! – Vishwanath Heddoori Sep 30 '21 at 12:18

1 Answers1

0

In order to share an object using DRb, the class must be defined in the dRb server as it allows an object in one Ruby process to invoke methods on an object in another Ruby process on the same or a different machine.

If there is a scenario where one needs to create an object on the dRb client and use that object in other DRb clients. We need to use ruby script runner and define object in the scriptrunner.rb so that multiple clients can use it.