class PseudoCleaner::RedisCleaner

I’m not a huge fan of sleeps. In the non-rails world, I used to be able to do a sleep(0) to signal the system to check if somebody else needed to do some work. Testing with Rails, I find I have to actually sleep, so I do a very short time like 0.01.

Constants

ALL_COMMANDS
COMMANDS

copied from Redis::Namespace

FLUSH_COMMANDS
NIL_FAIL_COMMANDS
NUM_CHANGED_COMMANDS
OVERRIDE_COMMANDS
POP_COMMANDS
READ_COMMANDS
WRITE_COMMANDS

Attributes

options[RW]

Public Class Methods

new(start_method, end_method, table, options) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 351
def initialize(start_method, end_method, table, options)
  @redis      = table
  @redis_name = nil

  clear_set :@initial_keys
  clear_set :@suite_altered_keys
  clear_set :@updated_keys
  clear_list_array :@read_keys
  clear_list_array :@multi_commands
  set_value_bool :@in_multi, false
  set_value_bool :@in_redis_cleanup, false
  set_value_bool :@suspend_tracking, false

  unless PseudoCleaner::MasterCleaner::VALID_START_METHODS.include?(start_method)
    raise "You must specify a valid start function from: #{PseudoCleaner::MasterCleaner::VALID_START_METHODS}."
  end
  unless PseudoCleaner::MasterCleaner::VALID_END_METHODS.include?(end_method)
    raise "You must specify a valid end function from: #{PseudoCleaner::MasterCleaner::VALID_END_METHODS}."
  end

  @options = options

  @options[:table_start_method] ||= start_method
  @options[:table_end_method]   ||= end_method
  @options[:output_diagnostics] ||= PseudoCleaner::Configuration.current_instance.output_diagnostics ||
      PseudoCleaner::Configuration.current_instance.post_transaction_analysis
end

Public Instance Methods

<=>(right_object) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 582
def <=>(right_object)
  if (right_object.is_a?(PseudoCleaner::RedisCleaner))
    return 0
  elsif (right_object.is_a?(PseudoCleaner::TableCleaner))
    return 1
  else
    if right_object.respond_to?(:<=>)
      comparison = (right_object <=> self)
      if comparison
        return -1 * comparison
      end
    end
  end

  return 1
end
add_set_value(value_name, value) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1019
def add_set_value(value_name, value)
  set = get_set(value_name)

  set << value
end
add_set_values(value_name, *values) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1013
def add_set_values(value_name, *values)
  set = get_set(value_name)

  set.merge(values)
end
append_list_value_array(value_name, array_value) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 988
def append_list_value_array(value_name, array_value)
  array = instance_variable_get(value_name)
  array << array_value
end
clear_list_array(value_name) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1001
def clear_list_array(value_name)
  instance_variable_set(value_name, [])
end
clear_set(value_name, keys = nil) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1005
def clear_set(value_name, keys = nil)
  if keys
    instance_variable_set(value_name, SortedSet.new(keys))
  else
    instance_variable_set(value_name, SortedSet.new)
  end
end
extract_key(arg) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 506
def extract_key(arg)
  if arg.is_a?(Array)
    arg
  elsif arg.is_a?(Hash)
    arg.keys
  else
    [arg]
  end
end
extract_keys(command, *args) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 516
def extract_keys(command, *args)
  handling     = OVERRIDE_COMMANDS[command.to_s.downcase] || PseudoCleaner::RedisCleaner::COMMANDS[command.to_s.downcase]
  message_keys = []

  (before, after) = handling

  case before
    when :first
      if args[0]
        extract_key(args[0]).each do |key|
          message_keys << key
        end
      end

    when :all
      args.each do |arg|
        extract_key(arg).each do |key|
          message_keys << key
        end
      end

    when :exclude_first
      args.each do |arg|
        extract_key(arg).each do |key|
          message_keys << key
        end
      end
      message_keys.shift

    when :exclude_last
      args.each do |arg|
        extract_key(arg).each do |key|
          message_keys << key
        end
      end
      message_keys.pop unless message_keys.length == 1

    when :exclude_options
      args.each do |arg|
        message_keys << arg unless arg.is_a?(Hash)
      end

    when :alternate
      args.each_with_index do |arg, i|
        if i.even?
          extract_key(arg).each do |key|
            message_keys << key
          end
        end
      end

    when :sort
      if args[-1].is_a?(Hash)
        if args[-1][:store] || args[-1]["store"]
          message_keys << (args[-1][:store] || args[-1]["store"])
        end
      end

    # when :eval_style
    #
    # when :scan_style
  end

  message_keys
