Module: PatientHttp::Sidekiq

Defined in:
lib/patient_http/sidekiq.rb,
lib/patient_http/sidekiq/stats.rb,
lib/patient_http/sidekiq/web_ui.rb,
lib/patient_http/sidekiq/context.rb,
lib/patient_http/sidekiq/task_handler.rb,
lib/patient_http/sidekiq/task_monitor.rb,
lib/patient_http/sidekiq/configuration.rb,
lib/patient_http/sidekiq/request_worker.rb,
lib/patient_http/sidekiq/callback_worker.rb,
lib/patient_http/sidekiq/lifecycle_hooks.rb,
lib/patient_http/sidekiq/request_executor.rb,
lib/patient_http/sidekiq/processor_observer.rb,
lib/patient_http/sidekiq/task_monitor_thread.rb

Defined Under Namespace

Classes: CallbackWorker, Configuration, Context, LifecycleHooks, ProcessorObserver, RequestExecutor, RequestWorker, Stats, TaskHandler, TaskMonitor, TaskMonitorThread, WebUI

Constant Summary collapse

VERSION =
File.read(File.expand_path("../../../VERSION", __FILE__)).strip

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configurationConfiguration

Ensure configuration is initialized

Returns:



106
107
108
# File 'lib/patient_http/sidekiq.rb', line 106

def configuration
  @configuration ||= Configuration.new
end

.processorPatientHttp::Processor?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the processor instance (internal accessor)

Returns:

  • (PatientHttp::Processor, nil)


330
331
332
# File 'lib/patient_http/sidekiq.rb', line 330

def processor
  @processor
end

Class Method Details

.after_completion {|response| ... } ⇒ Object

Add a callback to be executed after a successful request completion.

Yields:

  • (response)

    block to execute after an HTTP request completes

Yield Parameters:

  • response (PatientHttp::Response)

    the HTTP response



121
122
123
# File 'lib/patient_http/sidekiq.rb', line 121

def after_completion(&block)
  @after_completion_callbacks << block
end

.after_error {|error| ... } ⇒ Object

Add a callback to be executed after a request error.

Yields:

  • (error)

    block to execute after an HTTP request errors

Yield Parameters:

  • error (PatientHttp::Error)

    information about the error that was raised



129
130
131
# File 'lib/patient_http/sidekiq.rb', line 129

def after_error(&block)
  @after_error_callbacks << block
end

.append_middlewarevoid

This method returns an undefined value.

