Module: Datadog::Profiling::Ext::Forking

Defined in:
lib/ddtrace/profiling/ext/forking.rb

Overview

Monkey patches Kernel#fork, adding a Kernel#at_fork callback mechanism which is used to restore profiling abilities after the VM forks.

Defined Under Namespace

Modules: Kernel

Class Method Summary collapse

Class Method Details

.apply! ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/ddtrace/profiling/ext/forking.rb', line 12

def self.apply!
  return false unless supported?

  modules = [::Process, ::Kernel]
  # TODO: Ruby < 2.3 doesn't support Binding#receiver.
  #       Remove "else #eval" clause when Ruby < 2.3 support is dropped.
  # NOTE: Modifying the "main" object as we do here is (as far as I know) irreversible. During tests, this change
  #       will stick around even if we otherwise stub `Process` and `Kernel`.
  modules << (TOPLEVEL_BINDING.respond_to?(:receiver) ? TOPLEVEL_BINDING.receiver : TOPLEVEL_BINDING.eval('self'))

  # Patch top-level binding, Kernel, Process.
  # NOTE: We could instead do Kernel.module_eval { def fork; ... end }
  #       however, this method rewrite is more invasive and irreversible.
  #       It could also have collisions with other libraries that patch.
  #       Opt to modify the inheritance of each relevant target instead.
  modules.each do |mod|
    clazz = if mod.class <= Module
              mod.singleton_class
            else
              mod.class
            end

    clazz.prepend(Kernel)
  end
end

.supported? ⇒ Boolean

Returns:

  • (Boolean)


8
9
10
# File 'lib/ddtrace/profiling/ext/forking.rb', line 8

def self.supported?
  Process.respond_to?(:fork)
end