# encoding: utf-8 module Hatetepe class Client include Support::Handlers include Connection::Status attr_reader :config def initialize(config) @config = config @requests = [] setup_connection setup_handlers notify_handlers(:setup) end def request(http_method, uri) request = Request.new(http_method, uri) perform(request).sync end def perform(request) served = Promise.new @requests << [request, served] Fiber.new { perform!(request) }.resume served end def receive(response) request, served = correlate served.fulfill(response) response.closed { finish(request) } notify_handlers(:receive, request, response) end def finish(request) @requests.delete_if { |(req, _)| req == request } notify_handlers(:finish, request) end def close @connection.close end def teardown(reason) @requests.each do |(_, served)| served.reject(reason) if (response = served.value) response.reject_closed(reason) end end end private def perform!(request) notify_handlers(:perform, request) @connection.serialize(request) end def correlate tuple = @requests.detect { |(_, served)| served.pending? } raise ClientError, 'Unable to correlate with request' unless tuple tuple end def setup_connection @connection = EM.connect(@config[:address], @config[:port], Connection::EventMachine) @connection.parse(method(:receive)) @connection.closed.then(method(:teardown)) end end end