Module: Lich::Common::ShutdownCoordinator
- Defined in:
- documented/common/shutdown_coordinator.rb
Overview
Records process shutdown attribution and coarse shutdown progress.
The coordinator is deliberately state-only. It records first-wins shutdown intent and stores the result of any higher-level shutdown runner, but it does not perform teardown work itself.
Defined Under Namespace
Classes: Request
Constant Summary collapse
- ALLOWED_REASONS =
Shutdown reasons accepted by request.
[ :user_exit, :client_disconnect, :game_eof, :game_timeout, :connection_reset, :connection_pipe, :connection_aborted, :game_stream_desync, :unrecoverable_game_thread_error, ].freeze
- CONNECTION_LOSS_REASONS =
Reasons that indicate local frontend loss or remote game connection loss.
[ :client_disconnect, :game_eof, :game_timeout, :connection_reset, :connection_pipe, :connection_aborted, :game_stream_desync, :unrecoverable_game_thread_error, ].freeze
Class Method Summary collapse
-
.begin_best_effort_cleanup(result) ⇒ Object
Stores the in-progress or completed best-effort cleanup result once.
-
.begin_orderly_shutdown(result) ⇒ Object
Stores the in-progress or completed orderly-shutdown result once.
-
.best_effort_cleanup_completed? ⇒ Boolean
Whether best-effort cleanup completed all local steps.
-
.best_effort_cleanup_result ⇒ Object?
Best-effort cleanup result if cleanup started.
-
.client_socket_write_failed? ⇒ Boolean
Whether the client socket write path failed fatally.
-
.client_socket_write_failure ⇒ Exception?
First fatal client socket write failure.
-
.connection_loss? ⇒ Boolean
Whether shutdown began from local or remote connection loss.
-
.current ⇒ Request?
Stored first shutdown request.
-
.orderly_shutdown_completed? ⇒ Boolean
Whether the orderly-shutdown runner completed all steps.
-
.orderly_shutdown_result ⇒ Object?
Orderly-shutdown result if a user-exit runner started.
-
.orderly_user_exit? ⇒ Boolean
Whether shutdown was explicitly requested by user input.
-
.reason ⇒ Symbol?
Stored shutdown reason.
-
.record_client_socket_write_failure(error:, source: :client_socket_write) ⇒ Exception
Records fatal client socket write failure context once.
-
.request(reason:, source:, detail: nil) ⇒ Request
Records shutdown intent once.
-
.requested? ⇒ Boolean
Whether any shutdown request has been recorded.
-
.reset! ⇒ nil
Clears coordinator state for tests and process reinitialization.
-
.scripts_drained? ⇒ Boolean
Whether orderly shutdown or best-effort cleanup fully drained scripts.
-
.vars_saved? ⇒ Boolean
Whether orderly shutdown or best-effort cleanup saved script settings.
Class Method Details
.begin_best_effort_cleanup(result) ⇒ Object
Stores the in-progress or completed best-effort cleanup result once.
114 115 116 117 118 119 120 |
# File 'documented/common/shutdown_coordinator.rb', line 114 def begin_best_effort_cleanup(result) validate_cleanup_result!(result) mutex.synchronize do @best_effort_cleanup_result ||= result end end |
.begin_orderly_shutdown(result) ⇒ Object
Stores the in-progress or completed orderly-shutdown result once.
101 102 103 104 105 106 107 |
# File 'documented/common/shutdown_coordinator.rb', line 101 def begin_orderly_shutdown(result) validate_orderly_shutdown_result!(result) mutex.synchronize do @orderly_shutdown_result ||= result end end |
.best_effort_cleanup_completed? ⇒ Boolean
Returns whether best-effort cleanup completed all local steps.
138 139 140 |
# File 'documented/common/shutdown_coordinator.rb', line 138 def best_effort_cleanup_completed? best_effort_cleanup_result&.completed? end |
.best_effort_cleanup_result ⇒ Object?
Returns best-effort cleanup result if cleanup started.
128 129 130 |
# File 'documented/common/shutdown_coordinator.rb', line 128 def best_effort_cleanup_result mutex.synchronize { @best_effort_cleanup_result } end |
.client_socket_write_failed? ⇒ Boolean
Returns whether the client socket write path failed fatally.
190 191 192 |
# File 'documented/common/shutdown_coordinator.rb', line 190 def client_socket_write_failed? !client_socket_write_failure.nil? end |
.client_socket_write_failure ⇒ Exception?
Returns first fatal client socket write failure.
185 186 187 |
# File 'documented/common/shutdown_coordinator.rb', line 185 def client_socket_write_failure mutex.synchronize { @client_socket_write_failure } end |
.connection_loss? ⇒ Boolean
Returns whether shutdown began from local or remote connection loss.
92 93 94 |
# File 'documented/common/shutdown_coordinator.rb', line 92 def connection_loss? CONNECTION_LOSS_REASONS.include?(reason) end |
.current ⇒ Request?
Returns stored first shutdown request.
77 78 79 |
# File 'documented/common/shutdown_coordinator.rb', line 77 def current mutex.synchronize { @request } end |
.orderly_shutdown_completed? ⇒ Boolean
Returns whether the orderly-shutdown runner completed all steps.
133 134 135 |
# File 'documented/common/shutdown_coordinator.rb', line 133 def orderly_shutdown_completed? orderly_shutdown_result&.completed? end |
.orderly_shutdown_result ⇒ Object?
Returns orderly-shutdown result if a user-exit runner started.
123 124 125 |
# File 'documented/common/shutdown_coordinator.rb', line 123 def orderly_shutdown_result mutex.synchronize { @orderly_shutdown_result } end |
.orderly_user_exit? ⇒ Boolean
Returns whether shutdown was explicitly requested by user input.
87 88 89 |
# File 'documented/common/shutdown_coordinator.rb', line 87 def orderly_user_exit? reason == :user_exit end |
.reason ⇒ Symbol?
Returns stored shutdown reason.
82 83 84 |
# File 'documented/common/shutdown_coordinator.rb', line 82 def reason current&.reason end |
.record_client_socket_write_failure(error:, source: :client_socket_write) ⇒ Exception
Records fatal client socket write failure context once.
If no shutdown request exists yet, the write failure is treated as a client disconnect. If another shutdown reason already exists, first-wins attribution is preserved while the transport failure remains visible.
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'documented/common/shutdown_coordinator.rb', line 161 def record_client_socket_write_failure(error:, source: :client_socket_write) raise ArgumentError, "client socket write failure error must be present" if error.nil? validate_source!(source) stored_error = nil detail = nil request_needed = false mutex.synchronize do stored_error = (@client_socket_write_failure ||= error) detail = "#{stored_error.class}: #{stored_error.}" request_needed = @request.nil? end request( reason: :client_disconnect, source: source, detail: detail ) if request_needed stored_error end |
.request(reason:, source:, detail: nil) ⇒ Request
Records shutdown intent once.
First request wins so later fallout, such as Game.close unblocking the reader thread, does not overwrite the initiating reason.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'documented/common/shutdown_coordinator.rb', line 54 def request(reason:, source:, detail: nil) validate_reason!(reason) validate_source!(source) mutex.synchronize do @request ||= Request.new( reason: reason, source: source.to_s, detail: detail, requested_at: Time.now ).tap do |shutdown_request| log_request(shutdown_request) shutdown_request.freeze end end end |
.requested? ⇒ Boolean
Returns whether any shutdown request has been recorded.
72 73 74 |
# File 'documented/common/shutdown_coordinator.rb', line 72 def requested? !current.nil? end |
.reset! ⇒ nil
Clears coordinator state for tests and process reinitialization.
197 198 199 200 201 202 203 204 |
# File 'documented/common/shutdown_coordinator.rb', line 197 def reset! mutex.synchronize do @request = nil @orderly_shutdown_result = nil @best_effort_cleanup_result = nil @client_socket_write_failure = nil end end |
.scripts_drained? ⇒ Boolean
Returns whether orderly shutdown or best-effort cleanup fully drained scripts.
143 144 145 |
# File 'documented/common/shutdown_coordinator.rb', line 143 def scripts_drained? orderly_shutdown_result&.scripts_drained? || best_effort_cleanup_result&.scripts_drained? end |
.vars_saved? ⇒ Boolean
Returns whether orderly shutdown or best-effort cleanup saved script settings.
148 149 150 |
# File 'documented/common/shutdown_coordinator.rb', line 148 def vars_saved? orderly_shutdown_result&.vars_saved? || best_effort_cleanup_result&.vars_saved? end |