Skip to content

Can the SDK handle forking a little safer? #377

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions