class Ractor::Server::Request
Attributes
info[R]
initiating_ractor[R]
response_to[R]
sync[R]
Public Class Methods
message(*args, **options)
click to toggle source
# File lib/ractor/server/request.rb, line 94 def message(*args, **options) request = new(**options) [request, *args].freeze end
new(response_to: nil, sync: nil, info: nil)
click to toggle source
# File lib/ractor/server/request.rb, line 14 def initialize(response_to: nil, sync: nil, info: nil) @response_to = response_to @initiating_ractor = Ractor.current @sync = sync @info = info # for display only enforce_valid_sync! Ractor.make_shareable(self) end
pending_receive_conclusion()
click to toggle source
# File lib/ractor/server/request.rb, line 103 def pending_receive_conclusion ::Ractor.current[:ractor_server_request_receive_conclusion] ||= ::ObjectSpace::WeakMap.new end
pending_send_conclusion()
click to toggle source
# File lib/ractor/server/request.rb, line 99 def pending_send_conclusion ::Ractor.current[:ractor_server_request_send_conclusion] ||= ::ObjectSpace::WeakMap.new end
receive_if(&block)
click to toggle source
# File lib/ractor/server/request.rb, line 107 def receive_if(&block) message = ::Ractor.receive_if(&block) rq, = message rq.sync_after_receiving debug(:receive) { "Received #{message}" } message end
send(ractor, *arguments, move: false, **options)
click to toggle source
# File lib/ractor/server/request.rb, line 115 def send(ractor, *arguments, move: false, **options) message = Request.message(*arguments, **options) request, = message request.enforce_sync_when_sending! debug(:send) { "Sending #{message}" } ractor.send(message, move: move) request end
Public Instance Methods
===(message)
click to toggle source
Match any request that is a response to the receiver (or an array message starting with such)
# File lib/ractor/server/request.rb, line 24 def ===(message) request, = message match = request.is_a?(Request) && self == request.response_to debug(:receive) { "Request #{request.inspect} does not match #{self}" } unless match match end
enforce_sync_when_sending!()
click to toggle source
@api private
# File lib/ractor/server/request.rb, line 157 def enforce_sync_when_sending! # Only dynamic checks are done here; static validity checked in constructor case sync when :conclude, :interrupt registry = Request.pending_send_conclusion raise Talk::Error, "Request #{response_to} already answered" unless registry[response_to] registry[response_to] = false Request.pending_receive_conclusion[response_to.response_to] = false if sync == :interrupt when :ask, :converse Request.pending_receive_conclusion[self] = true end end
inspect()
click to toggle source
# File lib/ractor/server/request.rb, line 76 def inspect [ '<Request', info, ("for: #{response_to}" if response_to), ("sync: #{sync}" if sync), "from: #{ractor_name(initiating_ractor)}>", ].compact.join(' ') end
Also aliased as: to_s
receive()
click to toggle source
# File lib/ractor/server/request.rb, line 71 def receive enforce_sync_when_receiving! unwrap(Request.receive_if(&self)) end
respond_to_ractor()
click to toggle source
# File lib/ractor/server/request.rb, line 87 def respond_to_ractor response_to.initiating_ractor end
send(*args, **options)
click to toggle source
@return [Request]
# File lib/ractor/server/request.rb, line 39 def send(*args, **options) Request.send(initiating_ractor, *args, **options, response_to: self) end
send_exception(exception)
click to toggle source
# File lib/ractor/server/request.rb, line 67 def send_exception(exception) send(WrappedException.new(exception), sync: sync && :conclude) end
sync_after_receiving()
click to toggle source
@api private
# File lib/ractor/server/request.rb, line 172 def sync_after_receiving # Only dynamic checks are done here; static validity checked in constructor case sync when :conclude, :interrupt Request.pending_receive_conclusion[response_to] = false Request.pending_send_conclusion[response_to.response_to] = false if sync == :interrupt when :ask, :converse Request.pending_send_conclusion[self] = true end end
to_proc()
click to toggle source
# File lib/ractor/server/request.rb, line 34 def to_proc method(:===).to_proc end
Private Instance Methods
enforce_sync_when_receiving!()
click to toggle source
Receiver is request to receive a reply from
# File lib/ractor/server/request.rb, line 184 def enforce_sync_when_receiving! case sync when :tell, :conclude, :interrupt raise Talk::Error, "Can not receive from a Request for a `#{sync}` sync: #{self}" when :ask, :converse return :ok if Request.pending_receive_conclusion[self] raise Talk::Error, "Can not receive as #{self} is already answered" end end
enforce_valid_sync!()
click to toggle source
# File lib/ractor/server/request.rb, line 199 def enforce_valid_sync! # rubocop:disable Metrics/AbcSize, Metrics/MethodLength case [response_to&.sync, sync] in [nil, nil] :ok_unsynchronized in [nil | :converse, :tell | :ask | :converse] :ok_talk in [:ask | :converse, :conclude] :ok_concluding in [:ask | :converse, :interrupt] raise Talk::Error, 'Can only interrupt a 2-level conversation' unless response_to.response_to&.converse? :ok_interrupting in [:tell | :conclude | :interrupt => from, _] raise Talk::Error, "Can not respond to a Request with `#{from.inspect}` sync" in [:ask, _] raise Talk::Error, 'Request with `ask` sync must be responded with a `conclude`' \ "or `interrupt` sync, got #{sync.inspect}" in [_, nil] raise Talk::Error, "Specify sync to respond to a Request with #{sync.inspect}" else raise ArgumentError, "Unrecognized sync: #{sync.inspect}" end end
ractor_name(ractor)
click to toggle source
# File lib/ractor/server/request.rb, line 195 def ractor_name(ractor) ractor.name || "##{ractor.to_s.match(/#(\d+) /)[1]}" end
raise_exception(exc)
click to toggle source
# File lib/ractor/server/request.rb, line 140 def raise_exception(exc) raise exc unless WRAP_IN_REMOTE_ERROR if exc.exception.is_a?(Ractor::RemoteError) debug(:exception) { 'Received RemoteError, raising original cause' } raise exc.exception.cause else debug(:exception) { 'Received exception, raising RemoveError' } begin raise exc.exception rescue Exception raise Ractor::RemoteError # => sets `cause` to exc.exception end end end
unwrap(message)
click to toggle source
# File lib/ractor/server/request.rb, line 133 def unwrap(message) _rq, arg = message raise_exception(arg) if arg.is_a?(WrappedException) message end