Class: RubySkynet::Client

Inherits:
Object
  • Object
show all
Includes:
Common
Defined in:
lib/ruby_skynet/client.rb

Constant Summary

Constants included from Common

RubySkynet::Common::BINARY_ENCODING

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Common

included, local_ip_address, read_bson_document

Constructor Details

#initialize(skynet_name = self.class.skynet_name, skynet_version = self.class.skynet_version, skynet_region = self.class.skynet_region) ⇒ Client

Returns a new RubySkynet Client for the named service

Calls to an instance of the Client are thread-safe and can be called concurrently from multiple threads at the same time

Parameters:

:skynet_name
  Only required when creating instance of RubySkynet::Client directly
  Otherwise it defaults to the name of the class
  Name of the service to look for and connect to on Skynet

:skynet_version
  Optional version number of the service in Skynet
  Default: '*' being the latest version of the service

:skynet_region
  Optional region for this service in Skynet
  Default: RubySkynet.region

Example using Client class

require 'ruby_skynet'
SemanticLogger.default_level = :info
SemanticLogger.add_appender(STDOUT)

class EchoService < RubySkynet::Client
end

echo_service = EchoService.new
p echo_service.echo(:value => 5)

Example using Ruby Client directly

require 'ruby_skynet'
SemanticLogger.default_level = :info
SemanticLogger.add_appender(STDOUT)

tutorial_service = RubySkynet::Client.new('TutorialService')
p tutorial_service.call('Add', :value => 5)


62
63
64
65
66
67
68
69
# File 'lib/ruby_skynet/client.rb', line 62

def initialize(skynet_name=self.class.skynet_name, skynet_version=self.class.skynet_version, skynet_region=self.class.skynet_region)
  @skynet_name    = skynet_name
  @skynet_version = skynet_version
  @skynet_region  = skynet_region
  self.logger = SemanticLogger["#{self.class.name}: #{@skynet_name}/#{@skynet_version}/#{@skynet_region}"]

  raise "skynet_name is mandatory when using RubySkynet::Client directly" if @skynet_name == RubySkynet::Client.name
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object

Implement methods that call the remote Service



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ruby_skynet/client.rb', line 101

def method_missing(method, *args, &block)
  result = call(method, *args)

  # #TODO if Service returns method undefined, call super
  #
  # Define the method if the call was successful and no other thread has
  # already created the method
  if !result.nil? && result[:exception].nil? && !self.class.method_defined?(method)
    self.class.send(:define_method, method) {|*args| call(method, *args)}
  end
  result
end

Instance Attribute Details

#skynet_nameObject (readonly)

Allows this instance of the client to use different versions or regions.



14
15
16
# File 'lib/ruby_skynet/client.rb', line 14

def skynet_name
  @skynet_name
end

#skynet_regionObject (readonly)

Allows this instance of the client to use different versions or regions.



14
15
16
# File 'lib/ruby_skynet/client.rb', line 14

def skynet_region
  @skynet_region
end

#skynet_versionObject (readonly)

Allows this instance of the client to use different versions or regions.



14
15
16
# File 'lib/ruby_skynet/client.rb', line 14

def skynet_version
  @skynet_version
end

Class Method Details

.skynet_versionObject

Version of the Skynet service to use By default it will connect to the latest version Default: ‘*’



19
20
21
# File 'lib/ruby_skynet/client.rb', line 19

def self.skynet_version
  @skynet_version ||= '*'
end

Instance Method Details

#call(method_name, parameters, connection_params = {}) ⇒ Object

Performs a synchronous call to the Skynet Service

Parameters:

method_name [String|Symbol]:
  Name of the method to call at the service
parameters [Hash]:
  Parameters to pass into the service

Returns the Hash result returned from the Skynet Service

Raises RubySkynet::ProtocolError Raises RubySkynet::SkynetException



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ruby_skynet/client.rb', line 83

def call(method_name, parameters, connection_params={})
  # Skynet requires BSON RPC Calls to have the following format:
  # https://github.com/skynetservices/skynet/blob/master/protocol.md
  request_id = BSON::ObjectId.new.to_s

  # Obtain list of servers implementing this service in order of priority
  servers = ::RubySkynet.service_registry.servers_for(skynet_name, skynet_version, skynet_region)

  logger.tagged request_id do
    logger.benchmark_info "Called Skynet Service: #{skynet_name}.#{method_name}" do
      Connection.with_connection(servers, connection_params) do |connection|
        connection.rpc_call(request_id, skynet_name, method_name, parameters)
      end
    end
  end
end