Module: Diffend::Voting::Request

Defined in:
lib/diffend/voting/request.rb

Overview

Module responsible for doing request to Diffend

Constant Summary collapse

CONNECTION_EXCEPTIONS =

List of connection exceptions

[
  Errno::ECONNRESET,
  Errno::ENETUNREACH,
  Errno::EHOSTUNREACH,
  Errno::ECONNREFUSED
].freeze
TIMEOUT_EXCEPTIONS =

List of timeout exceptions

[
  Net::OpenTimeout,
  Net::ReadTimeout
].freeze

Class Method Summary collapse

Class Method Details

.assign_auth(request, config) ⇒ Object

Assigns basic authorization if provided in the config



114
115
116
117
118
119
120
# File 'lib/diffend/voting/request.rb', line 114

def assign_auth(request, config)
  return unless config
  return unless config.shareable_id
  return unless config.shareable_key

  request.basic_auth(config.shareable_id, config.shareable_key)
end

.assign_payload(request, payload) ⇒ Object

Assigns payload as json



126
127
128
# File 'lib/diffend/voting/request.rb', line 126

def assign_payload(request, payload)
  request.body = JSON.dump(payload: payload)
end

.build_http(url) ⇒ Object

Builds http connection object



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/diffend/voting/request.rb', line 83

def build_http(url)
  uri = URI(url)

  Net::HTTP.start(
    uri.host,
    uri.port,
    use_ssl: uri.scheme == 'https',
    verify_mode: OpenSSL::SSL::VERIFY_NONE,
    open_timeout: 5,
    read_timeout: 5
  ) { |http| yield(http, uri) }
end

.build_report(payload, exception) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
# File 'lib/diffend/voting/request.rb', line 173

def build_report(payload, exception)
  {
    request_id: SecureRandom.uuid,
    payload: payload,
    exception: {
      class: exception.class,
      message: exception.message,
      backtrace: exception.backtrace
    }
  }
end

.build_request(uri, config, payload) ⇒ Net::HTTP::Post

Build http post request and assigns headers and payload



103
104
105
106
107
108
# File 'lib/diffend/voting/request.rb', line 103

def build_request(uri, config, payload)
  Net::HTTP::Post
    .new(uri.request_uri, HEADERS)
    .tap { |request| assign_auth(request, config) }
    .tap { |request| assign_payload(request, payload) }
end

.build_request_error_messageObject



157
158
159
160
161
162
163
# File 'lib/diffend/voting/request.rb', line 157

def build_request_error_message
  <<~MSG
    \nWe were unable to process your request at this time. We recorded this incident in our system and will review it.\n
    If you think that this is a bug, don't hesitate.\n
    Create an issue on https://github.com/diffend-io/diffend-ruby/issues\n
  MSG
end

.build_unhandled_exception_messageObject



165
166
167
168
169
170
171
# File 'lib/diffend/voting/request.rb', line 165

def build_unhandled_exception_message
  <<~MSG
    \nSomething went really wrong. We recorded this incident in our system and will review it.\n
    This is a bug, don't hesitate.\n
    Create an issue on https://github.com/diffend-io/diffend-ruby/issues\n
  MSG
end

.call(command, payload, config) ⇒ Net::HTTPResponse

Execute request to Diffend



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/diffend/voting/request.rb', line 37

def call(command, payload, config)
  retry_count ||= 0

  build_http(commands_url(command, config.project_id)) do |http, uri|
    http.request(build_request(uri, config, payload))
  end
rescue *CONNECTION_EXCEPTIONS => e
  Bundler.ui.error('We experienced a connection issue, retrying...')
  sleep(exponential_backoff(retry_count))
  retry_count += 1

  retry if retry_count < 3

  output_report(build_report(payload, e))
  Bundler.ui.error('^^^ Above is the dump of your request ^^^')
  Bundler.ui.error(build_request_error_message)

  exit 1
rescue *TIMEOUT_EXCEPTIONS => e
  Bundler.ui.error('We experienced a timeout issue, retrying...')
  sleep(exponential_backoff(retry_count))
  retry_count += 1

  retry if retry_count < 3

  output_report(build_report(payload, e))
  Bundler.ui.error('^^^ Above is the dump of your request ^^^')
  Bundler.ui.error(build_request_error_message)

  exit 1
rescue StandardError => e
  exception_payload = build_report(payload, e)
  output_report(exception_payload)
  Bundler.ui.error('^^^ Above is the dump of your request ^^^')
  Bundler.ui.error(build_unhandled_exception_message)

  build_http(errors_url(config.project_id)) do |http, uri|
    http.request(build_request(uri, config, exception_payload))
  end

  exit 1
end

.commands_url(command, project_id) ⇒ String

Provides diffend command endpoint url



136
137
138
139
140
# File 'lib/diffend/voting/request.rb', line 136

def commands_url(command, project_id)
  return ENV['DIFFEND_COMMAND_URL'] if ENV.key?('DIFFEND_COMMAND_URL')

  "https://my.diffend.io/api/projects/#{project_id}/bundle/#{command}"
end

.errors_url(project_id) ⇒ String

Provides diffend errors endpoint url



147
148
149
150
151
# File 'lib/diffend/voting/request.rb', line 147

def errors_url(project_id)
  return ENV['DIFFEND_ERROR_URL'] if ENV.key?('DIFFEND_ERROR_URL')

  "https://my.diffend.io/api/projects/#{project_id}/errors"
end

.exponential_backoff(retry_count) ⇒ Object



153
154
155
# File 'lib/diffend/voting/request.rb', line 153

def exponential_backoff(retry_count)
  2**(retry_count + 1)
end

.output_report(report) ⇒ Object



185
186
187
# File 'lib/diffend/voting/request.rb', line 185

def output_report(report)
  puts report.to_json
end