rosenfeld / rspec_nested_transactions

Nested Transactions around before/after(:all) blocks too besides examples for RSpec
MIT License
37 stars 3 forks source link

ruby 3.0 support #4

Open Hampei opened 1 year ago

Hampei commented 1 year ago

When we switch to ruby 3.0.5 rspec 3.11.0 just hangs before any example that is run using nested_transactions (it set's up the fibre, the fibre yields in run_examples, I can see the process leaving the before :all call, but then nothing.

Using ruby3.1.3 is fails for what I'm assuming is the same reason with:

ThreadError:
       deadlock; lock already owned by another fiber belonging to the same thread
     # /Users/henk/.rvm/gems/ruby-3.1.3/gems/activesupport-6.1.6.1/lib/active_support/concurrency/load_interlock_aware_monitor.rb:17:in `enter'

I've made a minimal test repo that shows the error: https://github.com/Hampei/test_nested_transactions

rosenfeld commented 1 year ago

Hi @Hampei, thanks for creating a test case so that I can reproduce it. I just noticed the notification, sorry. I'll take a look at it, but at first, looking at the logs you pasted above, I'd suspect it may be related to ActiveSupport somehow because I'm using this gem with the latest Ruby without any issues. I'll see if I can understand what's going on in your example.

rosenfeld commented 1 year ago

Ok, I could just confirm that this issue is indeed related to ActiveRecord, as I suspected. I'll have to check the Rails source code to see when fibers are being used, but the reason why I never faced this issue before is because I haven't been using Rails for a few years and ActiveRecord for even more years. Maybe the issue is not supporting newer Ruby, but newer Rails.

I'll see if I can find some time to dig into Rails source to try to figure out the issue, by looking at where fibers are being used in its code. I'll let you know if I find anything.

rosenfeld commented 1 year ago

@Hampei please try a new branch from this repository and let me know if that works for you:

gem 'rspec_nested_transactions', git: 'https://github.com/rosenfeld/rspec_nested_transactions.git', branch: 'separate_thread'

I'll give it some more tests tomorrow in my own projects and if everything works fine then I can release a new version that should support newer ActiveRecord releases.

Thanks.

rosenfeld commented 1 year ago

Hi, I just tested it again my own test suites and it didn't work. The problem is that ActiveRecord uses a lock in the connection and it tries to call try_mon_enter on the monitor, which is a deadlock since the fiber in this gem already has a lock on the current thread. I tried to run the block in a separate thread to avoid this issue and it seemed to work for ActiveRecord (at least the test would run in your example app) but I haven't really tested using a more complete example and I don't have any applications around using ActiveRecord to test it. I haven't investigated yet why my tests are failing on this branch, but this branch is not production-ready yet.

I need more time to see if there's anything I could do in order to support ActiveRecord without breaking the other cases. If you can confirm that this branch looks fine for your suite, I'd leave the :separate_thread option as false by default and explain in the README that this should be set to true for ActiveRecord for it to work. Please let me know once you have the chance to test with this branch if it works with your test suite.