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 adapter on MacOS.

The underlying mysql problem was diagnosed in this comment by
@jgloudon:

rails#41176 (comment)

It seems like on MacOS the mysql8 client library is using kqueue which
creates a file descriptor that is not carried into the child process,
allowing for the FD to be re-used.

Co-authored-by: Donal McBreen <[email protected]>
  • Loading branch information
flavorjones and djmb committed Jan 29, 2025
1 parent 454ecdd commit 1709940
Show file tree
Hide file tree
Showing 4 changed files with 29 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*

* PoolConfig no longer keeps a reference to the connection class.

Keeping a reference to the class caused subtle issues when combined with reloading in
Expand Down
4 changes: 4 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,10 @@

module ActiveRecord
module TestDatabases # :nodoc:
ActiveSupport::Testing::Parallelization.before_fork_hook do
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*

* Allow the `#freeze_time` testing helper to accept a date or time argument.

```ruby
Expand Down
13 changes: 13 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,12 @@ def initialize(worker_count)
@url = DRb.start_service("drbunix:", @queue_server).uri
end

def before_fork
Parallelization.before_fork_hooks.each(&:cb)
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 1709940

Please sign in to comment.