Skip to content

Commit

Permalink
Clear AR connections in tests before forking for parallelization
Browse files Browse the repository at this point in the history
Fixes rails#41176 which seems to affect the mysql2 and postgresql adapters.

Occasionally large test suites see something like this:

```
/path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1003:in 'IO#wait_readable': Bad file descriptor (Errno::EBADF)
	from /path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1003:in 'DRb::DRbTCPSocket#alive?'
	from /path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1335:in 'DRb::DRbConn#alive?'
	from /path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1271:in 'block (3 levels) in DRb::DRbConn.make_pool'
	from /path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1269:in 'Array#each'
	from /path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1269:in 'block (2 levels) in DRb::DRbConn.make_pool'
	from /path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1240:in 'block in DRb::ThreadObject#_execute'
	from /path/to/installs/ruby/3.4.1/lib/ruby/3.4.0/monitor.rb:201:in 'Monitor#synchronize'
	from /path/to/installs/ruby/3.4.1/lib/ruby/3.4.0/monitor.rb:201:in 'MonitorMixin#mon_synchronize'
	from /path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1238:in 'DRb::ThreadObject#_execute'
	from /path/to/installs/ruby/3.4.1/lib/ruby/gems/3.4.0/gems/drb-2.2.1/lib/drb/drb.rb:1263:in 'block in DRb::DRbConn.make_pool'
```

Co-authored-by: Donal McBreen <[email protected]>
  • Loading branch information
flavorjones and djmb committed Jan 27, 2025
1 parent d8a3011 commit 97242db
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 0 deletions.
7 changes: 7 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
* Introduce a before-fork hook in `ActiveSupport::Testing::Parallelization` to clear existing
connections, to avoid fork-safety issues with the mysql2 adapter.

Fixes #41776

*Mike Dalessio*, *Donal McBreen*

* Introduce versions formatter for the schema dumper.

It is now possible to override how schema dumper formats versions information inside the
Expand Down
5 changes: 5 additions & 0 deletions activerecord/lib/active_record/test_databases.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

module ActiveRecord
module TestDatabases # :nodoc:
ActiveSupport::Testing::Parallelization.before_fork_hook do
puts "PREFORK: clearing connections"
ActiveRecord::Base.connection_handler.clear_all_connections!
end

ActiveSupport::Testing::Parallelization.after_fork_hook do |i|
create_and_load_schema(i, env_name: ActiveRecord::ConnectionHandling::DEFAULT_ENV.call)
end
Expand Down
5 changes: 5 additions & 0 deletions activesupport/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
* `ActiveSupport::Testing::Parallelization.before_fork_hook` allows declaration of callbacks that
are invoked immediately before forking test workers.

*Mike Dalessio*

* `nil.to_query("key")` now returns `key`.

Previously it would return `key=`, preventing round tripping with `Rack::Utils.parse_nested_query`.
Expand Down
15 changes: 15 additions & 0 deletions activesupport/lib/active_support/testing/parallelization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
module ActiveSupport
module Testing
class Parallelization # :nodoc:
@@before_fork_hooks = []

def self.before_fork_hook(&blk)
@@before_fork_hooks << blk
end

cattr_reader :before_fork_hooks

@@after_fork_hooks = []

def self.after_fork_hook(&blk)
Expand All @@ -32,7 +40,14 @@ def initialize(worker_count)
@url = DRb.start_service("drbunix:", @queue_server).uri
end

def before_fork
Parallelization.before_fork_hooks.each do |cb|
cb.call
end
end

def start
before_fork
@worker_pool = @worker_count.times.map do |worker|
Worker.new(worker, @url).start
end
Expand Down

0 comments on commit 97242db

Please sign in to comment.