Class: Ask::AppServer::SocketServer
- Inherits:
-
Object
- Object
- Ask::AppServer::SocketServer
- Defined in:
- lib/ask/app_server/socket_server.rb
Overview
Unix-socket transport for the session host: any number of clients can attach to the same sessions (terminal TUI, web console, bots) by connecting to the socket and speaking the canonical session protocol as NDJSON lines.
Each accepted connection gets its own reader thread and a Connection with per-session delivery cursors; the shared protocol engine (Server) routes responses back to the requesting connection and fans out session/event notifications to every subscribed connection.
The socket file is removed on start (stale cleanup) and on stop.
Instance Attribute Summary collapse
-
#protocol ⇒ Object
readonly
Returns the value of attribute protocol.
-
#socket_path ⇒ Object
readonly
Returns the value of attribute socket_path.
Class Method Summary collapse
-
.default_socket_path ⇒ Object
Default socket path: ASK_APP_SERVER_SOCKET env var or ~/.ask-app-server/app-server.sock.
Instance Method Summary collapse
-
#initialize(session_manager: nil, socket_path: nil) ⇒ SocketServer
constructor
A new instance of SocketServer.
-
#running? ⇒ Boolean
Whether the server is running.
-
#start ⇒ Object
Bind the socket and start accepting connections.
-
#stop ⇒ Object
Stop accepting, close all connections, and remove the socket file.
Constructor Details
#initialize(session_manager: nil, socket_path: nil) ⇒ SocketServer
Returns a new instance of SocketServer.
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/ask/app_server/socket_server.rb', line 32 def initialize(session_manager: nil, socket_path: nil) @session_manager = session_manager || SessionManager.new @protocol = Server.new(session_manager: @session_manager) @socket_path = socket_path || self.class.default_socket_path @running = false @listener = nil @acceptor = nil @pusher = nil @logger = Logger.new($stdout, level: ENV["DEBUG"] ? Logger::DEBUG : Logger::WARN) end |
Instance Attribute Details
#protocol ⇒ Object (readonly)
Returns the value of attribute protocol.
28 29 30 |
# File 'lib/ask/app_server/socket_server.rb', line 28 def protocol @protocol end |
#socket_path ⇒ Object (readonly)
Returns the value of attribute socket_path.
28 29 30 |
# File 'lib/ask/app_server/socket_server.rb', line 28 def socket_path @socket_path end |
Class Method Details
.default_socket_path ⇒ Object
Default socket path: ASK_APP_SERVER_SOCKET env var or ~/.ask-app-server/app-server.sock
23 24 25 26 |
# File 'lib/ask/app_server/socket_server.rb', line 23 def self.default_socket_path ENV["ASK_APP_SERVER_SOCKET"] || File.("~/.ask-app-server/app-server.sock") end |
Instance Method Details
#running? ⇒ Boolean
Whether the server is running.
67 68 69 |
# File 'lib/ask/app_server/socket_server.rb', line 67 def running? @running end |
#start ⇒ Object
Bind the socket and start accepting connections. Returns immediately (accept and push run in background threads).
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/ask/app_server/socket_server.rb', line 45 def start @running = true FileUtils.mkdir_p(File.dirname(@socket_path)) FileUtils.rm_f(@socket_path) # stale socket from a previous run @listener = UNIXServer.new(@socket_path) @acceptor = Thread.new { accept_loop } @pusher = Thread.new { pusher_loop } @logger.debug("Socket server listening on #{@socket_path}") self end |
#stop ⇒ Object
Stop accepting, close all connections, and remove the socket file.
57 58 59 60 61 62 63 64 |
# File 'lib/ask/app_server/socket_server.rb', line 57 def stop @running = false @acceptor&.kill rescue nil @pusher&.kill rescue nil @protocol.connections.each { |conn| @protocol.remove_connection(conn) } @listener&.close rescue nil FileUtils.rm_f(@socket_path) rescue nil end |