class Ractor::Server::Client
Constants
- CONFIG
- NON_SETTERS
- NOT_IMPLICITLY_DEFINED
Attributes
server[R]
Public Class Methods
call_server_alias(*args, **options, &block)
click to toggle source
# File lib/ractor/server/client.rb, line 100 def call_server_alias(*args, **options, &block) call_server(__callee__, *args, **options, &block) end
config(key) { |cur_value| ... }
click to toggle source
# File lib/ractor/server/client.rb, line 69 def config(key) cur = self::CONFIG cur_value = cur.fetch(key) if block_given? cur_value = yield cur_value remove_const(:CONFIG) if const_defined?(:CONFIG, false) const_set(:CONFIG, Ractor.make_shareable(cur.merge(key => cur_value))) end cur_value end
interface_with_server(*methods)
click to toggle source
# File lib/ractor/server/client.rb, line 51 def interface_with_server(*methods) methods.flatten!(1) self::ServerCallLayer.class_eval do methods.each do |method| public alias_method(method, :call_server_alias) end end debug(:interface) { "Defined methods #{methods.join(', ')}" } methods end
new(server)
click to toggle source
# File lib/ractor/server/client.rb, line 12 def initialize(server) raise ArgumentError, "Expected a Ractor, got #{server.inspect}" unless server.is_a?(::Ractor) @nest_request_key = :"Ractor::Server::Client#{object_id}" @server = server freeze end
refresh_server_call_layer()
click to toggle source
# File lib/ractor/server/client.rb, line 42 def refresh_server_call_layer layer = self::ServerCallLayer server_klass = self::Server are_defined = layer.instance_methods should_be_defined = server_klass.instance_methods - NOT_IMPLICITLY_DEFINED (are_defined - should_be_defined).each { layer.remove_method _1 } interface_with_server(*config(:tell_methods) | should_be_defined - are_defined) end
start(*args, **options)
click to toggle source
# File lib/ractor/server/client.rb, line 37 def start(*args, **options) ractor = self.class::Server.start_ractor(*args, **options) new(ractor) end
sync_kind(method, block_given)
click to toggle source
# File lib/ractor/server/client.rb, line 80 def sync_kind(method, block_given) case when setter?(method) || config(:tell_methods).include?(method) :tell when block_given :converse else :ask end end
tells(*methods)
click to toggle source
# File lib/ractor/server/client.rb, line 63 def tells(*methods) methods.flatten!(1) config(:tell_methods) { |set| set + methods } interface_with_server(*methods) end
Private Class Methods
inherited(base)
click to toggle source
Calls superclass method
# File lib/ractor/server/client.rb, line 98 def inherited(base) mod = Module.new do private def call_server_alias(*args, **options, &block) call_server(__callee__, *args, **options, &block) end end base.const_set(:ServerCallLayer, mod) base.include mod super end
setter?(method)
click to toggle source
# File lib/ractor/server/client.rb, line 114 def setter?(method) method.end_with?('=') && !NON_SETTERS.include?(method) end
Public Instance Methods
inspect()
click to toggle source
# File lib/ractor/server/client.rb, line 25 def inspect "<##{self.class} server: #{call_server(:inspect)}>" end
Also aliased as: to_s
Private Instance Methods
await_response(rq, method) { |result| ... }
click to toggle source
# File lib/ractor/server/client.rb, line 162 def await_response(rq, method) debug(:await) { "Awaiting response to #{rq}" } loop do response, result = rq.receive case response.sync in :converse then handle_yield(method, response) { yield result } in :conclude then return result end end ensure debug(:await) { "Finished waiting for #{rq}" } end
call_server(method, *args, **options, &block)
click to toggle source
@returns [Request] if method should be called as `:tell`, otherwise returns the result of the concluded method call.
# File lib/ractor/server/client.rb, line 147 def call_server(method, *args, **options, &block) Ractor.make_shareable([args, options]) if share_inputs?(method) info = format_call(method, *args, **options, &block) if $DEBUG rq = Request.send( @server, method, args, options, response_to: Thread.current[@nest_request_key], sync: self.class.sync_kind(method, !!block), info: info, ) return rq if rq.tell? await_response(rq, method, &block) end
format_call(method, *args, **options, &block)
click to toggle source
# File lib/ractor/server/client.rb, line 207 def format_call(method, *args, **options, &block) args = args.map(&:inspect) + options.map { _1.map(&:inspect).join(': ') } arg_list = "(#{args.join(', ')})" unless args.empty? block_sig = ' {...}' if block "#{method}#{arg_list}#{block_sig}" end
handle_yield(method, response) { |]| ... }
click to toggle source
# File lib/ractor/server/client.rb, line 176 def handle_yield(method, response) begin status, result = with_requests_nested(response) do [:ok, yield] rescue Exception => e [:exception, e] end ensure response.interrupt unless status # throw/return/... end if status == :exception response.send_exception(result) else Ractor.make_shareable(result) if share_inputs?(method) response.conclude result end end
implemented_by_server?(method)
click to toggle source
# File lib/ractor/server/client.rb, line 137 def implemented_by_server?(method) self.class::Server.method_defined?(method) end
method_missing(method, *args, **options, &block)
click to toggle source
Calls superclass method
# File lib/ractor/server/client.rb, line 123 def method_missing(method, *args, **options, &block) if implemented_by_server?(method) refresh_server_call_layer # sanity check unless self.class::ServerCallLayer.method_defined?(method) raise "`refresh_server_call_layer` failed for #{method}" end return __send__(method, *args, **options, &block) end super end
refresh_server_call_layer()
click to toggle source
# File lib/ractor/server/client.rb, line 141 def refresh_server_call_layer self.class.refresh_server_call_layer end
respond_to_missing?(method, priv = false)
click to toggle source
Calls superclass method
# File lib/ractor/server/client.rb, line 119 def respond_to_missing?(method, priv = false) !priv && implemented_by_server?(method) || super end
with_requests_nested(context) { || ... }
click to toggle source
# File lib/ractor/server/client.rb, line 194 def with_requests_nested(context) store = Thread.current prev = store[@nest_request_key] store[@nest_request_key] = context yield ensure store[@nest_request_key] = prev end