# encoding: utf-8

require 'httpkit'

class Streaming
  def serve(_request, served)
    response = streaming_response
    served.fulfill(response)

    response.body.write('Doing stuff...')
    EM.add_timer(1.0) { response.body.write('More stuff...') }
    EM.add_timer(2.0) { response.body.write('Done!') }
    EM.add_timer(3.0) { response.close }
  end

  private

  # When passing a Body without source, i.e. nil, the response is being kept
  # open for further body chunks.
  def streaming_response
    HTTPkit::Response.new(200,
                          { 'Content-Type' => 'application/octet-stream' },
                          HTTPkit::Body.new)
  end
end

HTTPkit.run do
  address = '127.0.0.1'
  port = HTTPkit.random_port(address)

  HTTPkit::Server.start(address: address, port: port,
                        handlers: [Streaming.new])

  response = HTTPkit.request(:get, "http://#{address}:#{port}")
  # Yields in the Fiber that wrote the chunk, does not block, a.k.a. async.
  # Only yields for future chunks, so we need to explicitly grab past ones.
  puts response.body.chunks
  response.body.closed.on_progress { |chunk| puts chunk }
  # Yields all past and future chunks here, blocks.
  response.body.each { |chunk| puts chunk }
end