class Goliath::RackProxy::RackCall

Allows “curry-calling” the Rack application, resuming the call as we're receiving more request body data.

Public Class Methods

new(app, env, rewindable_input: true) click to toggle source
# File lib/goliath/rack_proxy.rb, line 72
def initialize(app, env, rewindable_input: true)
  @app              = app
  @env              = env
  @rewindable_input = rewindable_input
end

Public Instance Methods

resume(data = nil, on_response: nil) click to toggle source
# File lib/goliath/rack_proxy.rb, line 78
def resume(data = nil, on_response: nil)
  if fiber.alive?
    response = fiber.resume(data)
    on_response.call(response) if response && on_response
  end
end

Private Instance Methods

fiber() click to toggle source

Calls the Rack application inside a Fiber, using the RackInput object as the request body. When the Rack application wants to read request body data that hasn't been received yet, the execution is automatically paused so that the event loop can go on.

# File lib/goliath/rack_proxy.rb, line 91
def fiber
  @fiber ||= Fiber.new do
    rack_input = RackInput.new(rewindable: @rewindable_input) { Fiber.yield }

    response = @app.call @env.merge(
      "rack.input"     => rack_input,
      "async.callback" => nil, # prevent Roda/Sinatra from calling EventMachine while streaming the response
    )

    rack_input.close

    response
  end
end