Add Sidekiq middleware for context handling. The middleware is already added during initialization. You can call this method again to append the middleware if needed to insert it after other middleware. If you need further control, you can manually add the ‘PatientHttp::Sidekiq::Context::Middleware` middleware yourself.



140
141
142
143
144
145
146
# File 'lib/patient_http/sidekiq.rb', line 140

def append_middleware
  ::Sidekiq.configure_server do |config|
    config.server_middleware do |chain|
      chain.add PatientHttp::Sidekiq::Context::Middleware
    end
  end
end

.configure {|Configuration| ... } ⇒ Configuration

Configure the gem with a block

Yields:

Returns:



97
98
99
100
101
102
# File 'lib/patient_http/sidekiq.rb', line 97

def configure
  configuration = Configuration.new
  yield(configuration) if block_given?
  register_handler
  @configuration = configuration
end

.decrypt(data) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Decrypt data using the configured encryptor.

Parameters:

  • data (Hash)

    the data to decrypt

Returns:

  • (Hash)

    the decrypted data (or original if not encrypted)



199
200
201
# File 'lib/patient_http/sidekiq.rb', line 199

def decrypt(data)
  configuration.encryptor.decrypt(data)
end

.draining?Boolean

Check if the processor is draining (not accepting new requests but still processing in-flight ones).

Returns:

  • (Boolean)


159
160
161
# File 'lib/patient_http/sidekiq.rb', line 159

def draining?
  !!@processor&.draining?
end

.encrypt(data) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Encrypt data using the configured encryptor.

Parameters:

  • data (Hash)

    the data to encrypt

Returns:

  • (Hash)

    the encrypted data (or original if no encryption configured)



190
191
192
# File 'lib/patient_http/sidekiq.rb', line 190

def encrypt(data)
  configuration.encryptor.encrypt(data)
end

.execute(request, callback:, callback_args: nil, raise_error_responses: false) ⇒ String

Execute an async HTTP request.

Parameters:

  • request (PatientHttp::Request)

    the HTTP request to execute

  • callback (Class, String)

    Callback service class with on_complete and on_error instance methods, or its fully qualified class name.

  • callback_args (#to_h, nil) (defaults to: nil)

    Arguments to pass to callback via the PatientHttp::Response/PatientHttp::Error object. Must respond to to_h and contain only JSON-native types (nil, true, false, String, Integer, Float, Array, Hash). All hash keys will be converted to strings for serialization. Access via response.callback_args or error.callback_args using symbol or string keys.

  • raise_error_responses (Boolean) (defaults to: false)

    If true, treats non-2xx responses as errors and calls on_error instead of on_complete. Defaults to false.

Returns:

  • (String)

    the request ID



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/patient_http/sidekiq.rb', line 216

def execute(request, callback:, callback_args: nil, raise_error_responses: false)
  PatientHttp::CallbackValidator.validate!(callback)
  callback_name = callback.is_a?(Class) ? callback.name : callback.to_s
  callback_args = PatientHttp::CallbackValidator.validate_callback_args(callback_args)
  request_id = SecureRandom.uuid

  encrypted = encrypt(request.as_json)

  data = if external_storage.enabled?
    external_storage.store(encrypted, max_size: configuration.payload_store_threshold)
  else
    encrypted
  end

  RequestWorker.perform_async(data, callback_name, raise_error_responses, callback_args, request_id)

  request_id
end

.external_storagePatientHttp::ExternalStorage

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get an ExternalStorage instance for storing and fetching payloads.

Returns:

  • (PatientHttp::ExternalStorage)


181
182
183
# File 'lib/patient_http/sidekiq.rb', line 181

def external_storage
  @external_storage ||= PatientHttp::ExternalStorage.new(configuration)
end

.invoke_completion_callbacks(response) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Invoke the registered completion callbacks

Parameters:

  • response (PatientHttp::Response)

    the HTTP response



309
310
311
312
313
# File 'lib/patient_http/sidekiq.rb', line 309

def invoke_completion_callbacks(response)
  @after_completion_callbacks.each do |callback|
    callback.call(response)
  end
end

.invoke_error_callbacks(error) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Invoke the registered error callbacks

Parameters:

  • error (PatientHttp::Error)

    information about the error that was raised



320
321
322
323
324
# File 'lib/patient_http/sidekiq.rb', line 320

def invoke_error_callbacks(error)
  @after_error_callbacks.each do |callback|
    callback.call(error)
  end
end

.quietvoid

This method returns an undefined value.

Signal the processor to drain (stop accepting new requests)



269
270
271
272
273
# File 'lib/patient_http/sidekiq.rb', line 269

def quiet
  return unless running?

  @processor.drain
end

.register_handlerObject

Register Sidekiq as the request handler for processing HTTP requests. This is called automatically when the processor starts or you call PatientHttp::Sidekiq.configure.



237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/patient_http/sidekiq.rb', line 237

def register_handler
  @request_handler ||= lambda do |request:, callback:, raise_error_responses:, callback_args:|
    execute(
      request,
      callback: callback,
      raise_error_responses: raise_error_responses,
      callback_args: callback_args
    )
  end

  PatientHttp.register_handler(@request_handler)
end

.reset!void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Reset all state (useful for testing)



294
295
296
297
298
299
300
301
302
# File 'lib/patient_http/sidekiq.rb', line 294

def reset!
  @processor&.stop(timeout: 0)
  @processor = nil
  @configuration = nil
  @external_storage = nil
  @after_completion_callbacks = []
  @after_error_callbacks = []
  PatientHttp.unregister_handler(@request_handler) if @request_handler
end

.reset_configuration!Configuration

Reset configuration to defaults (useful for testing)

Returns:



112
113
114
115
# File 'lib/patient_http/sidekiq.rb', line 112

def reset_configuration!
  @configuration = nil
  configuration
end

.running?Boolean

Check if the processor is running.

Returns:

  • (Boolean)


151
152
153
# File 'lib/patient_http/sidekiq.rb', line 151

def running?
  !!@processor&.running?
end

.startvoid

This method returns an undefined value.

Start the processor



253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/patient_http/sidekiq.rb', line 253

def start
  return if running?

  @processor = PatientHttp::Processor.new(configuration)
  @processor.observe(ProcessorObserver.new(@processor))
  configuration.observers.each do |observer|
    @processor.observe(observer)
  end
  @processor.start

  register_handler
end

.stop(timeout: nil) ⇒ void

This method returns an undefined value.

Stop the processor gracefully

Parameters:

  • timeout (Float, nil) (defaults to: nil)

    maximum time to wait for in-flight requests to complete



279
280
281
282
283
284
285
286
287
288
# File 'lib/patient_http/sidekiq.rb', line 279

def stop(timeout: nil)
  if @request_handler
    PatientHttp.unregister_handler(@request_handler)
  end

  return unless @processor

  @processor.stop(timeout: timeout)
  @processor = nil
end

.stopped?Boolean

Check if the processor is stopped or has not been started.

Returns:

  • (Boolean)


173
174
175
# File 'lib/patient_http/sidekiq.rb', line 173

def stopped?
  @processor.nil? || @processor.stopped?
end

.stopping?Boolean

Check if the processor is in the process of stopping.

Returns:

  • (Boolean)


166
167
168
# File 'lib/patient_http/sidekiq.rb', line 166

def stopping?
  !!@processor&.stopping?
end