-
Notifications
You must be signed in to change notification settings - Fork 143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrap possible autoloaded models in interlock loading #730
Wrap possible autoloaded models in interlock loading #730
Conversation
Since we don't eager load the models that could be loaded here, we need to wrap these calls in the interlock loading to ensure rails' interlock knows we're loading code in this block, so two threads don't try to autoload at the same time. Fixes timing issues resulting in errors of the variety: ``` LoadError (Unable to autoload constant ManageIQ::Providers::Openstack::StorageManager::CinderManager, expected /home/mmarosi/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/bundler/gems/manageiq-providers-openstack-4481f21d2ebe/app/models/manageiq/providers/openstack/storage_manager/cinder_manager.rb to define it) ``` Fixes ManageIQ/manageiq#19772 In that issue, we had 3 requests happen in 3 threads at the same time: ``` [----] I, [2020-01-28T16:39:43.358817 #6310:3fd8bc363880] INFO -- : Started GET "/ems_cloud/ems_cloud_form_fields/new" for ::1 at 2020-01-28 16:39:43 -0500 [----] I, [2020-01-28T16:39:43.394484 #6310:3fd8bc363754] INFO -- : Started OPTIONS "/api/providers" for ::1 at 2020-01-28 16:39:43 -0500 [----] I, [2020-01-28T16:39:43.690661 #6310:3fd8bc3633a8] INFO -- : Started OPTIONS "/api/providers" for ::1 at 2020-01-28 16:39:43 -0500 ``` We were able to reduce that issue to this recreation script run locally against `rails server`: ```ruby threads = [] threads << Thread.new do `curl -k -L -u admin:smartvm -i -X GET http://localhost:3000/ems_cloud/ems_cloud_form_fields/new` end 2.times do threads << Thread.new do `curl -k -L -u admin:smartvm -i -X OPTIONS http://localhost:3000/api/providers` end end threads.join ```
Note, I don't know how to test this. The method is already tested and testing race conditions leaves me in the pits. 🏎 |
Checked commit jrafanie@6f602dc with ruby 2.5.5, rubocop 0.69.0, haml-lint 0.20.0, and yamllint 1.10.0 |
It feels like we could be playing whack-a-mole with any code that could possibly load a model and could possibly be run from a thread :/ I guess that is relatively rare but I'd be surprised if this didn't also happen somewhere in ui-classic? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 this fixes a definite known issue, we might want to look at more general solutions in the future
…_loading Wrap possible autoloaded models in interlock loading
@miq-bot add-label constant problem |
@agrare Cannot apply the following label because they are not recognized: constant problem |
@agrare These constant problems will probably go away with Rails 6 and zeitwerk |
Since we don't eager load the models that could be loaded here, we need to wrap
these calls in the interlock loading to ensure rails' interlock knows we're
loading code in this block, so two threads don't try to autoload at the same
time.
Fixes timing issues resulting in errors of the variety:
Fixes ManageIQ/manageiq#19772
In that issue, we had 3 requests happen in 3 threads at the same time:
We were able to reduce that issue to this recreation script run locally against
rails server
: