module Semian::Adapter
def acquire_semian_resource(scope:, adapter:, &block)
def acquire_semian_resource(scope:, adapter:, &block) return yield if resource_already_acquired? semian_resource.acquire(scope: scope, adapter: adapter, resource: self) do mark_resource_as_acquired(&block) end rescue ::Semian::OpenCircuitError => error last_error = semian_resource.circuit_breaker.last_error message = "#{error.message} caused by #{last_error.message}" last_error = nil unless last_error.is_a?(Exception) # Net::HTTPServerError is not an exception raise self.class::CircuitOpenError.new(semian_identifier, message), cause: last_error rescue ::Semian::BaseError => error raise self.class::ResourceBusyError.new(semian_identifier, error.message) rescue *resource_exceptions => error error.semian_identifier = semian_identifier if error.respond_to?(:semian_identifier=) raise end
def clear_semian_resource
def clear_semian_resource @semian_resource = nil end
def mark_resource_as_acquired
def mark_resource_as_acquired previous = @resource_acquired @resource_acquired = true yield ensure @resource_acquired = previous end
def raw_semian_options
def raw_semian_options raise NotImplementedError, "Semian adapters must implement a `raw_semian_options` method" end
def resource_already_acquired?
def resource_already_acquired? @resource_acquired end
def resource_exceptions
def resource_exceptions raise NotImplementedError, "Semian adapters must implement a `resource_exceptions` method" end
def semian_identifier
def semian_identifier raise NotImplementedError, "Semian adapters must implement a `semian_identifier` method" end
def semian_options
def semian_options return @semian_options if defined? @semian_options options = raw_semian_options symbolized_options = options && options.transform_keys(&:to_sym) # rubocop:disable Style/SafeNavigation symbolized_options.tap do @semian_options = symbolized_options if !symbolized_options || !symbolized_options.fetch(:dynamic, false) end end
def semian_resource
def semian_resource return @semian_resource if @semian_resource case semian_options when false @semian_resource = UnprotectedResource.new(semian_identifier) when nil Semian.logger.info("Semian is not configured for #{self.class.name}: #{semian_identifier}") @semian_resource = UnprotectedResource.new(semian_identifier) else options = semian_options.dup options.delete(:name) options[:consumer] = self options[:exceptions] ||= [] options[:exceptions] += resource_exceptions resource = ::Semian.retrieve_or_register(semian_identifier, **options) @semian_resource = resource unless options.fetch(:dynamic, false) resource end end