Class: Wurk::Swarm::ChildBoot
- Inherits:
-
Object
- Object
- Wurk::Swarm::ChildBoot
- Includes:
- Component
- Defined in:
- lib/wurk/swarm/child_boot.rb
Overview
Step 5 of the boot ordering. Runs inside each forked child:
* reset signal traps inherited from the parent,
* reconnect ActiveRecord (if loaded) + open a fresh Redis pool,
* apply the slot's queues + concurrency to the default capsule,
* install child signal handlers (TERM/INT drain, TSTP quiet,
USR2 reopen logs),
* launch the Wurk::Launcher and block until shutdown.
Kept separate from Wurk::Swarm so the parent supervisor stays focused on PID supervision (SRP).
Constant Summary collapse
- CHILD_SIGNALS =
{ 'TERM' => :term, 'INT' => :term, 'TSTP' => :tstp, 'USR2' => :usr2 }.freeze
Constants included from Component
Component::DEFAULT_THREAD_PRIORITY, Component::LEADER_CACHE_TTL_MS, Component::PROCESS_NONCE
Instance Attribute Summary
Attributes included from Component
Instance Method Summary collapse
-
#initialize(config, slot, index, parent_pid: ::Process.ppid, start_quiet: false) ⇒ ChildBoot
constructor
parent_pidis captured by the swarm before it forks (race-free) and threaded through so OrphanGuard can tell "still supervised" from "reparented after the supervisor died". - #run ⇒ Object
Methods included from Component
#default_tag, #fire_event, #handle_exception, #hostname, #identity, #leader?, #logger, #mono_ms, #process_nonce, #real_ms, #redis, #safe_thread, #tid, #watchdog
Constructor Details
#initialize(config, slot, index, parent_pid: ::Process.ppid, start_quiet: false) ⇒ ChildBoot
parent_pid is captured by the swarm before it forks (race-free) and
threaded through so OrphanGuard can tell "still supervised" from
"reparented after the supervisor died". Defaults to the live parent for
the non-swarm callers (tests) that construct a ChildBoot directly.
start_quiet: — the swarm was TSTP-quieted before this child was
forked (respawn/recycle during maintenance); boot the launcher already
quieted so the replacement doesn't resume fetching. Delivered as a
constructor flag, not a post-fork TSTP, because the signal would race
the trap-reset window (default TSTP disposition suspends the child).
35 36 37 38 39 40 41 42 43 |
# File 'lib/wurk/swarm/child_boot.rb', line 35 def initialize(config, slot, index, parent_pid: ::Process.ppid, start_quiet: false) @config = config @slot = slot @index = index @parent_pid = parent_pid @start_quiet = start_quiet @signal_read = nil @signal_write = nil end |
Instance Method Details
#run ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/wurk/swarm/child_boot.rb', line 45 def run reset_inherited_signals reconnect_after_fork Wurk.server = true # :fork runs in each child after our internal AR/Redis reconnect and # before fetching, so apps can reopen sockets / restart threads / # reconnect non-fork-safe libs (Ent §7.4). It never fires in the parent # (which only forks + supervises). Like :startup, the child's forked # copy of the bucket is cleared after dispatch, so siblings fire theirs. fire_event(:fork) apply_slot_to_config # :startup must fire in each worker child before its managers spin up # (Sidekiq contract, reraise: true). The parent supervisor never runs # jobs, so the non-swarm CLI path fires it once per process — for the # swarm, each child fires it here. Its own forked copy of the bucket is # cleared after, so siblings still fire their own. fire_event(:startup, reraise: true) run_launcher exit 0 rescue StandardError, ::Wurk::Shutdown => e @config.logger.error { "swarm child ##{@index} (#{::Process.pid}) crashed: #{e.class}: #{e.}" } exit 1 end |