Handle multiple threads in rails system tests #2287
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I've been working on upgrading rspec tests in a Rails 6.0.4 application using activerecord-oracle_enhanced-adapter v6.0.6. This update demonstrates a bug we encountered and a potential fix. The bug
RuntimeError: executing in another thread
occurs for us after the following:config.use_transactional_fixtures = true
js: true
that contains ajax requests and many interactions with the databaseThe error seems to be a race condition and is difficult to reproduce consistently. After tracing through the code, I think it is related to a feature added in Rails 5.1 to support transactions in system tests: rails/rails#28083
The update made all threads share the same database connection in tests. It uses Monitor and
synchronize
to avoid simultaneous requests from different threads. For example, anything using thelog
method is wrapped with a call to synchronize: https://github.com/rails/rails/blob/v7.0.2.3/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L765It seems that some methods in the oracle adapter are not synchronized. For our project, the errors traced back to the
OracleEnhanced::Connection#describe
method in connection.rb. I was able to fix the error with calls to@lock.synchronize
around any method using describe. Those changes are included in this commit.I'm not deeply familiar with this adapter or ruby threads so this is more of a quick patch and proof-of-concept. I included a test case that usually reproduces the error without the fix. Hopefully someone more familiar with these codebases could take a look.
Thanks!