class Execution
Manages one request and its isolated worker transport.
Definitions
def initialize(endpoint, backend, request, parent)
Initialize an execution.
Signature
-
parameter
endpointTransport::Endpoint The caller endpoint.
-
parameter
backendThread | Ractor The isolated execution context.
-
parameter
requestProtocol::HTTP::Request The original request.
-
parameter
parentAsync::Task The parent task for body forwarding.
Implementation
def initialize(endpoint, backend, request, parent)
@endpoint = endpoint
@backend = backend
@request = request
@parent = parent
@input_task = nil
@input_close_task = nil
@finished = false
@mutex = Mutex.new
end
def control
Signature
-
attribute
Channel The control channel.
Implementation
def control
@endpoint.control
end
def body
Signature
-
attribute
Channel The bidirectional body channel.
Implementation
def body
@endpoint.body
end
def call
Start the worker request and wait for the response head.
Signature
-
returns
Protocol::HTTP::Response The reconstructed response.
Implementation
def call
description = request_description(@request)
control.write(:request, description)
if description[:body]
@input_task = @parent.async do
forward_request_body(@request.body)
end
end
wait_for_response
rescue
cancel($!)
raise
end
def stream_input(stream)
Forward upgraded-stream input after the request body phase.
Signature
-
parameter
streamIO | Object The caller's duplex stream.
-
returns
Async::Task The forwarding task.
Implementation
def stream_input(stream)
@parent.async do
@input_task&.wait
while chunk = read_stream_chunk(stream)
body.write(:stream_chunk, chunk)
end
rescue => error
begin
body.write(:stream_error, RemoteError.dump(error))
rescue ClosedError
# The worker has already finished:
end
ensure
body.close_write
end
end
def close_input
Finish the request direction once the initial request body has been forwarded.
Implementation
def close_input
@input_close_task ||= @parent.async do
@input_task&.wait
body.close_write
end
end
def finish
Finish the execution and release its transport.
Implementation
def finish
return unless transition_to_finished
@input_task&.cancel
@input_close_task&.cancel
@endpoint.close
@backend.join
return nil
end
def cancel(error = nil)
Cancel the execution and release its transport.
Signature
-
parameter
errorException | Nil The cancellation reason.
Implementation
def cancel(error = nil)
return unless transition_to_finished
begin
control.write(:cancel, error && RemoteError.dump(error))
rescue ClosedError
# The worker has already finished:
end
@input_task&.cancel
@input_close_task&.cancel
@request.close(error)
@endpoint.close
return nil
end