end
get_list_array(value_name) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 997
def get_list_array(value_name)
  instance_variable_get(value_name)
end
get_list_length(value_name) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 993
def get_list_length(value_name)
  instance_variable_get(value_name).length
end
get_set(value_name) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1037
def get_set(value_name)
  set = instance_variable_get(value_name)

  unless set
    set = SortedSet.new
    instance_variable_set(value_name, set)
  end

  set
end
get_value_bool(value_name) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 984
def get_value_bool(value_name)
  instance_variable_get(value_name)
end
ignore_key(key) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 708
def ignore_key(key)
  ignore_regexes.detect { |ignore_regex| key =~ ignore_regex }
end
ignore_regexes() click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 704
def ignore_regexes
  []
end
method_missing(command, *args, &block) click to toggle source
Calls superclass method
# File lib/pseudo_cleaner/redis_cleaner.rb, line 392
def method_missing(command, *args, &block)
  normalized_command = command.to_s.downcase

  if redis.respond_to?(normalized_command)
    if (normalized_command == "pipelined" ||
        (normalized_command == "multi" && block)) &&
        !get_value_bool(:@suspend_tracking)
      set_value_bool :@in_multi, true
      normalized_command = "exec"
    end

    initial_keys = nil
    if FLUSH_COMMANDS.include?(normalized_command)
      initial_keys = get_set(:@initial_keys)
    end

    response = redis.send(command, *args, &block)

    if FLUSH_COMMANDS.include?(normalized_command)
      add_set_values :@updated_keys, *initial_keys.to_a
    end

    if get_value_bool(:@in_multi) && !(["exec", "discard"].include?(normalized_command))
      append_list_value_array :@multi_commands, [normalized_command, *args]
    else
      process_command(response, normalized_command, *args)
    end

    response
  else
    super
  end
end
peek_values() click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 739
def peek_values
  time = Benchmark.measure do
    puts "  RedisCleaner(#{redis_name})" if PseudoCleaner::Configuration.instance.benchmark

    synchronize_test_values do |updated_values, read_values|
      if (updated_values && !updated_values.empty?) || (read_values && !read_values.empty?)
        output_values = false

        updated_values = updated_values.select do |value|
          value, read_value = split_read_values(value)
          !ignore_key(value)
        end
        read_values    = read_values.select do |value|
          value, read_value = split_read_values(value)
          !ignore_key(value)
        end

        if PseudoCleaner::MasterCleaner.report_table
          Cornucopia::Util::ReportTable.new(nested_table:         PseudoCleaner::MasterCleaner.report_table,
                                            nested_table_label:   redis_name,
                                            suppress_blank_table: true) do |report_table|
            updated_values.each_with_index do |updated_value, index|
              updated_value, read_value = split_read_values(updated_value)
              unless ignore_key(updated_value)
                output_values = true
                report_table.write_stats index.to_s, report_record(updated_value)
                report_table.write_stats "", read_value if read_value
              end
            end
          end

          if track_reads
            Cornucopia::Util::ReportTable.new(nested_table:         PseudoCleaner::MasterCleaner.report_table,
                                              nested_table_label:   "#{redis_name} - reads",
                                              suppress_blank_table: true) do |report_table|
              read_values.each_with_index do |updated_value, index|
                updated_value, read_value = split_read_values(updated_value)
                unless ignore_key(updated_value)
                  output_values = true
                  report_table.write_stats index.to_s, report_record(updated_value)
                  report_table.write_stats "", read_value if read_value
                end
              end
            end
          end
        else
          PseudoCleaner::Logger.write("  #{redis_name}")

          updated_values.each_with_index do |updated_value, index|
            updated_value, read_value = split_read_values(updated_value)
            unless ignore_key(updated_value)
              output_values = true
              PseudoCleaner::Logger.write("    #{index}: #{report_record(updated_value)}")
              PseudoCleaner::Logger.write("       #{read_value}") if read_value
            end
          end

          if track_reads
            PseudoCleaner::Logger.write("  #{redis_name} - reads")

            read_values.each_with_index do |updated_value, index|
              updated_value, read_value = split_read_values(updated_value)
              unless ignore_key(updated_value)
                output_values = true
                PseudoCleaner::Logger.write("    #{index}: #{report_record(updated_value)}")
                PseudoCleaner::Logger.write("       #{read_value}") if read_value
              end
            end
          end
        end

        PseudoCleaner::MasterCleaner.report_error if output_values
      end
    end
  end

  puts "  RedisCleaner(#{redis_name}) time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
