Class: PatientHttp::Sidekiq::Configuration

Inherits:
Configuration
  • Object
show all
Defined in:
lib/patient_http/sidekiq/configuration.rb

Overview

Configuration for the Sidekiq integration.

Wraps PatientHttp::Configuration with Sidekiq-aware defaults and adds Sidekiq-specific options like worker queue/retry settings.

Access the underlying pool configuration via the http_pool attribute.

Defined Under Namespace

Classes: ProfileConfiguration

Constant Summary collapse

DEFAULT_PAYLOAD_STORE_THRESHOLD =

Default threshold in bytes above which payloads are stored externally

64 * 1024

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(heartbeat_interval: 60, orphan_threshold: 300, sidekiq_options: nil, payload_store_threshold: DEFAULT_PAYLOAD_STORE_THRESHOLD, on_retries_exhausted: nil, direct_execution: true, redis_pool_size: nil, redis_pool_timeout: 5, stats_flush_interval: 5, inflight_details: true, **pool_options) ⇒ Configuration

Initializes a new Configuration with the specified options.

Parameters:

  • heartbeat_interval (Integer) (defaults to: 60)

    Interval for updating inflight request heartbeats in seconds

  • orphan_threshold (Integer) (defaults to: 300)

    Age threshold for detecting orphaned requests in seconds

  • sidekiq_options (Hash, nil) (defaults to: nil)

    Sidekiq options to apply to RequestWorker and CallbackWorker

  • on_retries_exhausted (#call, nil) (defaults to: nil)

    Handler called when a CallbackWorker job exhausts retries

  • direct_execution (Boolean) (defaults to: true)

    Whether requests execute directly on a processor running in the current process instead of being enqueued through Sidekiq

  • pool_options (Hash)

    Options passed through to PatientHttp::Configuration. Sidekiq-aware defaults are applied for shutdown_timeout and logger if not explicitly provided.



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
109
110
# File 'lib/patient_http/sidekiq/configuration.rb', line 80

def initialize(
  heartbeat_interval: 60,
  orphan_threshold: 300,
  sidekiq_options: nil,
  payload_store_threshold: DEFAULT_PAYLOAD_STORE_THRESHOLD,
  on_retries_exhausted: nil,
  direct_execution: true,
  redis_pool_size: nil,
  redis_pool_timeout: 5,
  stats_flush_interval: 5,
  inflight_details: true,
  **pool_options
)
  pool_options[:shutdown_timeout] ||= (::Sidekiq.default_configuration[:timeout] || 25) - 2
  pool_options[:logger] ||= ::Sidekiq.logger

  super(**pool_options)

  @observers = []
  @processor_profiles = {default: {}}
  self.sidekiq_options = sidekiq_options
  self.heartbeat_interval = heartbeat_interval
  self.orphan_threshold = orphan_threshold
  self.payload_store_threshold = payload_store_threshold || DEFAULT_PAYLOAD_STORE_THRESHOLD
  self.on_retries_exhausted = on_retries_exhausted
  self.direct_execution = direct_execution
  self.redis_pool_size = redis_pool_size
  self.redis_pool_timeout = redis_pool_timeout
  self.stats_flush_interval = stats_flush_interval
  self.inflight_details = inflight_details
end

Instance Attribute Details

#direct_executionBoolean

Returns Whether requests execute directly on a processor running in the current process instead of being enqueued through Sidekiq.

Returns:

  • (Boolean)

    Whether requests execute directly on a processor running in the current process instead of being enqueued through Sidekiq



31
32
33
# File 'lib/patient_http/sidekiq/configuration.rb', line 31

def direct_execution
  @direct_execution
end

#heartbeat_intervalNumeric

Returns Heartbeat update interval in seconds.

Returns:

  • (Numeric)

    Heartbeat update interval in seconds



24
25
26
# File 'lib/patient_http/sidekiq/configuration.rb', line 24

def heartbeat_interval
  @heartbeat_interval
end

#inflight_detailsBoolean

Returns Whether the URL, HTTP method, and processor of each in-flight request are recorded so the Web UI can list them.

Returns:

  • (Boolean)

    Whether the URL, HTTP method, and processor of each in-flight request are recorded so the Web UI can list them



35
36
37
# File 'lib/patient_http/sidekiq/configuration.rb', line 35

def inflight_details
  @inflight_details
end

#observersArray<PatientHttp::ProcessorObserver> (readonly)

Returns Registered processor observers Observers will be registered with the processor when it is started, allowing them to receive lifecycle callbacks for PatientHttp requests.

Returns:

  • (Array<PatientHttp::ProcessorObserver>)

    Registered processor observers Observers will be registered with the processor when it is started, allowing them to receive lifecycle callbacks for PatientHttp requests.



67
68
69
# File 'lib/patient_http/sidekiq/configuration.rb', line 67

def observers
  @observers
end

#orphan_thresholdNumeric

Returns Orphan detection threshold in seconds.

Returns:

  • (Numeric)

    Orphan detection threshold in seconds



21
22
23
# File 'lib/patient_http/sidekiq/configuration.rb', line 21

def orphan_threshold
  @orphan_threshold
end

#payload_store_thresholdInteger

Returns Size threshold in bytes for external payload storage.

Returns:

  • (Integer)

    Size threshold in bytes for external payload storage



18
19
20
# File 'lib/patient_http/sidekiq/configuration.rb', line 18

def payload_store_threshold
  @payload_store_threshold
end

#redis_pool_sizeInteger?

Returns Size of the gem's dedicated Redis pool; nil sizes it automatically from completion_threads.

Returns:

  • (Integer, nil)

    Size of the gem's dedicated Redis pool; nil sizes it automatically from completion_threads



39
40
41
# File 'lib/patient_http/sidekiq/configuration.rb', line 39

def redis_pool_size
  @redis_pool_size
end

#redis_pool_timeoutNumeric

Returns Checkout timeout in seconds for the gem's dedicated Redis pool.

Returns:

  • (Numeric)

    Checkout timeout in seconds for the gem's dedicated Redis pool



42
43
44
# File 'lib/patient_http/sidekiq/configuration.rb', line 42

def redis_pool_timeout
  @redis_pool_timeout
end

#sidekiq_optionsHash?

Returns Sidekiq options to apply to RequestWorker and CallbackWorker.

Returns:

  • (Hash, nil)

    Sidekiq options to apply to RequestWorker and CallbackWorker



27
28
29
# File 'lib/patient_http/sidekiq/configuration.rb', line 27

def sidekiq_options
  @sidekiq_options
end

#stats_flush_intervalNumeric

Returns Seconds between flushes of locally aggregated stats to Redis (0 flushes synchronously on every recorded event).

Returns:

  • (Numeric)

    Seconds between flushes of locally aggregated stats to Redis (0 flushes synchronously on every recorded event)



46
47
48
# File 'lib/patient_http/sidekiq/configuration.rb', line 46

def stats_flush_interval
  @stats_flush_interval
end

Instance Method Details

#direct_execution?Boolean

Check if direct execution is enabled.

Returns:

  • (Boolean)


195
196
197
# File 'lib/patient_http/sidekiq/configuration.rb', line 195

def direct_execution?
  @direct_execution
end

#inflight_details?Boolean

Check if in-flight request details are recorded.

Returns:

  • (Boolean)


253
254
255
# File 'lib/patient_http/sidekiq/configuration.rb', line 253

def inflight_details?
  @inflight_details
end

#inflight_url_sanitizer#call? #inflight_url_sanitizer {|url| ... } ⇒ Object

Set the sanitizer applied to a request URL before it is recorded for the Web UI, or read the current one.

The sanitizer receives the full URL and returns what to display. Without one, the user name, password, query string, and fragment are removed and the scheme, host, and path are kept. Use it to redact more, such as an identifier in the path.

Examples:

config.inflight_url_sanitizer { |url| url.sub(%r{/users/\d+}, "/users/:id") }

Overloads:

  • #inflight_url_sanitizer#call?

    Returns the current sanitizer.

    Returns:

    • (#call, nil)

      the current sanitizer

  • #inflight_url_sanitizer {|url| ... } ⇒ Object

    Yields:

    • (url)

      block that returns the URL to display

    Yield Parameters:

    • url (String)

      the full request URL



273
274
275
276
277
278
279
# File 'lib/patient_http/sidekiq/configuration.rb', line 273

def inflight_url_sanitizer(&block)
  if block
    @inflight_url_sanitizer = block
  else
    @inflight_url_sanitizer
  end
end

#inflight_url_sanitizer=(value) ⇒ Object

Set the sanitizer applied to a request URL before it is recorded.

Parameters:

  • value (#call, nil)

    a callable object, or nil to use the default

Raises:

  • (ArgumentError)

    If value is not callable and not nil



285
286
287
288
289
290
291
# File 'lib/patient_http/sidekiq/configuration.rb', line 285

def inflight_url_sanitizer=(value)
  if value && !value.respond_to?(:call)
    raise ArgumentError.new("inflight_url_sanitizer must respond to #call, got: #{value.class}")
  end

  @inflight_url_sanitizer = value
end

#multiple_processors?Boolean

Whether more than one processor profile is declared.

Returns:

  • (Boolean)


332
333
334
# File 'lib/patient_http/sidekiq/configuration.rb', line 332

def multiple_processors?
  @processor_profiles.size > 1
end

#on_retries_exhausted#call? #on_retries_exhausted {|error| ... } ⇒ #call?

Returns Handler invoked when a CallbackWorker job exhausts all retries.

Overloads:

  • #on_retries_exhausted#call?

    Returns the current handler.

    Returns:

    • (#call, nil)
  • #on_retries_exhausted {|error| ... } ⇒ #call?

    Sets a block as the handler.

    Yields:

    • (error)

      block to execute when retries are exhausted

    Yield Parameters:

    • error (PatientHttp::Error)

      information about the error

Returns:

  • (#call, nil)

    Handler invoked when a CallbackWorker job exhausts all retries.



56
57
58
59
60
61
62
# File 'lib/patient_http/sidekiq/configuration.rb', line 56

def on_retries_exhausted(&block)
  if block
    @on_retries_exhausted = block
  else
    @on_retries_exhausted
  end
end

#on_retries_exhausted=(value) ⇒ Object

Set the on_retries_exhausted handler.

This handler is called when a CallbackWorker job exhausts all retries. It receives the same arguments as the on_error callback.

Parameters:

  • value (#call, nil)

    A callable object or nil to clear the handler

Raises:

  • (ArgumentError)

    If value is not callable and not nil



119
120
121
122
123
124
125
# File 'lib/patient_http/sidekiq/configuration.rb', line 119

def on_retries_exhausted=(value)
  if value && !value.respond_to?(:call)
    raise ArgumentError.new("on_retries_exhausted must respond to #call, got: #{value.class}")
  end

  @on_retries_exhausted = value
end

#processor(name, **options) ⇒ Hash

Declare a named processor profile, or read one back.

Each profile becomes an independent processor with its own capacity, timeouts, and threads. Options are overrides applied on top of this configuration's HTTP pool options. Requests select a processor with the processor: option on PatientHttp::Sidekiq.execute (or on the request itself). The :default profile always exists; declaring it overrides options for the default processor.

Examples:

PatientHttp::Sidekiq.configure do |config|
  config.processor(:llm, max_connections: 200, request_timeout: 120)
  config.processor(:webhooks, max_connections: 64, request_timeout: 10)
end

Parameters:

  • name (Symbol, String)

    the processor name

  • options (Hash)

    overrides for PatientHttp::Configuration options

Returns:

  • (Hash)

    the stored options for the profile



311
312
313
314
315
316
317
318
319
320
# File 'lib/patient_http/sidekiq/configuration.rb', line 311

def processor(name, **options)
  key = normalize_processor_name(name)

  if options.any?
    validate_profile_options!(options)
    @processor_profiles[key] = options
  end

  @processor_profiles[key]
end

#processor_config(name) ⇒ PatientHttp::Configuration

Build the effective configuration for a named processor. The default profile with no overrides is this configuration itself; other profiles get a view of this configuration with their overrides applied, so they share secrets, preprocessors, payload stores, and encryption.

Parameters:

  • name (Symbol, String)

    the processor name

Returns:

  • (PatientHttp::Configuration)

    the configuration for the processor

Raises:

  • (ArgumentError)

    if the profile is not declared



344
345
346
347
348
349
350
351
352
# File 'lib/patient_http/sidekiq/configuration.rb', line 344

def processor_config(name)
  key = normalize_processor_name(name)
  profile = @processor_profiles[key]
  raise ArgumentError.new("Unknown processor profile: #{name.inspect}") unless profile

  return self if profile.empty?

  ProfileConfiguration.new(self, profile)
end

#processor_profilesHash{Symbol => Hash}

All declared processor profiles. Always includes :default.

Returns:

  • (Hash{Symbol => Hash})

    profile options by processor name



325
326
327
# File 'lib/patient_http/sidekiq/configuration.rb', line 325

def processor_profiles
  @processor_profiles.dup
end

#to_hHash

Convert to hash for inspection

Returns:

  • (Hash)

    hash representation with string keys



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/patient_http/sidekiq/configuration.rb', line 356

def to_h
  super.merge(
    "payload_store_threshold" => payload_store_threshold,
    "heartbeat_interval" => heartbeat_interval,
    "orphan_threshold" => orphan_threshold,
    "sidekiq_options" => sidekiq_options,
    "direct_execution" => direct_execution,
    "on_retries_exhausted" => on_retries_exhausted ? "defined" : nil,
    "redis_pool_size" => redis_pool_size,
    "redis_pool_timeout" => redis_pool_timeout,
    "stats_flush_interval" => stats_flush_interval,
    "inflight_details" => inflight_details,
    "processor_profiles" => processor_profiles.keys.map(&:to_s)
  )
end