Class: Terret::OpenRouter::AsyncTransport
- Inherits:
-
Object
- Object
- Terret::OpenRouter::AsyncTransport
- Defined in:
- lib/terret/openrouter/async_transport.rb
Overview
Default transport: streams over async-http on the Fiber scheduler. Sync reuses a running reactor when called from inside one and spins a temporary reactor otherwise, so the adapter blocks correctly in both plain Ruby and Async callers. The connection stays open only for the duration of the block, which is why the contract yields rather than returns: an SSE body must be consumed before the response closes.
Constant Summary collapse
- CONNECT_ERRORS =
[SystemCallError, SocketError, IOError, Async::TimeoutError].freeze
Instance Method Summary collapse
- #call(url:, headers:, body:) ⇒ Object
-
#initialize(timeout: 120) ⇒ AsyncTransport
constructor
A new instance of AsyncTransport.
Constructor Details
#initialize(timeout: 120) ⇒ AsyncTransport
Returns a new instance of AsyncTransport.
18 19 20 |
# File 'lib/terret/openrouter/async_transport.rb', line 18 def initialize(timeout: 120) @timeout = timeout end |
Instance Method Details
#call(url:, headers:, body:) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/terret/openrouter/async_transport.rb', line 22 def call(url:, headers:, body:) Sync do endpoint = Async::HTTP::Endpoint.parse(url, timeout: @timeout) client = Async::HTTP::Client.new(endpoint) begin response = begin client.post(endpoint.path, headers, body) rescue *CONNECT_ERRORS => e raise LLM::RetryableError, "connection failed: #{e.class}: #{e.}" end begin chunks = Enumerator.new { |y| response.body&.each { |c| y << c } } yield response.status, chunks ensure response.close end ensure client.close end end end |