process_command(response, *args) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 426
def process_command(response, *args)
  unless get_value_bool(:@in_redis_cleanup) || get_value_bool(:@suspend_tracking)
    if "multi" == args[0]
      set_value_bool :@in_multi, true
      clear_list_array :@multi_commands
    elsif ["exec", "pipelined"].include?(args[0])
      begin
        if (!response && get_list_length(:@multi_commands) > 0) ||
            (response && response.length != get_list_length(:@multi_commands))
          puts "exec response does not match sent commands.\n  response: #{response}\n  commands: #{get_list_array(:@multi_commands)}"

          # make the response length match the commands length.
          # so far the only time this has happened was when a multi returned nil which SHOULD indicate a failure
          #
          # I am assuming that the multi failed in this case, but even if so, it is safest for tracking purposes
          # to assume that redis DID change and record it as such.  Even if I am wrong, for the cleaner, it
          # doesn't matter, and there is no harm.
          response ||= []
          get_list_array(:@multi_commands).each_with_index do |command, index|
            if response.length < index
              response << true
            end
          end
        end

        get_list_array(:@multi_commands).each_with_index do |command, index|
          process_command(response[index], *command)
        end
      ensure
        set_value_bool :@in_multi, false
        clear_list_array :@multi_commands
      end
    elsif "discard" == args[0]
      set_value_bool :@in_multi, false
      clear_list_array :@multi_commands
    elsif WRITE_COMMANDS.include?(args[0])
      add_set_values :@updated_keys, *extract_keys(*args)
    elsif NUM_CHANGED_COMMANDS.include?(args[0])
      update_key = true
      if [true, false].include?(response)
        update_key = response
      else
        update_key = response > 0 rescue true
      end

      if update_key
        add_set_values :@updated_keys, *extract_keys(*args)
      end
    elsif POP_COMMANDS.include?(args[0])
      if response
        add_set_value :@updated_keys, response[0]
      end
    elsif NIL_FAIL_COMMANDS.include?(args[0])
      if response
        add_set_values :@updated_keys, *extract_keys(*args)
      end
    elsif track_reads && READ_COMMANDS.include?(args[0])
      keys = extract_keys(*args)
      append_list_value_array(:@read_keys,
                              [
                                  keys.length,
                                  *keys,
                                  response.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
                              ]
      )
    end
  end
end
redis() click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 599
def redis
  @redis ||= Redis.current
end
redis_name() click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 712
def redis_name
  unless @redis_name
    redis_options = redis.client.options.with_indifferent_access
    @redis_name   = "#{redis_options[:host]}:#{redis_options[:port]}/#{redis_options[:db]}"
  end

  @redis_name
end
remove_set_value(value_name, value) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1025
def remove_set_value(value_name, value)
  set = get_set(value_name)

  set.delete value
end
report_dirty_values(message, test_values) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 944
def report_dirty_values message, test_values
  test_values = test_values.select { |value| !ignore_key(split_read_values(value)[0]) }

  if test_values && !test_values.empty?
    output_values = false

    if PseudoCleaner::MasterCleaner.report_table
      Cornucopia::Util::ReportTable.new(nested_table:         PseudoCleaner::MasterCleaner.report_table,
                                        nested_table_label:   redis_name,
                                        suppress_blank_table: true) do |report_table|
        report_table.write_stats "action", message
        test_values.each_with_index do |key_name, index|
          key_name, read_value = split_read_values(key_name)
          unless ignore_key(key_name)
            output_values = true
            report_table.write_stats index, report_record(key_name)
            report_table.write_stats("", read_value) if read_value
          end
        end
      end
    else
      test_values.each do |key_name|
        key_name, read_value = split_read_values(key_name)
        unless ignore_key(key_name)
          PseudoCleaner::Logger.write("********* RedisCleaner - #{message}".red.on_light_white) unless output_values
          output_values = true
          PseudoCleaner::Logger.write("  #{key_name}: #{report_record(key_name)}".red.on_light_white)
          PseudoCleaner::Logger.write("     #{read_value}".red.on_light_white) if read_value
        end
      end
    end

    PseudoCleaner::MasterCleaner.report_error if output_values
  end
end
report_end_of_suite_state(report_reason) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 818
def report_end_of_suite_state report_reason
  current_keys = SortedSet.new(redis.keys)

  initial_key_set = get_set(:@initial_keys)

  deleted_keys = initial_key_set - current_keys
  new_keys     = current_keys - initial_key_set

  # filter out values we inserted that will go away on their own.
  new_keys     = new_keys.select { |key| (key =~ /redis_cleaner::synchronization_(?:end_)?key_[0-9]+_[0-9]+/).nil? }

  report_dirty_values "new values as of #{report_reason}", new_keys
  report_dirty_values "values deleted before #{report_reason}", deleted_keys
  report_dirty_values "initial values changed during suite run", get_set(:@suite_altered_keys)

  clear_set :@suite_altered_keys

  new_keys
