Home > front end >  executing in another thread|RuntimeError
executing in another thread|RuntimeError

Time:12-31

I have something similar in my project

class Raj
  def execute
    5.times do
      Thread.new do
        object = Gopal.new
        object.db_connection
        object.enter_tax_id
      end
    end
  end
end

class Gopal
  def db_connection
    @db = "" # Created db connection here
    @browser = Watir::Browser.new
  end

  def enter_tax_id
    m = Mutex.new
    m.synchronize do
      data = @db_conn.select_one("select max(tax_id_no) from pcmp.tax_identifier")
      @browser.text_field(id: 'something').set 'data'
    end
  end
end

The enter tax id method pulls information from the database and then enters a value into the text field. This thread has an issue since other threads are interacting with it; when multiple threads attempt to execute the same procedure, a 'executing in another thread' error is raised.

CodePudding user response:

To ensure that only one thread at a time can execute a specific section of code, you can use a mutex (short for "mutual exclusion") object. A mutex allows only one thread to acquire a lock on it at a time, and any other threads that try to acquire the lock will block until the lock is released.

In your case, you can use a mutex object to synchronize access to the enter_tax_id method. Here's how you can do it:

class Gopal
  def initialize
    @mutex = Mutex.new
  end

  def db_connection
    @db = "" # Created db connection here
    @browser = Watir::Browser.new
  end

  def enter_tax_id
    @mutex.synchronize do
      data = @db.select_one("select max(tax_id) 1 from table")
      @browser.text_field(id: 'something').set 'data'
    end
  end
end

With this change, when multiple threads try to execute the enter_tax_id method at the same time, only one of them will be able to acquire the lock on the mutex object. The other threads will block until the lock is released. This will ensure that only one thread at a time can execute the code inside the synchronize block.

It's also a good idea to wrap the code inside a begin / rescue block to handle any exceptions that may occur while acquiring the lock or executing the code.

def enter_tax_id
  @mutex.synchronize do
    begin
      data = @db.select_one("select max(tax_id) 1 from table")
      @browser.text_field(id: 'something').set 'data'
    rescue => e
      # Handle exception here
    end
  end
end

I hope this helps! :)

CodePudding user response:

In order to resolve this issue, I used the following strategy:

class Gopal
  @mutex = Mutex.new
  def self.mutex_var
    @mutex
  end
  def db_connection
    @db = "" # Created db connection here
    @browser = Watir::Browser.new
  end

  def enter_tax_id
    Gopal.mutex_var.synchronize do
      data = @db.select_one("select max(tax_id) 1 from table")
      @browser.text_field(id: 'something').set 'data'
    end
  end
end

The mutex variable is now persistent as long as the class is loaded, thus even if another object is instantiated, the mutex variable will still be present and provide protection.

  • Related