Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby why are class instance variables threadsafe

According to this answer they are, but then the poster states that things work differently in JRuby so I am confused?

I am implementing a multi tenancy solution using class instance variables, so it doesn't matter what Ruby implementation or web server I am using, I need to make sure that data cannot be leaked.

Here is my code:

class Tenant < ActiveRecord::Base

  def self.current_tenant=(tenant)
    @tenant = tenant
  end

  def self.current_tenant
    @tenant
  end
end

What do I need to do to make sure that no matter what happens (changing Ruby implementation, changing web server, new Ruby threading capabilities etc) that my code is thread safe?

like image 423
Lee Avatar asked Jul 29 '14 13:07

Lee


People also ask

Why instance variables are not thread-safe?

It is because, Servlets create only one instance and multiple threads access it. So in that case Instance Variables are not thread safe.

Are instance variables thread-safe in Ruby?

Performing writes/reads on class variables in Ruby is not thread safe. Performing writes/reads on instance variables appears to be thread safe.

What is the difference between class variable and instance variable in Ruby?

What is the difference between class variables and class instance variables? The main difference is the behavior concerning inheritance: class variables are shared between a class and all its subclasses, while class instance variables only belong to one specific class.

Are static variables Threadsafe?

Static variables are not thread safe. Instance variables do not require thread synchronization unless shared among threads. But, static variables are always shared by all the threads in the process. Hence, access to static variable is not thread safe.


1 Answers

Since the tenancy attribute's scope is a request, I would suggest you keep it in the scope of the current thread. Since a request is handled on a single thread, and a thread handles a single request at a time - as long as you always set the tenancy at the beginning of the request you will be fine (for extra security, you might want to un-assign the tenant at the end of the request).

To do this you can use thread local attributes:

class Tenant < ActiveRecord::Base

  def self.current_tenant=(tenant)
    Thread.current[:current_tenant] = tenant
  end

  def self.current_tenant
    Thread.current[:current_tenant]
  end

  def self.clear_current_tenant
    Thread.current[:current_tenant] = nil
  end
end

Since this is using a thread store, you are totally thread safe - each thread is responsible for its own data.

like image 133
Uri Agassi Avatar answered Nov 04 '22 05:11

Uri Agassi