end
report_record(key_name) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 906
def report_record(key_name)
  key_hash = { key: key_name, type: redis.type(key_name), ttl: redis.ttl(key_name) }
  case key_hash[:type]
    when "string"
      key_hash[:value] = redis.get(key_name)
    when "list"
      key_hash[:list] = { len: redis.llen(key_name), values: redis.lrange(key_name, 0, -1) }
    when "set"
      key_hash[:set] = { len: redis.scard(key_name), values: redis.smembers(key_name) }
    when "zset"
      sorted_set_values = redis.zrange(key_name, 0, -1).reduce({}) do |hash, set_value|
        hash[set_value] = redis.zscore(key_name, set_value)
        hash
      end

      key_hash[:sorted_set] = { len: redis.zcard(key_name), values: sorted_set_values }
    when "hash"
      key_hash[:hash] = { len: redis.hlen(key_name), values: redis.hgetall(key_name) }
  end

  if key_hash[:value].nil? &&
      key_hash[:list].nil? &&
      key_hash[:set].nil? &&
      key_hash[:sorted_set].nil? &&
      key_hash[:hash].nil?
    key_hash[:value] = "[[DELETED]]"
  end

  key_hash
end
reset_suite() click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 692
def reset_suite
  time = Benchmark.measure do
    puts "  RedisCleaner(#{redis_name})" if PseudoCleaner::Configuration.instance.benchmark

    report_end_of_suite_state "reset suite"

    start_monitor
  end

  puts "  RedisCleaner(#{redis_name}) time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
respond_to?(command, include_private=false) click to toggle source

emulate Ruby 1.9+ and keep respond_to_missing? logic together.

Calls superclass method
# File lib/pseudo_cleaner/redis_cleaner.rb, line 388
def respond_to?(command, include_private=false)
  super or respond_to_missing?(command, include_private)
end
Also aliased as: self_respond_to?
respond_to_missing?(command, include_all=false) click to toggle source
Calls superclass method
# File lib/pseudo_cleaner/redis_cleaner.rb, line 495
def respond_to_missing?(command, include_all=false)
  return true if ALL_COMMANDS.include?(command.to_s.downcase)

  # blind passthrough is deprecated and will be removed in 2.0
  if redis.respond_to?(command, include_all)
    return true
  end

  defined?(super) && super
end
review_rows(&block) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 721
def review_rows(&block)
  time = Benchmark.measure do
    puts "  RedisCleaner(#{redis_name})" if PseudoCleaner::Configuration.instance.benchmark

    synchronize_test_values do |updated_values, read_values|
      if updated_values && !updated_values.empty?
        updated_values.each do |updated_value|
          unless ignore_key(updated_value)
            block.yield redis_name, report_record(updated_value)
          end
        end
      end
    end
  end

  puts "  RedisCleaner(#{redis_name}) time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
self_respond_to?(command, include_private=false)
Alias for: respond_to?
set_includes?(value_name, value) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1031
def set_includes?(value_name, value)
  set = get_set(value_name)

  set.include?(value)
end
set_value_bool(value_name, bool_value) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 980
def set_value_bool(value_name, bool_value)
  instance_variable_set(value_name, bool_value)
end
split_read_values(key) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 937
def split_read_values(key)
  split = Array.wrap(key)
  split << nil if split.length < 2

  split
end
start_monitor() click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 881
def start_monitor
  redis_keys = redis.keys
  clear_set :@initial_keys, redis_keys
  clear_set :@suite_altered_keys
  clear_set :@updated_keys
  clear_list_array :@read_keys
  clear_list_array :@multi_commands
  set_value_bool :@in_multi, false
  set_value_bool :@in_redis_cleanup, false
  set_value_bool :@suspend_tracking, false

  if @options[:output_diagnostics]
    if PseudoCleaner::MasterCleaner.report_table
      Cornucopia::Util::ReportTable.new(nested_table:         PseudoCleaner::MasterCleaner.report_table,
                                        nested_table_label:   redis_name,
                                        suppress_blank_table: true) do |report_table|
        report_table.write_stats "initial keys count", redis_keys.count
      end
    else
      PseudoCleaner::Logger.write("#{redis_name}")
      PseudoCleaner::Logger.write("    Initial keys count - #{redis_keys.count}")
    end
  end
