Class: PatientHttp::Configuration
- Inherits:
-
Object
- Object
- PatientHttp::Configuration
- Defined in:
- lib/patient_http/configuration.rb
Overview
Configuration for the PatientHttp processor.
This class holds all configuration options for the HTTP connection pool, including connection limits, timeouts, and other HTTP client settings. It has no dependencies on any job system.
Instance Attribute Summary collapse
-
#completion_retries ⇒ Integer
Number of retries when delivering a completed result fails.
-
#completion_threads ⇒ Integer
Number of threads that deliver completed results.
-
#connection_pool_size ⇒ Integer
This is the maximum number of hosts for which connections will be kept alive for at one time.
-
#connection_timeout ⇒ Numeric?
Connection timeout in seconds.
-
#default_payload_store_name ⇒ Symbol?
readonly
Get the name of the default payload store.
-
#logger ⇒ Logger
Get the logger to use to report pool events.
-
#max_connections ⇒ Integer
Maximum number of concurrent connections.
-
#max_connections_per_host ⇒ Integer?
Maximum number of connections per host (nil for unlimited).
-
#max_redirects ⇒ Integer
Maximum number of redirects to follow (0 disables redirects).
-
#max_response_size ⇒ Integer
Maximum response size in bytes.
-
#protocol ⇒ Symbol?
HTTP protocol to use (:http1 or :http2).
-
#proxy_url ⇒ String?
HTTP/HTTPS proxy URL (supports authentication).
-
#raise_error_responses ⇒ Boolean
Whether to raise HttpError for non-2xx responses by default.
-
#request_timeout ⇒ Numeric
Default request timeout in seconds.
-
#retries ⇒ Integer
Number of retries for failed requests.
-
#secret_manager ⇒ SecretManager
readonly
The secret manager instance.
-
#shutdown_timeout ⇒ Numeric
Graceful shutdown timeout in seconds.
-
#user_agent ⇒ String?
Default User-Agent header value.
Instance Method Summary collapse
-
#decryption(callable = nil) {|data| ... } ⇒ Object
Set the decryption callable for decrypting payloads after deserialization.
-
#encryption(callable = nil) {|data| ... } ⇒ Object
Set the encryption callable for encrypting payloads before serialization.
- #encryption_key=(keys) ⇒ Object
-
#encryptor ⇒ Encryptor
Return an Encryptor instance.
-
#initialize(max_connections: 256, request_timeout: 60, shutdown_timeout: 30, logger: nil, max_response_size: 1024 * 1024, user_agent: "PatientHttp", raise_error_responses: false, max_redirects: 5, connection_pool_size: 100, connection_timeout: nil, proxy_url: nil, retries: 3, protocol: nil, encryption_key: nil, max_connections_per_host: nil, completion_threads: 2, completion_retries: 2) ⇒ Configuration
constructor
Initializes a new Configuration with the specified options.
-
#payload_store(name = nil) ⇒ PayloadStore::Base?
Get a registered payload store by name.
-
#payload_stores ⇒ Hash{Symbol => PayloadStore::Base}
Get all registered payload stores.
-
#preprocessor(name) ⇒ #call?
Get a registered preprocessor by name.
-
#register_payload_store(name, adapter:, **options) ⇒ void
Register a payload store for external storage of large payloads.
-
#register_preprocessor(name, callable = nil) {|outgoing_request| ... } ⇒ void
Register a named preprocessor that can be attached to requests to modify them just before they are sent -- for example, to sign requests.
-
#register_secret(name, value = nil) {|name| ... } ⇒ void
Register a named secret whose value can be referenced indirectly when building requests via secret.
-
#to_h ⇒ Hash
Convert to hash for inspection.
Constructor Details
#initialize(max_connections: 256, request_timeout: 60, shutdown_timeout: 30, logger: nil, max_response_size: 1024 * 1024, user_agent: "PatientHttp", raise_error_responses: false, max_redirects: 5, connection_pool_size: 100, connection_timeout: nil, proxy_url: nil, retries: 3, protocol: nil, encryption_key: nil, max_connections_per_host: nil, completion_threads: 2, completion_retries: 2) ⇒ Configuration
Initializes a new Configuration with the specified options.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/patient_http/configuration.rb', line 87 def initialize( max_connections: 256, request_timeout: 60, shutdown_timeout: 30, logger: nil, max_response_size: 1024 * 1024, user_agent: "PatientHttp", raise_error_responses: false, max_redirects: 5, connection_pool_size: 100, connection_timeout: nil, proxy_url: nil, retries: 3, protocol: nil, encryption_key: nil, max_connections_per_host: nil, completion_threads: 2, completion_retries: 2 ) @mutex = Mutex.new # Initialize payload store configuration @payload_stores = {} @default_payload_store_name = nil # Initialize secret configuration @secrets = {} @secret_manager = SecretManager.new # Initialize preprocessor registry @preprocessors = {} @encryptor = nil self.max_connections = max_connections self.request_timeout = request_timeout self.shutdown_timeout = shutdown_timeout self.logger = logger || Logger.new($stderr, level: Logger::ERROR) self.max_response_size = max_response_size self.user_agent = user_agent self.raise_error_responses = raise_error_responses self.max_redirects = max_redirects self.connection_pool_size = connection_pool_size self.connection_timeout = connection_timeout self.proxy_url = proxy_url self.retries = retries self.protocol = protocol self.encryption_key = encryption_key self.max_connections_per_host = max_connections_per_host self.completion_threads = completion_threads self.completion_retries = completion_retries end |
Instance Attribute Details
#completion_retries ⇒ Integer
Returns Number of retries when delivering a completed result fails. A retry calls the task handler again, so handlers must be idempotent.
26 27 28 |
# File 'lib/patient_http/configuration.rb', line 26 def completion_retries @completion_retries end |
#completion_threads ⇒ Integer
Returns Number of threads that deliver completed results.
22 23 24 |
# File 'lib/patient_http/configuration.rb', line 22 def completion_threads @completion_threads end |
#connection_pool_size ⇒ Integer
Returns This is the maximum number of hosts for which connections will be kept alive for at one time.
48 49 50 |
# File 'lib/patient_http/configuration.rb', line 48 def connection_pool_size @connection_pool_size end |
#connection_timeout ⇒ Numeric?
Returns Connection timeout in seconds.
51 52 53 |
# File 'lib/patient_http/configuration.rb', line 51 def connection_timeout @connection_timeout end |
#default_payload_store_name ⇒ Symbol? (readonly)
Get the name of the default payload store.
407 408 409 |
# File 'lib/patient_http/configuration.rb', line 407 def default_payload_store_name @default_payload_store_name end |
#logger ⇒ Logger
Get the logger to use to report pool events. Default is to log errors to STDERR.
142 143 144 |
# File 'lib/patient_http/configuration.rb', line 142 def logger @logger end |
#max_connections ⇒ Integer
Returns Maximum number of concurrent connections.
16 17 18 |
# File 'lib/patient_http/configuration.rb', line 16 def max_connections @max_connections end |
#max_connections_per_host ⇒ Integer?
Returns Maximum number of connections per host (nil for unlimited).
19 20 21 |
# File 'lib/patient_http/configuration.rb', line 19 def max_connections_per_host @max_connections_per_host end |
#max_redirects ⇒ Integer
Returns Maximum number of redirects to follow (0 disables redirects).
44 45 46 |
# File 'lib/patient_http/configuration.rb', line 44 def max_redirects @max_redirects end |
#max_response_size ⇒ Integer
Returns Maximum response size in bytes.
35 36 37 |
# File 'lib/patient_http/configuration.rb', line 35 def max_response_size @max_response_size end |
#protocol ⇒ Symbol?
Returns HTTP protocol to use (:http1 or :http2). When nil, the protocol is negotiated with the server (HTTP/2 preferred for HTTPS).
61 62 63 |
# File 'lib/patient_http/configuration.rb', line 61 def protocol @protocol end |
#proxy_url ⇒ String?
Returns HTTP/HTTPS proxy URL (supports authentication).
54 55 56 |
# File 'lib/patient_http/configuration.rb', line 54 def proxy_url @proxy_url end |
#raise_error_responses ⇒ Boolean
Returns Whether to raise HttpError for non-2xx responses by default.
41 42 43 |
# File 'lib/patient_http/configuration.rb', line 41 def raise_error_responses @raise_error_responses end |
#request_timeout ⇒ Numeric
Returns Default request timeout in seconds.
29 30 31 |
# File 'lib/patient_http/configuration.rb', line 29 def request_timeout @request_timeout end |
#retries ⇒ Integer
Returns Number of retries for failed requests.
57 58 59 |
# File 'lib/patient_http/configuration.rb', line 57 def retries @retries end |
#secret_manager ⇒ SecretManager (readonly)
Returns the secret manager instance.
64 65 66 |
# File 'lib/patient_http/configuration.rb', line 64 def secret_manager @secret_manager end |
#shutdown_timeout ⇒ Numeric
Returns Graceful shutdown timeout in seconds.
32 33 34 |
# File 'lib/patient_http/configuration.rb', line 32 def shutdown_timeout @shutdown_timeout end |
#user_agent ⇒ String?
Returns Default User-Agent header value.
38 39 40 |
# File 'lib/patient_http/configuration.rb', line 38 def user_agent @user_agent end |
Instance Method Details
#decryption(callable = nil) {|data| ... } ⇒ Object
Set the decryption callable for decrypting payloads after deserialization.
248 249 250 251 |
# File 'lib/patient_http/configuration.rb', line 248 def decryption(callable = nil, &block) @decryption = resolve_callable(:decryption, callable, &block) @encryptor = nil end |
#encryption(callable = nil) {|data| ... } ⇒ Object
Set the encryption callable for encrypting payloads before serialization.
238 239 240 241 |
# File 'lib/patient_http/configuration.rb', line 238 def encryption(callable = nil, &block) @encryption = resolve_callable(:encryption, callable, &block) @encryptor = nil end |
#encryption_key=(keys) ⇒ Object
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/patient_http/configuration.rb', line 253 def encryption_key=(keys) keys = Array(keys).map(&:to_s).reject(&:empty?) if keys.empty? @encryption = nil @decryption = nil @encryptor = nil return end unless defined?(ActiveSupport::MessageEncryptor) begin require "active_support/key_generator" require "active_support/message_encryptor" rescue LoadError raise ArgumentError.new("ActiveSupport::MessageEncryptor is required for encryption_key") end end key_length = ActiveSupport::MessageEncryptor.key_len key_generator = lambda do |key| ActiveSupport::KeyGenerator.new(key).generate_key(SALT, key_length) end encryptor = ActiveSupport::MessageEncryptor.new(key_generator.call(keys.first), cipher: "aes-256-gcm") keys[1..].each { |key| encryptor.rotate(key_generator.call(key)) } encryption { |data| encryptor.encrypt_and_sign(data) } decryption { |data| encryptor.decrypt_and_verify(data) } @encryptor = nil end |
#encryptor ⇒ Encryptor
Return an Encryptor instance. If encryption and decryption are not set, then this will be an empty Encryptor that returns data unchanged.
288 289 290 |
# File 'lib/patient_http/configuration.rb', line 288 def encryptor @encryptor ||= Encryptor.new(encryption: @encryption, decryption: @decryption) end |
#payload_store(name = nil) ⇒ PayloadStore::Base?
Get a registered payload store by name.
394 395 396 397 398 399 400 401 402 |
# File 'lib/patient_http/configuration.rb', line 394 def payload_store(name = nil) if name.nil? return nil unless @default_payload_store_name @payload_stores[@default_payload_store_name] else @payload_stores[name.to_sym] end end |
#payload_stores ⇒ Hash{Symbol => PayloadStore::Base}
Get all registered payload stores.
412 413 414 |
# File 'lib/patient_http/configuration.rb', line 412 def payload_stores @payload_stores.dup end |
#preprocessor(name) ⇒ #call?
Get a registered preprocessor by name.
352 353 354 |
# File 'lib/patient_http/configuration.rb', line 352 def preprocessor(name) @preprocessors[name.to_s] end |
#register_payload_store(name, adapter:, **options) ⇒ void
This method returns an undefined value.
Register a payload store for external storage of large payloads.
The name is included in the serialized references to the stored data. Changing it will cause any existing reference to become invalid.
Multiple stores can be registered for migration purposes. The last store registered becomes the default used for new writes. References to other registered stores remain valid for reading.
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/patient_http/configuration.rb', line 370 def register_payload_store(name, adapter:, **) name = name.to_sym adapter = adapter.to_sym # Trigger autoload for common adapters ensure_adapter_loaded(adapter) unless PayloadStore::Base.lookup(adapter) raise ArgumentError, "Unknown payload store adapter: #{adapter.inspect}. " \ "Available adapters: #{PayloadStore::Base.registered_adapters.inspect}" end store = PayloadStore::Base.create(adapter, **) @mutex.synchronize do @payload_stores = @payload_stores.merge(name => store) @default_payload_store_name = name end end |
#register_preprocessor(name, callable = nil) {|outgoing_request| ... } ⇒ void
This method returns an undefined value.
Register a named preprocessor that can be attached to requests to modify them just before they are sent -- for example, to sign requests.
The preprocessor can be provided as a callable or a block taking a single argument. When a request that references the preprocessor is sent, it is invoked with an OutgoingRequest after secret references have been resolved and the x-request-id and default user-agent headers have been set. It can change the request headers and append query parameters.
Requests reference preprocessors by name only, so the callable (and any credentials it uses) stays on the processor side and is never serialized.
337 338 339 340 341 342 343 344 345 346 |
# File 'lib/patient_http/configuration.rb', line 337 def register_preprocessor(name, callable = nil, &block) preprocessor = resolve_callable(:preprocessor, callable, &block) raise ArgumentError.new("register_preprocessor requires a callable or a block") if preprocessor.nil? validate_preprocessor_parameters!(preprocessor) @mutex.synchronize do @preprocessors = @preprocessors.merge(name.to_s => preprocessor) end end |
#register_secret(name, value = nil) {|name| ... } ⇒ void
This method returns an undefined value.
Register a named secret whose value can be referenced indirectly when building requests via PatientHttp.secret.
The value can be provided directly or as a block (callable). A block is invoked lazily with the secret name each time the secret is resolved, which is useful for values that should be read on demand (for example, from the environment).
304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/patient_http/configuration.rb', line 304 def register_secret(name, value = nil, &block) if value.nil? && block.nil? raise ArgumentError.new("register_secret requires a value or a block") end if !value.nil? && block raise ArgumentError.new("register_secret accepts either a value or a block, not both") end @mutex.synchronize do @secrets[name.to_s] = block || value @secret_manager = SecretManager.new(secrets: @secrets.dup) end end |
#to_h ⇒ Hash
Convert to hash for inspection
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 |
# File 'lib/patient_http/configuration.rb', line 418 def to_h { "max_connections" => max_connections, "request_timeout" => request_timeout, "shutdown_timeout" => shutdown_timeout, "logger" => logger, "max_response_size" => max_response_size, "user_agent" => user_agent, "raise_error_responses" => raise_error_responses, "max_redirects" => max_redirects, "connection_pool_size" => connection_pool_size, "connection_timeout" => connection_timeout, "proxy_url" => proxy_url, "retries" => retries, "protocol" => protocol, "max_connections_per_host" => max_connections_per_host, "completion_threads" => completion_threads, "completion_retries" => completion_retries, "payload_stores" => payload_stores.keys, "default_payload_store" => default_payload_store_name, "secrets" => @mutex.synchronize { @secrets.keys }, "preprocessors" => @mutex.synchronize { @preprocessors.keys } } end |