DEV Community

Discussion on: React Context pattern in Rails

Collapse
 
silva96 profile image
Benjamín Silva

I really liked your approach, very clean. Why do you need the thread safe var?

Collapse
 
thevtm profile image
Vinícius Manjabosco

It was a recommendation from one of my colleagues I believe it's for it to work with Puma and Sidekiq.
Both allow multiple requests/jobs to be executed at the same time in different threads.

Collapse
 
silva96 profile image
Benjamín Silva • Edited

I get it, since this is a class variable, the class is defined at process level (puma worker), each thread (puma thread within the worker) can access the class defined in the process and its variables, so you need it to be thread safe so each thread can define its own value.

Here is the thing. Puma uses thread pools. So a thread might be reutilized from one request to another later. In that case, the class would still have the "threadsafe" var with the old value, and a ContextAlreadyDefinedError would be risen

I suggest you to use a "clean up mechanism" or use a gem like github.com/ElMassimo/request_store...

quoting the gem:

...values can stick around even after the request is over, since some servers have a pool of Threads that they reuse, which can cause bugs.

Thread Thread
 
silva96 profile image
Benjamín Silva • Edited

using that gem you don't even need the with block thing.

you can for example in the controller:

RequestLocals[:request] = request
Enter fullscreen mode Exit fullscreen mode

and then in the model:

if RequestLocals[:request].remote_ip == some_ip
  ...do something
end
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
thevtm profile image
Vinícius Manjabosco

I agree that request_store_rails would be an alternative solution for my problems.

Maybe I'm missing something but the with block is the "clean up mechanism".

    def with(request_value)
      if get.present?
        raise ContextAlreadyDefinedError,
          "Context already defined!"
      end

      begin
        @@request_value.value = request_value
        yield
      ensure
        @@request_value.value = nil # "clean up mechanism"
      end
    end
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
silva96 profile image
Benjamín Silva

totally, my bad!