end
suite_end(test_strategy) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 678
def suite_end test_strategy
  time = Benchmark.measure do
    puts "  RedisCleaner(#{redis_name})" if PseudoCleaner::Configuration.instance.benchmark

    new_keys = report_end_of_suite_state "suite end"

    new_keys.each do |key_value|
      redis.del key_value
    end
  end

  puts "  RedisCleaner(#{redis_name}) time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
suite_start(test_strategy) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 603
def suite_start test_strategy
  time = Benchmark.measure do
    puts "  RedisCleaner(#{redis_name})" if PseudoCleaner::Configuration.instance.benchmark

    start_monitor
  end

  puts "  RedisCleaner(#{redis_name}) time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
suspend_tracking(&block) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 613
def suspend_tracking(&block)
  begin
    set_value_bool :@suspend_tracking, true

    block.yield
  ensure
    set_value_bool :@suspend_tracking, false
  end
end
synchronize_test_values(&block) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 838
def synchronize_test_values(&block)
  if get_value_bool(:@in_multi)
    # Ideally we should never get here, but if we do, assume everything was changed and keep moving...
    get_list_array(:@multi_commands).each do |args|
      if WRITE_COMMANDS.include?(args[0]) ||
          POP_COMMANDS.include?(args[0]) ||
          NIL_FAIL_COMMANDS.include?(args[0]) ||
          NUM_CHANGED_COMMANDS.include?(args[0])
        add_set_values :@updated_keys, *extract_keys(*args)
      elsif track_reads && READ_COMMANDS.include?(args[0])
        keys = *extract_keys(*args)
        append_list_value_array :@read_keys, [keys.length, *keys, response]
      end
    end

    set_value_bool(:@in_multi, false)
    clear_list_array(:@multi_commands)
  end

  updated_values = get_set(:@updated_keys).dup
  read_values    = get_list_array(:@read_keys)

  read_values = read_values.reduce([]) do |array, values|
    if values.length > values[0].to_i + 1
      read_value  = values[-1]
      values = values[1..-2].map { |value| [value, read_value] }
    else
      values = values[1..-1]
    end

    array.concat values

    array
  end
  set_value_bool :@in_redis_cleanup, true

  begin
    block.yield updated_values, read_values
  ensure
    set_value_bool :@in_redis_cleanup, false
  end
end
test_end(test_strategy) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 645
def test_end test_strategy
  time = Benchmark.measure do
    puts "  RedisCleaner(#{redis_name})" if PseudoCleaner::Configuration.instance.benchmark

    synchronize_test_values do |updated_values, read_values|
      if (updated_values && !updated_values.empty?) || (read_values && !read_values.empty?)
        report_keys = []

        if @options[:output_diagnostics]
          report_dirty_values "updated values", updated_values
          report_dirty_values "read values", read_values if track_reads
        end

        updated_values.each do |value|
          if set_includes?(:@initial_keys, value)
            report_keys << value
            add_set_value(:@suite_altered_keys, value) unless ignore_key(value)
          else
            redis.del(value)
          end
        end

        report_dirty_values "initial values altered by test", report_keys
      end
    end

    clear_set :@updated_keys
    clear_list_array :@read_keys
  end

  puts "  RedisCleaner(#{redis_name}) time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
test_start(test_strategy) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 623
def test_start test_strategy
  time = Benchmark.measure do
    puts "  RedisCleaner(#{redis_name})" if PseudoCleaner::Configuration.instance.benchmark

    synchronize_test_values do |test_values, read_values|
      if (test_values && !test_values.empty?) || (read_values && !read_values.empty?)
        report_dirty_values "values altered before the test started", test_values
        report_dirty_values "values read before the test started", read_values if track_reads

        test_values.each do |value|
          redis.del value unless set_includes?(:@initial_keys, value)
        end
      end
    end

    clear_set :@updated_keys
    clear_list_array :@read_keys
  end

  puts "  RedisCleaner(#{redis_name}) time: #{time}" if PseudoCleaner::Configuration.instance.benchmark
end
track_reads() click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1052
def track_reads
  @track_reads ||= PseudoCleaner::Configuration.instance.redis_track_reads
end
track_reads=(value) click to toggle source
# File lib/pseudo_cleaner/redis_cleaner.rb, line 1048
def track_reads=(value)
  @track_reads = value
end
type(key) click to toggle source

Ruby defines a now deprecated type method so we need to override it here since it will never hit method_missing

# File lib/pseudo_cleaner/redis_cleaner.rb, line 381
def type(key)
  redis.type(key)
end