Module: Hooksmith::Idempotency
- Defined in:
- lib/hooksmith/idempotency.rb
Overview
Provides idempotency support for webhook processing.
Idempotency ensures that processing the same webhook multiple times (due to retries, network issues, etc.) produces the same result and doesn't cause duplicate side effects.
Defined Under Namespace
Modules: Extractors
Class Method Summary collapse
-
.already_processed?(provider:, key:) ⇒ Boolean
Checks if an event with the given idempotency key was already processed.
-
.composite_key(*fields, separator: ':') ⇒ String
Generates a composite idempotency key from multiple fields.
-
.extract_key(provider:, payload:) ⇒ String?
Extracts an idempotency key from a webhook payload.
Class Method Details
.already_processed?(provider:, key:) ⇒ Boolean
Checks if an event with the given idempotency key was already processed.
This requires the event store to be enabled and the model to respond to
exists_with_idempotency_key? or have a find_by_idempotency_key method.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/hooksmith/idempotency.rb', line 51 def already_processed?(provider:, key:) return false if key.nil? config = Hooksmith.configuration.event_store_config return false unless config.enabled model_class = config.model_class return false unless model_class check_duplicate(model_class, provider.to_s, key) rescue StandardError => e Hooksmith.logger.error("Failed to check idempotency for #{provider}: #{e.}") false end |
.composite_key(*fields, separator: ':') ⇒ String
Generates a composite idempotency key from multiple fields.
71 72 73 |
# File 'lib/hooksmith/idempotency.rb', line 71 def composite_key(*fields, separator: ':') fields.compact.map(&:to_s).join(separator) end |
.extract_key(provider:, payload:) ⇒ String?
Extracts an idempotency key from a webhook payload.
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/hooksmith/idempotency.rb', line 32 def extract_key(provider:, payload:) extractor = Hooksmith.configuration.idempotency_key_for(provider) return nil unless extractor key = extractor.call(payload) key&.to_s rescue StandardError => e Hooksmith.logger.error("Failed to extract idempotency key for #{provider}: #{e.}") nil end |