Class: PatientHttp::LifecycleManager

Inherits:
Object
  • Object
show all
Includes:
TimeHelper
Defined in:
lib/patient_http/lifecycle_manager.rb

Overview

Manages the lifecycle state of the Processor.

Handles state transitions and provides predicates for checking the current state. Thread-safe state management using Concurrent::AtomicReference.

Constant Summary collapse

STATES =

Valid processor states

%i[stopped starting running draining stopping].freeze
POLL_INTERVAL =

Polling interval during wait operations

0.001

Instance Method Summary collapse

Methods included from TimeHelper

#monotonic_time, #wall_clock_time

Constructor Details

#initializevoid

Initialize the lifecycle manager.



20
21
22
23
24
25
# File 'lib/patient_http/lifecycle_manager.rb', line 20

def initialize
  @state = Concurrent::AtomicReference.new(:stopped)
  @shutdown_barrier = Concurrent::Event.new
  @reactor_ready = Concurrent::Event.new
  @lock = Mutex.new
end

Instance Method Details

#drain!Boolean

Transition to draining state.

Returns:

  • (Boolean)

    true if transition was successful



94
95
96
97
98
99
100
101
102
# File 'lib/patient_http/lifecycle_manager.rb', line 94

def drain!
  @lock.synchronize do
    return false unless running?

    @state.set(:draining)
  end

  true
end

#draining?Boolean

Check if processor is draining.

Returns:

  • (Boolean)

    true if draining



58
59
60
# File 'lib/patient_http/lifecycle_manager.rb', line 58

def draining?
  state == :draining
end

#reactor_ready!void

This method returns an undefined value.

Signal that the reactor is ready.



133
134
135
# File 'lib/patient_http/lifecycle_manager.rb', line 133

def reactor_ready!
  @reactor_ready.set
end

#running!void

This method returns an undefined value.

Transition to running state.



87
88
89
# File 'lib/patient_http/lifecycle_manager.rb', line 87

def running!
  @state.set(:running)
end

#running?Boolean

Check if processor is running.

Returns:

  • (Boolean)

    true if running



44
45
46
# File 'lib/patient_http/lifecycle_manager.rb', line 44

def running?
  state == :running
end

#shutdown_signaled?Boolean

Check if shutdown has been signaled.

Returns:

  • (Boolean)

    true if shutdown is signaled



147
148
149
# File 'lib/patient_http/lifecycle_manager.rb', line 147

def shutdown_signaled?
  @shutdown_barrier.set?
end

#start!Boolean

Transition to starting state.

Returns:

  • (Boolean)

    true if transition was successful



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/patient_http/lifecycle_manager.rb', line 72

def start!
  @lock.synchronize do
    return false if starting? || running? || stopping?

    @state.set(:starting)
    @shutdown_barrier.reset
    @reactor_ready.reset
  end

  true
end

#starting?Boolean

Check if processor is starting.

Returns:

  • (Boolean)

    true if starting



37
38
39
# File 'lib/patient_http/lifecycle_manager.rb', line 37

def starting?
  state == :starting
end

#stateSymbol

Get the current state.

Returns:

  • (Symbol)

    the current state



30
31
32
# File 'lib/patient_http/lifecycle_manager.rb', line 30

def state
  @state.get
end

#stop!Boolean

Transition to stopping state.

Returns:

  • (Boolean)

    true if transition was successful



107
108
109
110
111
112
113
114
115
116
# File 'lib/patient_http/lifecycle_manager.rb', line 107

def stop!
  @lock.synchronize do
    return false if stopped? || stopping? || starting?

    @state.set(:stopping)
    @shutdown_barrier.set
  end

  true
end

#stopped!void

This method returns an undefined value.

Transition to stopped state.

Also signals the reactor_ready event to unblock any thread waiting in #wait_for_reactor in case the reactor failed before it could signal readiness.



125
126
127
128
# File 'lib/patient_http/lifecycle_manager.rb', line 125

def stopped!
  @state.set(:stopped)
  @reactor_ready.set
end

#stopped?Boolean

Check if processor is stopped.

Returns:

  • (Boolean)

    true if stopped



51
52
53
# File 'lib/patient_http/lifecycle_manager.rb', line 51

def stopped?
  state == :stopped
end

#stopping?Boolean

Check if processor is stopping.

Returns:

  • (Boolean)

    true if stopping



65
66
67
# File 'lib/patient_http/lifecycle_manager.rb', line 65

def stopping?
  state == :stopping
end

#wait_for_condition(timeout: 1) { ... } ⇒ Boolean

Wait for a condition to be met.

Parameters:

  • timeout (Numeric) (defaults to: 1)

    maximum time to wait in seconds

Yields:

  • Block that checks the condition.

Returns:

  • (Boolean)

    true if the condition is met, false if timeout reached



164
165
166
167
168
169
170
171
172
# File 'lib/patient_http/lifecycle_manager.rb', line 164

def wait_for_condition(timeout: 1)
  deadline = monotonic_time + timeout
  while monotonic_time <= deadline
    return true if yield

    sleep(POLL_INTERVAL)
  end
  false
end

#wait_for_reactorvoid

This method returns an undefined value.

Wait for the reactor to be ready.



140
141
142
# File 'lib/patient_http/lifecycle_manager.rb', line 140

def wait_for_reactor
  @reactor_ready.wait
end

#wait_for_running(timeout: 5) ⇒ Boolean

Wait for running state.

Parameters:

  • timeout (Numeric) (defaults to: 5)

    maximum time to wait in seconds

Returns:

  • (Boolean)

    true if running, false if timeout reached



155
156
157
# File 'lib/patient_http/lifecycle_manager.rb', line 155

def wait_for_running(timeout: 5)
  wait_for_condition(timeout: timeout) { running? }
end