Class: Lich::InternalAPI::ActiveSessions::Registry
- Inherits:
-
Object
- Object
- Lich::InternalAPI::ActiveSessions::Registry
- Defined in:
- documented/internal_api/active_sessions/registry.rb
Overview
Manages active sessions for the Lich application.
This class is responsible for tracking and managing the state of active sessions.
Class Method Summary collapse
-
.process_alive?(pid) ⇒ Boolean
Checks if a process with the given ID is alive.
Instance Method Summary collapse
-
#empty_snapshot(error: nil) ⇒ Hash
Returns an empty snapshot of sessions, optionally including an error message.
-
#initialize(time_source: -> { Time.now.to_i }, process_checker: self.class.method(:process_alive?)) ⇒ void
constructor
Initializes a new session registry.
-
#remove(pid) ⇒ Boolean
Removes a session by its process ID.
-
#session(pid) ⇒ Hash?
Retrieves a session by its process ID.
-
#snapshot ⇒ Hash
Takes a snapshot of all active sessions.
-
#sweep_dead_sessions! ⇒ void
private
Cleans up sessions that are no longer associated with active processes.
-
#upsert(payload) ⇒ Hash
Inserts or updates a session with the given payload.
Constructor Details
#initialize(time_source: -> { Time.now.to_i }, process_checker: self.class.method(:process_alive?)) ⇒ void
Initializes a new session registry.
19 20 21 22 23 24 |
# File 'documented/internal_api/active_sessions/registry.rb', line 19 def initialize(time_source: -> { Time.now.to_i }, process_checker: self.class.method(:process_alive?)) @time_source = time_source @process_checker = process_checker @sessions = {} @mutex = Mutex.new end |
Class Method Details
.process_alive?(pid) ⇒ Boolean
Checks if a process with the given ID is alive.
124 125 126 127 128 129 130 131 132 133 |
# File 'documented/internal_api/active_sessions/registry.rb', line 124 def self.process_alive?(pid) Process.kill(0, pid.to_i) true rescue Errno::ESRCH false rescue Errno::EPERM true rescue StandardError false end |
Instance Method Details
#empty_snapshot(error: nil) ⇒ Hash
Returns an empty snapshot of sessions, optionally including an error message.
109 110 111 112 113 114 115 116 117 118 |
# File 'documented/internal_api/active_sessions/registry.rb', line 109 def empty_snapshot(error: nil) { source: 'ActiveSessionsAPI', total: 0, connected: 0, detachable: 0, sessions: [], error: error }.compact end |
#remove(pid) ⇒ Boolean
Removes a session by its process ID.
54 55 56 |
# File 'documented/internal_api/active_sessions/registry.rb', line 54 def remove(pid) @mutex.synchronize { !@sessions.delete(pid.to_i).nil? } end |
#session(pid) ⇒ Hash?
Retrieves a session by its process ID.
62 63 64 65 66 67 |
# File 'documented/internal_api/active_sessions/registry.rb', line 62 def session(pid) @mutex.synchronize do record = @sessions[pid.to_i] record ? record.dup : nil end end |
#snapshot ⇒ Hash
Takes a snapshot of all active sessions.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'documented/internal_api/active_sessions/registry.rb', line 72 def snapshot sweep_dead_sessions! now = @time_source.call sessions = @mutex.synchronize { @sessions.values.map(&:dup) } normalized = sessions.sort_by { |session| session[:pid] }.map do |session| session.merge( uptime_seconds: [0, now - session[:started_at].to_i].max, listener: listener_hash(session) ) end { source: 'ActiveSessionsAPI', total: normalized.length, connected: normalized.count { |session| session[:connected] }, detachable: normalized.count { |session| session[:listener] }, sessions: normalized } end |
#sweep_dead_sessions! ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Cleans up sessions that are no longer associated with active processes.
96 97 98 99 100 101 102 103 |
# File 'documented/internal_api/active_sessions/registry.rb', line 96 def sweep_dead_sessions! dead_pids = @mutex.synchronize { @sessions.keys }.reject { |pid| @process_checker.call(pid) } return if dead_pids.empty? @mutex.synchronize do dead_pids.each { |pid| @sessions.delete(pid) } end end |
#upsert(payload) ⇒ Hash
Inserts or updates a session with the given payload.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'documented/internal_api/active_sessions/registry.rb', line 30 def upsert(payload) data = symbolize_keys(payload) pid = Integer(data.fetch(:pid)) now = @time_source.call @mutex.synchronize do current = @sessions[pid] || {} started_at = data[:started_at] || current[:started_at] || now merged = current.merge(mergeable_data(data)) merged[:pid] = pid merged[:started_at] = started_at merged[:last_seen_at] = now merged[:connected] = !!merged[:connected] merged[:hidden] = !!merged[:hidden] @sessions[pid] = merged end session(pid) end |