Ruby 3.1: decorate Process._fork if available

Ref: https://bugs.ruby-lang.org/issues/17795

This new API makes it much easier to correctly
intercept forks.
This commit is contained in:
Jean Boussier 2021-10-25 15:27:13 +02:00
parent e5b814c529
commit fe4ead7fc6

@ -2,6 +2,16 @@
module ActiveSupport
module ForkTracker # :nodoc:
module ModernCoreExt
def _fork
pid = super
if pid == 0
ForkTracker.check!
end
pid
end
end
module CoreExt
def fork(...)
if block_given?
@ -28,14 +38,17 @@ module CoreExtPrivate
class << self
def check!
if @pid != Process.pid
new_pid = Process.pid
if @pid != new_pid
@callbacks.each(&:call)
@pid = Process.pid
@pid = new_pid
end
end
def hook!
if Process.respond_to?(:fork)
if Process.respond_to?(:_fork) # Ruby 3.1+
::Process.singleton_class.prepend(ModernCoreExt)
elsif Process.respond_to?(:fork)
::Object.prepend(CoreExtPrivate) if RUBY_VERSION < "3.0"
::Kernel.prepend(CoreExtPrivate)
::Kernel.singleton_class.prepend(CoreExt)