Commit Graph

3 Commits

Author SHA1 Message Date
Jean Boussier
6253874326 Make AbstractAdapter#lock thread local by default
Fix: https://github.com/rails/rails/issues/45994

A semi-common issue since Ruby 3.0.2 is that using a fiber inside
a transaction cause a deadlock:

```ruby
Post.transaction do
 enum =  Enumerator.new do |y|
   y.yield Post.first # stuck
 end
 enum.next
end
```

This is because in https://bugs.ruby-lang.org/issues/17827
Ruby changed Monitor to be owned by the calling Fiber rather than Thread.

And since the Active Record connection pool is per Thread, we end
up in a situation where a Fiber tries to acquire a lock owned by another
fiber with no change to ever resolve.

In https://github.com/rails/rails/pull/46519 We've made that lock optional
as it's only needed for system tests.

Now this PR introduce an alternative lock implementation that behave like Monitor
used to up to Ruby 2.7, and we use this one if `ActiveSupport::IsolatedExecutionState.context`
is a Thread.

If it's a Fiber, we continue to use the implementation derived from the stdlib that is Fiber based.

Co-Authored-By: Maple Ong <maple.develops@gmail.com>
2022-11-23 14:34:40 +01:00
Michael Grosser
203998c916
allow running each test with pure ruby path/to/test.rb
also:
 - makes test dependencies obvious
 - makes tests runnable from within subfolders
2019-12-18 08:49:19 -06:00
Brent Wheeldon
1f9f6f6cfc
Prevent deadlocks with load interlock and DB lock.
This fixes an issue where competing threads deadlock each other.

- Thread A holds the load interlock but is blocked on getting the DB lock
- Thread B holds the DB lock but is blocked on getting the load interlock (for example when there is a `Model.transaction` block that needs to autoload)

This solution allows for dependency loading in other threads while a thread is waiting to acquire the DB lock.

Fixes #31019
2017-11-09 10:46:01 -05:00