Skip to content

Can the SDK handle forking a little safer? #377

@dannyfallon

Description

@dannyfallon
require 'bundler/setup'
require 'eppo_client'

config = EppoClient::Config.new(
  'test-api-key-12345',
  log_level: 'warn',
  poll_interval_seconds: 300
)

EppoClient::init(config)
client = EppoClient::Client.instance
client.wait_for_initialization(1)
pid = Process.fork do
  puts "   [Child] Forked successfully"
  sleep 0.1
  exit 0
end

Process.wait(pid)

Output:

1. Initializing Eppo client...
2. Waiting for client initialization...
[2025-12-18T16:40:18Z WARN  eppo] client is not authorized. Check your API key
   Client initialized successfully
3. Forking process...
   [Child] Forked successfully

thread '<unnamed>' (4148640) panicked at /Users/danny/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.44.1/src/runtime/io/driver.rs:208:27:
failed to wake I/O driver: Os { code: 9, kind: Uncategorized, message: "Bad file descriptor" }
stack backtrace:
   0:        0x1218af30c - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::hace9c8f0bf02b28d
   1:        0x1218c3988 - core::fmt::write::haff06c4d5dadd744
   2:        0x1218a453c - std::io::default_write_fmt::h349b76ae705bfbb3
   3:        0x1218ac634 - std::io::Write::write_fmt::h5ddde028a424c999
   4:        0x1218ae190 - std::sys::backtrace::BacktraceLock::print::hd758fb250dfaa015
   5:        0x1218a1d00 - std::panicking::default_hook::{{closure}}::hf0b2effb73fcdb33
   6:        0x1218a1c18 - std::panicking::default_hook::h91163188c82e55a1
   7:        0x1218a1fc4 - std::panicking::panic_with_hook::h9d9f4b295fd289e2
   8:        0x1218ae51c - std::panicking::panic_handler::{{closure}}::h3b0d19ced6899bb8
   9:        0x1218ae29c - std::sys::backtrace::__rust_end_short_backtrace::h2bd50c9fdd80557b
  10:        0x1218a0ba8 - __rustc[834c5bfdc4cd1ec3]::rust_begin_unwind
  11:        0x1218e075c - core::panicking::panic_fmt::h49b99017a75b3cd4
  12:        0x1218e03b4 - core::result::unwrap_failed::h4df382aa3f2dc484
  13:        0x121870358 - <tokio::runtime::scheduler::current_thread::Handle as tokio::util::wake::Wake>::wake::hf642571f9fdd8a6b
  14:        0x1218795c8 - tokio::sync::notify::Notify::notify_waiters::h3f5f579a2f14e82c
  15:        0x1215ea57c - core::ptr::drop_in_place<eppo_core::background::runtime::BackgroundRuntime<tokio::runtime::handle::Handle>>::hafd8a998d77216b2
  16:        0x1215ed874 - magnus::typed_data::DataTypeFunctions::extern_free::hb982338b837a4672
  17:        0x10158e20c - _finalize_deferred_heap_pages
  18:        0x101586014 - _rb_objspace_call_finalizer
  19:        0x1015740f0 - _rb_ec_cleanup
  20:        0x10157420c - _ruby_stop
  21:        0x101639f48 - _rb_f_fork
  22:        0x10172348c - _vm_call_cfunc_with_frame_
  23:        0x101707948 - _vm_exec_core
  24:        0x101705474 - _rb_vm_exec
  25:        0x1015d68ac - _load_iseq_eval
  26:        0x1015d3c1c - _rb_load_internal
  27:        0x1015d57fc - _rb_f_load
  28:        0x10172348c - _vm_call_cfunc_with_frame_
  29:        0x101709ab4 - _vm_exec_core
  30:        0x101705630 - _rb_vm_exec
  31:        0x1015d68ac - _load_iseq_eval
  32:        0x1015d3c1c - _rb_load_internal
  33:        0x1015d57fc - _rb_f_load
  34:        0x10172348c - _vm_call_cfunc_with_frame_
  35:        0x101709ab4 - _vm_exec_core
  36:        0x101705474 - _rb_vm_exec
  37:        0x101574394 - _rb_ec_exec_node
  38:        0x1015742bc - _ruby_run_node
  39:        0x100c9c5d8 - _main
reproduce_panic.rb:14: [BUG] failed to wake I/O driver: Os { code: 9, kind: Uncategorized, message: "Bad file descriptor" }
ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [arm64-darwin25]

This is the most trivial way to reproduce what I consider to be something the SDK should handle without blowing up - have you considered pthread_atfork to shut down Eppo in the event of a fork, or otherwise gracefully handle being forked without crashing Ruby?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions