8

In my RoR app, I'm writing an API in which I need to call multiple upstream APIs, so I'm planning to call them in parallel to save time. I want to follow best practices when implementing multi-threaded logic in ruby-on-rails applications.

The RoR guide states clearly that we need to wrap our code but it didn't explain why it is important.

From ruby-on-rails guidelines:

Each thread should be wrapped before it runs application code, so if your application manually delegates work to other threads, such as via Thread.new or Concurrent Ruby features that use thread pools, you should immediately wrap the block

  • My App runs Rails version 4.
  • Number of upstream API calls in a single request ranges from 3 to 30
  • I checked out this similar SO post, but it doesn't mention anything about wrapping threaded code.
vaibhavatul47
  • 2,766
  • 4
  • 29
  • 42
  • 2
    Read [this](https://bibwild.wordpress.com/2016/12/29/concurrency-in-rails-5-0/) for more info. I'm 99% sure that the feature you're reading about is for Rails >= 5 only, not Rails 4. What it boils down to is: using that wrapper takes care of a lot of issues you might run into when calling `Thread.new` in the `development` environment, but those issues likely won't appear at all in `production` given the default configuration for that environment. – anothermh Nov 06 '19 at 16:47
  • 4
    Keep reading: ["The Executor will put the current thread into running mode in the Load Interlock. This operation will block temporarily if another thread is currently either autoloading a constant or unloading/reloading the application."](https://guides.rubyonrails.org/threading_and_code_execution.html#executor-concurrency). The implication is that some of the global behavior needs help to be thread-safe, which (as @anothermh notes) may not be an issue in production. – mu is too short Nov 06 '19 at 17:55

2 Answers2

1

Thread wrapping is crucial to ensuring that the application can utilize the server's full potential. Without wrapping, threads can interact with one another and receive memory from an internal pool in ways that ultimately slow down performance. Wrapping ensures that each thread is held responsible when it is created and that resources are only requested when necessary. By doing this, efficiency is increased and problems like memory leaks and unexpected interactions between threads are avoided.

Hubert Jakubiak
  • 853
  • 8
  • 19
0

Wrapping the thread on the executor makes sure that you won't have any problem with unloaded constants... You won't see errors like

Unable to autoload constant User, expected ../user.rb to define it (LoadError).
CHAVDA MEET
  • 777
  • 8
  • 14