Class: TentClient::CycleHTTP

Inherits:
Object
  • Object
show all
Defined in:
lib/tent-client/cycle_http.rb

Overview

Proxies to Faraday and cycles through server urls

until either non left or response status in the 200s or 400s

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, &faraday_block) ⇒ CycleHTTP

Returns a new instance of CycleHTTP.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/tent-client/cycle_http.rb', line 9

def initialize(client, &faraday_block)
  @faraday_block = faraday_block
  @client = client

  if client.entity_uri
    unless (Hash === client.server_meta) && (Array === client.server_meta['servers'])
      raise MalformedServerMeta.new("Server meta post for Entity(#{client.entity_uri.inspect}) is malformed: #{client.server_meta.inspect}")
    end

    @servers = client.server_meta['servers'].sort_by { |s| s['preference'] }
  else
    @servers = []
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



114
115
116
117
118
119
120
# File 'lib/tent-client/cycle_http.rb', line 114

def method_missing(method_name, *args, &block)
  if http.respond_to?(method_name)
    http.send(method_name, *args, &block)
  else
    super
  end
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



8
9
10
# File 'lib/tent-client/cycle_http.rb', line 8

def client
  @client
end

#serversObject (readonly)

Returns the value of attribute servers.



8
9
10
# File 'lib/tent-client/cycle_http.rb', line 8

def servers
  @servers
end

Instance Method Details

#current_serverObject



24
25
26
# File 'lib/tent-client/cycle_http.rb', line 24

def current_server
  @current_server || servers.first
end

#httpObject



35
36
37
# File 'lib/tent-client/cycle_http.rb', line 35

def http
  @http ||= new_http
end

#multipart_request(verb, url, params, parts, headers = {}, &block) ⇒ Object



68
69
70
71
72
73
74
75
# File 'lib/tent-client/cycle_http.rb', line 68

def multipart_request(verb, url, params, parts, headers = {}, &block)
  body = multipart_body(parts)
  run_request(verb.to_sym, url, params, body, headers) do |request|
    request.headers['Content-Type'] = "#{MULTIPART_CONTENT_TYPE}; boundary=#{MULTIPART_BOUNDARY}"
    request.headers['Content-Length'] = body.length.to_s
    yield(request) if block_given?
  end
end

#named_url(name, params = {}) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/tent-client/cycle_http.rb', line 39

def named_url(name, params = {})
  unless (Hash === current_server) && (Hash === current_server['urls']) && (template = current_server['urls'][name.to_s])
    raise ServerNotFound.new("Failed to match #{name.to_s.inspect} to a url for server: #{Yajl::Encoder.encode(current_server)}")
  end

  template.to_s.gsub(/\{([^\}]+)\}/) {
    param = (params.delete($1) || params.delete($1.to_sym)).to_s
    URI.encode_www_form_component(param)
  }
end

#new_httpObject



28
29
30
31
32
33
# File 'lib/tent-client/cycle_http.rb', line 28

def new_http
  @current_server = servers.shift
  @http = Faraday.new do |f|
    @faraday_block.call(f)
  end
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/tent-client/cycle_http.rb', line 110

def respond_to_missing?(method_name, include_private = false)
  http.respond_to?(method_name, include_private)
end

#run_request(verb, url, params, body, headers, &block) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/tent-client/cycle_http.rb', line 77

def run_request(verb, url, params, body, headers, &block)
  args = [verb, url, params, body, headers]
  if Symbol === url
    name = url
    url = named_url(url, params || {})
  else
    name = nil
  end

  res = http.run_request(verb, url, body, headers) do |request|
    request.params.update(params) if params
    yield request if block_given?
  end

  if name
    res.env[:tent_server] = current_server
  end

  return res if servers.empty? || !name

  case res.status
  when 200...300, 400...500
    res
  else
    new_http
    run_request(*args, &block)
  end
rescue Faraday::Error::TimeoutError, Faraday::Error::ConnectionFailed
  raise if servers.empty?
  new_http
  run_request(*args, &block)
end