0

I saw some retry code written like this, it tries to call a service 3 times if some exception is raised, Im trying to understand in a non-MRI multi-threaded server, is this counter thread safe? is it necessary to lock the process using Mutex?

This is how its been called

MyClass.new.my_method

class MyClass
  def my_method
    counter = 3
    begin
      call_some_service_raise_some_exception
    rescue SomeException => e
      retry if counter.positive?
    end
  end
end
user1883793
  • 4,011
  • 11
  • 36
  • 65
  • It's not thread safe unless you use a Mutex or atomic operations. – tadman Feb 26 '18 at 22:23
  • @tadman, thanks, Im trying to understand in what scenario it will cause a race condition, this is how its called MyClass.new.method, can you explain a bit more? because there is one object created, and the counter is inside the method, so how can more than one thread be processing the same method when the switcher happens. appreciated – user1883793 Feb 26 '18 at 22:32
  • 1
    It's not clear if `caller` is a variable or a property on that object, so you'll need to clarify. Keep in mind [`method`](https://ruby-doc.org/core-2.5.0/Object.html#method-i-method) is already reserved as a method name, it gives you information on the method in question, so be careful. – tadman Feb 26 '18 at 22:52

1 Answers1

2

Assuming the variable counter is scoped to that method only, and that there is no funny shenanigans going on with Singleton or any other weird stuff, then yes, that method should be thread safe in its current form.

If, however, counter is an instance variable and you are using an accessor to set it, then that method is not thread safe. You may never encounter the race condition if you're using every MyClass once only, but all it takes is one well-meaning refactoring to reuse MyClass and suddenly you've got a race condition there.

Basically - if your method is self-contained, uses variables scoped to it only, and references no external shared data then it is thread safe by default.

As soon as you use something that could be accessed at the same time by another thread, you have a potential race condition in the making and you should start thinking about synchronising access to the shared resources.

mcfinnigan
  • 11,442
  • 35
  • 28