Class: Woods::Console::ConnectionManager
- Inherits:
-
Object
- Object
- Woods::Console::ConnectionManager
- Defined in:
- lib/woods/console/connection_manager.rb
Overview
Manages the bridge process connection via Docker exec, direct spawn, or SSH.
Spawns and manages the bridge process, sends JSON-lines requests, receives responses. Implements heartbeat (30s) and reconnect with exponential backoff (max 5 retries).
Constant Summary collapse
- MAX_RETRIES =
5- HEARTBEAT_INTERVAL =
30
Instance Method Summary collapse
-
#alive? ⇒ Boolean
Check if the bridge process is alive.
-
#connect! ⇒ void
Spawn the bridge process.
-
#disconnect! ⇒ void
Terminate the bridge process.
-
#heartbeat_needed? ⇒ Boolean
Check if a heartbeat is needed (30s since last communication).
-
#initialize(config:) ⇒ ConnectionManager
constructor
A new instance of ConnectionManager.
-
#send_request(request) ⇒ Hash
Send a request to the bridge and read the response.
Constructor Details
#initialize(config:) ⇒ ConnectionManager
Returns a new instance of ConnectionManager.
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/woods/console/connection_manager.rb', line 40 def initialize(config:) @config = config @mode = config['mode'] || 'direct' @command = config['command'] || 'bundle exec rails runner lib/woods/console/bridge.rb' @stdin = nil @stdout = nil @wait_thread = nil @retries = 0 @last_heartbeat = nil end |
Instance Method Details
#alive? ⇒ Boolean
Check if the bridge process is alive.
104 105 106 107 108 |
# File 'lib/woods/console/connection_manager.rb', line 104 def alive? return false unless @wait_thread @wait_thread.alive? end |
#connect! ⇒ void
This method returns an undefined value.
Spawn the bridge process.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/woods/console/connection_manager.rb', line 55 def connect! cmd = build_command if @mode == 'direct' && @config['directory'] Dir.chdir(@config['directory']) do @stdin, @stdout, @wait_thread = Open3.popen2(*cmd) end else @stdin, @stdout, @wait_thread = Open3.popen2(*cmd) end @last_heartbeat = Time.now @retries = 0 rescue StandardError => e raise ConnectionError, "Failed to connect (#{@mode}): #{e.}" end |
#disconnect! ⇒ void
This method returns an undefined value.
Terminate the bridge process.
73 74 75 76 77 78 79 80 |
# File 'lib/woods/console/connection_manager.rb', line 73 def disconnect! @stdin&.close @stdout&.close @wait_thread&.value @stdin = nil @stdout = nil @wait_thread = nil end |
#heartbeat_needed? ⇒ Boolean
Check if a heartbeat is needed (30s since last communication).
113 114 115 116 117 |
# File 'lib/woods/console/connection_manager.rb', line 113 def heartbeat_needed? return false unless @last_heartbeat (Time.now - @last_heartbeat) >= HEARTBEAT_INTERVAL end |
#send_request(request) ⇒ Hash
Send a request to the bridge and read the response.
87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/woods/console/connection_manager.rb', line 87 def send_request(request) ensure_connected! @stdin.puts(JSON.generate(request)) @stdin.flush line = @stdout.gets raise ConnectionError, 'Bridge process closed unexpectedly' unless line @last_heartbeat = Time.now JSON.parse(line) rescue IOError, Errno::EPIPE, Errno::ECONNRESET => e reconnect_or_raise!(e) retry end |