module MessagePack::Rpc::Client

Module that implemented client protocol of MessagePack-RPC.

@abstract

Include from the class that implements the rpc client. 
If you receive a protocol level error, override the on_error method.

Public Class Methods

included(klass) click to toggle source
# File lib/msgpack/rpc/client.rb, line 24
def included(klass)
  m = Module.new {
    klass.instance_variable_set(:@msgpack_options, {}) 

    def msgpack_options(opts = :none)
      if opts.nil? || opts.kind_of?(Hash)
        @msgpack_options = opts
      end

      return (@msgpack_options = opts)
    end

    def new_unpacker
      return MessagePack::Unpacker.new(@msgpack_options || {})
    end
  }

  klass.extend(m)
end
msgpack_options(opts = :none) click to toggle source
# File lib/msgpack/rpc/client.rb, line 28
def msgpack_options(opts = :none)
  if opts.nil? || opts.kind_of?(Hash)
    @msgpack_options = opts
  end

  return (@msgpack_options = opts)
end
new_unpacker() click to toggle source
# File lib/msgpack/rpc/client.rb, line 36
def new_unpacker
  return MessagePack::Unpacker.new(@msgpack_options || {})
end

Public Instance Methods

call(meth, *args, &blk) click to toggle source

call the procedure of peer rpc server

@param [Symbol] meth

target procedure name.

@param [Array] args

arguments for procedure.

@return [Integer]

assigned mesaage id

@yield [res, err]

callback that is when the procedure call completes.

@yieldparam [Object] res

responce of procedure when procedure successed.

@yieldparam [Object] err

error data of procedure when procedure failed.
# File lib/msgpack/rpc/client.rb, line 98
def call(meth, *args, &blk)
  raise ArgumentError.new("handler is not spcified") if not blk

  id = new_id

  session_map[id] = blk
  send_data([0, id, meth, args].to_msgpack)

  return id
end
cancel(id) click to toggle source

cacel the call message

@param [Integer] id

message id of calling message (return value of
MessagePack::Rpc::Client#call())

@note

 When this method is called, the procedure call corresponding to
the ID specified in the argument is cancelled.
# File lib/msgpack/rpc/client.rb, line 120
def cancel(id)
  session_map.delete(id)
end
notify(meth, *args) click to toggle source

send the notification to peer rpc server

@param [Symbol] meth

notify name

@param [Array] args

argument for notification
# File lib/msgpack/rpc/client.rb, line 133
def notify(meth, *args)
  send_data([2, meth, args].to_msgpack)
end
on(name, &blk) click to toggle source

define the notify method

@param [Symbol] name

notification name

@yield [*args]

 callback that is when received the notification
from peer rpc server.
# File lib/msgpack/rpc/client.rb, line 223
def on(name, &blk)
  raise ArgumentError.new("handler is not spcified") if not blk
  notify_handler[name] = blk
end
receive_dgram(data) click to toggle source

emqueu the received datagram to communication buffer

@param [Blob] data

recevied data from rpc server.

@note

Use this method for datagram communication. \
Use it when it is guaranteed that data is exchanged \
in packets (it works a bit faster).
# File lib/msgpack/rpc/client.rb, line 190
def receive_dgram(data)
  eval_response(MessagePack.unpack(data, self.class.msgpack_options))
end
receive_stream(data) click to toggle source

emqueu the received data to communication buffer

@param [Blob] data

recevied data from rpc server.
# File lib/msgpack/rpc/client.rb, line 200
def receive_stream(data)
  begin
    unpacker.feed_each(data) {|resp| eval_response(resp)}

  rescue MessagePack::UnpackError => e
    unpacker.reset
    error_occured(e)

  rescue => e
    error_occured(e)
  end
end

Private Instance Methods

error_occured(e) click to toggle source
# File lib/msgpack/rpc/client.rb, line 66
def error_occured(e)
  e = ProtocolError.new(e) if e.kind_of?(String)

  if self.respond_to?(:on_error, true)
    __send__(:on_error, e)
  else
    STDERR.print("#{e.message}")
  end
end
eval_response(resp) click to toggle source
# File lib/msgpack/rpc/client.rb, line 137
def eval_response(resp)
  if not resp.kind_of?(Array)
    error_occured("responce is not array")
  end

  case resp.shift
  when 1 # as response
    id, error, result = resp

    if not session_map.include?(id)
      error_occured("unknwon responce id is received.")

    elsif error.nil?
      # when success
      session_map.delete(id).(result, nil)

    elsif result.nil?
      # when error occurred
      session_map.delete(id).(nil, error)

    else
      session_map.delete(id)
      error_occured("invalid responce data")
    end

  when 2 # as notification
    meth = resp[0].to_sym
    args = resp[1]

    if notify_handler.include?(meth)
      notify_handler[meth].(*args)

    else
      STDERR.print("unhandled notification '#{meth}' received.\n")
    end

  else
    error_occured("unknown response received")
  end
end
new_id() click to toggle source
# File lib/msgpack/rpc/client.rb, line 45
def new_id
  @session_id ||= -1
  return (@session_id += 1)
end
notify_handler() click to toggle source
# File lib/msgpack/rpc/client.rb, line 56
def notify_handler
  return (@notify_handler ||= {})
end
session_map() click to toggle source
# File lib/msgpack/rpc/client.rb, line 51
def session_map
  return (@session_map ||= {})
end
unpacker() click to toggle source
# File lib/msgpack/rpc/client.rb, line 61
def unpacker
  return (@unpacker ||= self.class.new_unpacker)
end