# encoding: utf-8

require 'httpkit'

class Failwhale
  # TODO: Rejecting the served promise on the server side currently has no
  #       effect, except for the response simply not being sent. This has the
  #       potential of mixing up responses, so we should instead just send
  #       a 500 response for every rejected served promise. The same should
  #       happen for errors raised from handlers' #serve.
  def serve(request, served)
    raise if request.uri == '/raise'

    served.fulfill(HTTPkit::Response.new(500))
  end
end

HTTPkit.run do
  address = '127.0.0.1'
  port = HTTPkit.random_port(address)
  uri = "http://#{address}:#{port}"

  HTTPkit.server(uri) do |request, served|
    raise if request.uri == '/raise'
    served.fulfill(HTTPkit::Response.new(500))
  end

  # 5xx responses are just normal responses.
  response = HTTPkit.request(:get, uri)
  p response.status
  # => 500

  # Let's crash the server and make it close the connection.
  begin
    HTTPkit.request(:get, uri + '/raise')
  rescue Promise::Error => ex
    puts ex.backtrace
    # Connection error. Below we see how to find out more.
  end

  client = HTTPkit::Client.start(address: address, port: port)
  request = HTTPkit::Request.new(:get, '/raise')
  served = client.perform(request)

  # Instead of getting fulfilled with a response, we see that the served
  # promise gets rejected. Calling #sync on served would raise the rejection
  # reason, in this case Promise::Error.
  served.wait
  p served.state
  # => :rejected
  p served.reason
  # => Promise::Error if the connection was closed properly (in the TCP sense),
  #    otherwise one of the Errno:: constants.
  p client.closed?
  # => true
end