Class: Salemove::ProcessHandler::PivotProcess::ServiceSpawner

Inherits:
Object
  • Object
show all
Defined in:
lib/salemove/process_handler/pivot_process.rb

Constant Summary collapse

PROCESSED_REQUEST_LOG_KEYS =
[:error, :success]

Instance Method Summary collapse

Constructor Details

#initialize(service, freddy:, logger:, benchmarker:, exception_notifier:, log_error_as_string:) ⇒ ServiceSpawner

Returns a new instance of ServiceSpawner.



123
124
125
126
127
128
129
130
# File 'lib/salemove/process_handler/pivot_process.rb', line 123

def initialize(service, freddy:, logger:, benchmarker:, exception_notifier:, log_error_as_string:)
  @service = service
  @freddy = freddy
  @logger = logger
  @benchmarker = benchmarker
  @exception_notifier = exception_notifier
  @log_error_as_string = log_error_as_string
end

Instance Method Details

#delegate_to_service(input) ⇒ Object



178
179
180
181
182
183
184
185
186
# File 'lib/salemove/process_handler/pivot_process.rb', line 178

def delegate_to_service(input)
  result = @benchmarker.call(input) { @service.call(input) }

  unless result.respond_to?(:fulfilled?)
    log_processed_request(input, result)
  end

  result
end

#handle_exception(exception, input) ⇒ Object



200
201
202
203
204
205
206
207
# File 'lib/salemove/process_handler/pivot_process.rb', line 200

def handle_exception(exception, input)
  message = [exception.inspect, *exception.backtrace].join("\n")
  @logger.error(message, input)

  @exception_notifier.notify_or_ignore(exception, input) if @exception_notifier

  { success: false, error: exception.message }
end

#handle_fulfillable_response(input, handler, response) ⇒ Object



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/salemove/process_handler/pivot_process.rb', line 143

def handle_fulfillable_response(input, handler, response)
  timeout = response.respond_to?(:timeout) && response.timeout || DEFAULT_FULFILLABLE_TIMEOUT
  Timeout::timeout(timeout) do
    while true
      if response.fulfilled?
        log_processed_request(input, response.value)
        return handle_response(handler, response.value)
      end
      sleep 0.001
    end
  end
rescue Timeout::Error
  @logger.error "Fullfillable response was not fulfilled in #{timeout} seconds", input
  handle_response(handler, success: false, error: "Fulfillable response was not fulfilled")
end

#handle_request(input) ⇒ Object



167
168
169
170
171
172
173
174
175
176
# File 'lib/salemove/process_handler/pivot_process.rb', line 167

def handle_request(input)
  @logger.info 'Received request', input
  if input.has_key?(:ping)
    { success: true, pong: 'pong' }
  else
    delegate_to_service(input)
  end
rescue StandardError => exception
  handle_exception(exception, input)
end

#handle_response(handler, response) ⇒ Object



159
160
161
162
163
164
165
# File 'lib/salemove/process_handler/pivot_process.rb', line 159

def handle_response(handler, response)
  if response.is_a?(Hash) && (response[:success] == false || response[:error])
    handler.error(response)
  else
    handler.success(response)
  end
end

#log_processed_request(input, result) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
# File 'lib/salemove/process_handler/pivot_process.rb', line 188

def log_processed_request(input, result)
  attributes = result
    .select { |k, _| PROCESSED_REQUEST_LOG_KEYS.include?(k) }
    .merge(input)

  if @log_error_as_string
    attributes[:error] = attributes[:error].to_s if attributes.has_key?(:error)
  end

  @logger.info 'Processed request', attributes
end

#spawnObject



132
133
134
135
136
137
138
139
140
141
# File 'lib/salemove/process_handler/pivot_process.rb', line 132

def spawn
  @freddy.respond_to(@service.class::QUEUE) do |input, handler|
    response = handle_request(input)
    if response.respond_to?(:fulfilled?)
      handle_fulfillable_response(input, handler, response)
    else
      handle_response(handler, response)
    end
  end
end