Sha256: cd0f2ec5a2f08d9c3caacff4a241a2bc3dd52f6d1b59ac9c94dc3b2a86bb2b91

Contents?: true

Size: 1.64 KB

Versions: 1

Compression:

Stored size: 1.64 KB

Contents

# 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

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
hatetepe-0.6.0.pre.1 lib/hatetepe/client.rb