module Semian::Redis
def connect
def connect acquire_semian_resource(adapter: :redis, scope: :connection) do raw_connect rescue SocketError, RuntimeError => e raise ResolveError, semian_identifier if dns_resolve_failure?(e.cause || e) raise end end
def dns_resolve_failure?(e)
def dns_resolve_failure?(e) e.to_s.match?(/(can't resolve)|(name or service not known)|(nodename nor servname provided, or not known)|(failure in name resolution)/i) # rubocop:disable Layout/LineLength end
def included(base)
def included(base) base.send(:alias_method, :raw_io, :io) base.send(:remove_method, :io) base.send(:alias_method, :raw_connect, :connect) base.send(:remove_method, :connect) end
def io(&block)
def io(&block) acquire_semian_resource(adapter: :redis, scope: :query) do reply = raw_io(&block) raise_if_out_of_memory(reply) reply end end
def raise_if_out_of_memory(reply)
def raise_if_out_of_memory(reply) return unless reply.is_a?(::Redis::CommandError) return unless reply.message =~ /OOM command not allowed when used memory > 'maxmemory'/ raise ::Redis::OutOfMemoryError, reply.message end
def raw_semian_options
def raw_semian_options return options[:semian] if options.key?(:semian) return options["semian"] if options.key?("semian") end
def resource_exceptions
def resource_exceptions [ ::Redis::BaseConnectionError, ::Errno::EINVAL, # Hiredis bug: https://github.com/redis/hiredis-rb/issues/21 ::Redis::OutOfMemoryError, ] end
def semian_identifier
def semian_identifier @semian_identifier ||= begin name = semian_options && semian_options[:name] name ||= "#{location}/#{db}" :"redis_#{name}" end end
def with_resource_timeout(temp_timeout)
def with_resource_timeout(temp_timeout) timeout = options[:timeout] connect_timeout = options[:connect_timeout] read_timeout = options[:read_timeout] write_timeout = options[:write_timeout] begin connection.timeout = temp_timeout if connected? options[:timeout] = Float(temp_timeout) options[:connect_timeout] = Float(temp_timeout) options[:read_timeout] = Float(temp_timeout) options[:write_timeout] = Float(temp_timeout) yield ensure options[:timeout] = timeout options[:connect_timeout] = connect_timeout options[:read_timeout] = read_timeout options[:write_timeout] = write_timeout connection.timeout = self.timeout if connected? end end