Module: Datadog::Core::Utils::AtForkMonkeyPatch::ProcessMonkeyPatch

Defined in:
lib/datadog/core/utils/at_fork_monkey_patch.rb

Overview

Adds at_fork behavior; see parent module for details.

Instance Method Summary collapse

Instance Method Details

#_fork ⇒ Object

Hook provided by Ruby 3.1+ for observability libraries that want to know about fork, see https://github.com/ruby/ruby/pull/5017 and https://bugs.ruby-lang.org/issues/17795



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/datadog/core/utils/at_fork_monkey_patch.rb', line 206

def _fork
  snapshot = AtForkMonkeyPatch.snapshot_at_fork_blocks
  started = {}
  begin
    AtForkMonkeyPatch.run_at_fork_blocks(:before, snapshot: snapshot, started: started)
    pid = super
  rescue Exception => e # rubocop:disable Lint/RescueException -- re-raised unchanged; we only need to run parent cleanup first
    # The fork or a before-fork callback failed, so no child was
    # created. Restore state set up by any earlier callbacks.
    AtForkMonkeyPatch.send(:run_parent_cleanup, snapshot, started, e)
    raise
  end

  if pid == 0
    AtForkMonkeyPatch.run_at_fork_blocks(:child, snapshot: snapshot)
  else
    AtForkMonkeyPatch.run_at_fork_blocks(:parent, snapshot: snapshot)
  end

  pid
end

#daemon(*args) ⇒ Object

A call to Process.daemon ( https://rubyapi.org/3.1/o/process#method-c-daemon ) forks the current process and keeps executing code in the child process, killing off the parent, thus effectively replacing it. This is not covered by _fork and thus we have some extra code for it.



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/datadog/core/utils/at_fork_monkey_patch.rb', line 231

def daemon(*args)
  snapshot = AtForkMonkeyPatch.snapshot_at_fork_blocks
  started = {}
  begin
    AtForkMonkeyPatch.run_at_fork_blocks(:before, snapshot: snapshot, started: started)
    result = super
  rescue Exception => e # rubocop:disable Lint/RescueException -- re-raised unchanged; we only need to run parent cleanup first
    # `daemon` or a before-fork callback failed, so the original
    # process survives. Restore state set up by earlier callbacks.
    AtForkMonkeyPatch.send(:run_parent_cleanup, snapshot, started, e)
    raise
  end

  # `daemon` kills the parent, so there is no surviving parent to run
  # `:parent` callbacks in; only the child continues executing.
  AtForkMonkeyPatch.run_at_fork_blocks(:child, snapshot: snapshot)

  result
end