Class: Igniter::Store::TCPAdapter
- Inherits:
-
Object
- Object
- Igniter::Store::TCPAdapter
- Includes:
- WireProtocol
- Defined in:
- lib/igniter/store/tcp_adapter.rb
Overview
TCP transport adapter for the Igniter Store Open Protocol.
Exposes Protocol::Interpreter over a framed TCP (or Unix socket) connection using the same WireProtocol CRC32 framing as the legacy StoreServer path. Each request frame carries a WireEnvelope JSON object; each response frame carries the WireEnvelope response JSON object.
This is the new envelope dispatch path (default port 7401). The legacy StoreServer path (port 7400) is separate and unchanged.
Usage:
adapter = TCPAdapter.new(interpreter: interpreter, port: 7401)
adapter.start_async
adapter.wait_until_ready
adapter.stop
Constant Summary
Constants included from WireProtocol
WireProtocol::FRAME_CRC_SIZE, WireProtocol::FRAME_HEADER_SIZE
Instance Method Summary collapse
- #bind_address ⇒ Object
-
#initialize(interpreter:, port: 7401, host: "127.0.0.1", transport: :tcp) ⇒ TCPAdapter
constructor
A new instance of TCPAdapter.
-
#start ⇒ Object
Runs the accept loop in the current thread (blocks until #stop).
-
#start_async ⇒ Object
Starts the accept loop in a background thread.
- #stop ⇒ Object
-
#wait_until_ready(timeout: 2) ⇒ Object
Blocks until the server socket is bound and ready.
Methods included from WireProtocol
Constructor Details
#initialize(interpreter:, port: 7401, host: "127.0.0.1", transport: :tcp) ⇒ TCPAdapter
Returns a new instance of TCPAdapter.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/igniter/store/tcp_adapter.rb', line 27 def initialize(interpreter:, port: 7401, host: "127.0.0.1", transport: :tcp) @interpreter = interpreter @port = port @host = host @transport = transport @stopped = false @threads = [] @threads_mutex = Mutex.new @ready_mutex = Mutex.new @ready_cond = ConditionVariable.new @ready = false @server = build_server # Socket is bound during initialize — signal ready immediately so that # wait_until_ready is race-free even before start is called. signal_ready end |
Instance Method Details
#bind_address ⇒ Object
88 89 90 |
# File 'lib/igniter/store/tcp_adapter.rb', line 88 def bind_address @transport == :unix ? @host : "#{@host}:#{@port}" end |
#start ⇒ Object
Runs the accept loop in the current thread (blocks until #stop).
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/igniter/store/tcp_adapter.rb', line 45 def start until @stopped begin socket = @server.accept rescue IOError, Errno::EBADF break end t = Thread.new(socket) { |s| handle_client(s) } @threads_mutex.synchronize { @threads << t } end end |
#start_async ⇒ Object
Starts the accept loop in a background thread. Returns self.
58 59 60 61 62 63 64 65 |
# File 'lib/igniter/store/tcp_adapter.rb', line 58 def start_async @thread = Thread.new do Thread.current.abort_on_exception = false start end wait_until_ready self end |
#stop ⇒ Object
80 81 82 83 84 85 86 |
# File 'lib/igniter/store/tcp_adapter.rb', line 80 def stop @stopped = true @server&.close rescue nil @thread&.join(2) rescue nil @threads_mutex.synchronize { @threads.each { |t| t.join(1) rescue nil } } self end |
#wait_until_ready(timeout: 2) ⇒ Object
Blocks until the server socket is bound and ready.
68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/igniter/store/tcp_adapter.rb', line 68 def wait_until_ready(timeout: 2) @ready_mutex.synchronize do deadline = Time.now + timeout until @ready remaining = deadline - Time.now raise "TCPAdapter did not become ready within #{timeout}s" if remaining <= 0 @ready_cond.wait(@ready_mutex, remaining) end end self end |