Class: MetaRPC::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/metarpc/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, header_setter_func = nil) ⇒ Client

Returns a new instance of Client.



5
6
7
8
# File 'lib/metarpc/client.rb', line 5

def initialize(url, header_setter_func = nil)
  @metarpc_url = URI.parse(url)
  @metarpc_header_setter_func = header_setter_func
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &blk) ⇒ Object



14
15
16
17
18
19
# File 'lib/metarpc/client.rb', line 14

def method_missing(sym, *args, &blk)
  call = metarpc_build_method(sym, args)
  return metarpc_pending_batch << { call: call, on_response: blk } if metarpc_pending_batch

  metarpc_execute_request(call)
end

Instance Attribute Details

#metarpc_header_setter_funcObject (readonly)

Returns the value of attribute metarpc_header_setter_func.



3
4
5
# File 'lib/metarpc/client.rb', line 3

def metarpc_header_setter_func
  @metarpc_header_setter_func
end

#metarpc_pending_batchObject (readonly)

Returns the value of attribute metarpc_pending_batch.



3
4
5
# File 'lib/metarpc/client.rb', line 3

def metarpc_pending_batch
  @metarpc_pending_batch
end

#metarpc_urlObject (readonly)

Returns the value of attribute metarpc_url.



3
4
5
# File 'lib/metarpc/client.rb', line 3

def metarpc_url
  @metarpc_url
end

Instance Method Details

#metarpc_build_method(method, args) ⇒ Object



28
29
30
31
32
33
34
35
# File 'lib/metarpc/client.rb', line 28

def metarpc_build_method(method, args)
  {
    jsonrpc: '2.0',
    method: method,
    params: args[0].is_a?(Hash) && args.count == 1 ? args[0] : args,
    id: SecureRandom.uuid
  }
end

#metarpc_execute_request(call) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/metarpc/client.rb', line 37

def metarpc_execute_request(call)
  body = call.to_json
  headers = metarpc_header_setter_func.call(body) if metarpc_header_setter_func.present?
  (headers ||= {})['Content-Type'] = 'text/json'

  http = Net::HTTP.new(metarpc_url.host, metarpc_url.port)
  request = Net::HTTP::Post.new(metarpc_url.request_uri, headers)
  request.body = body

  metarpc_parse_response(http.request(request).body)
end

#metarpc_handle_batch_response(response) ⇒ Object



59
60
61
62
63
64
65
66
67
68
# File 'lib/metarpc/client.rb', line 59

def metarpc_handle_batch_response(response)
  response.each do |raw_call_response|
    call_response = raw_call_response.deep_symbolize_keys
    pending_batch = metarpc_pending_batch.find { |batch| batch[:call][:id] == call_response[:id] }
    next unless pending_batch[:on_response].present?

    response = ResponseWrapper.new(call_response)
    pending_batch[:on_response].call(response)
  end
end

#metarpc_parse_response(raw_response) ⇒ Object

Raises:



49
50
51
52
53
54
55
56
57
# File 'lib/metarpc/client.rb', line 49

def metarpc_parse_response(raw_response)
  response = JSON.parse(raw_response)
  return metarpc_handle_batch_response(response) if metarpc_pending_batch

  response.deep_symbolize_keys!
  raise RpcClientError.new(response[:error]), "#{response[:error][:code]} #{response[:error][:message]}" if response.key?(:error)

  response[:result]
end

#respond_to_missing?(_sym) ⇒ Boolean

Returns:

  • (Boolean)


10
11
12
# File 'lib/metarpc/client.rb', line 10

def respond_to_missing?(_sym)
  true
end

#rpc_batch(&blk) ⇒ Object



21
22
23
24
25
26
# File 'lib/metarpc/client.rb', line 21

def rpc_batch(&blk)
  @metarpc_pending_batch = []
  instance_exec(&blk)
  metarpc_execute_request(metarpc_pending_batch.map { |p| p[:call] })
  @metarpc_pending_batch = nil
end