Class: GlobalErrorHandler::Redis

Inherits:
Object
  • Object
show all
Defined in:
lib/global_error_handler/redis.rb

Constant Summary collapse

CURRENT_ID_KEY =
'global_error_handler:current_id'
EXCEPTIONS_REDIS_KEY =
'global_error_handler:exceptions'
EXCEPTION_KEY_PREFIX =
'global_error_handler:exception'
FILTER_KEY_PREFIX =
'global_error_handler:filter'
FILTER_FIELDS =
%w(error_class error_message)
FILTER_MAX_CHARS =
60
REDIS_TTL =

4 weeks

4 * 7 * 24 * 60 * 60

Class Method Summary collapse

Class Method Details

.cleanup_database_dependencies!Object



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
139
# File 'lib/global_error_handler/redis.rb', line 111

def cleanup_database_dependencies!
  total_exceptions_count = exceptions_count
  total_exception_keys_count = redis.keys(exception_key('*')).size
  if total_exceptions_count > total_exception_keys_count
    puts "==> Database dependency is broken. Need to fix it!"
    start = 0
    per_page = 500
    exception_keys_to_be_cleaned_up = []
    valid_chunks_count = 0
    cleanup_count = exception_keys_to_be_cleaned_up.size
    while total_exceptions_count > start
      exception_keys(start, per_page).each do |redis_key|
        exception_keys_to_be_cleaned_up.push redis_key unless redis.exists(redis_key)
      end
      if cleanup_count == (cleanup_count = exception_keys_to_be_cleaned_up.size)
        valid_chunks_count += 1
      end
      break if valid_chunks_count > 3 #if three ranges in a row are consistent, treat database consistency and finish looping
      start += per_page
    end

    puts "*** found #{exception_keys_to_be_cleaned_up.count} broken dependency keys."
    exception_keys_to_be_cleaned_up.each do |redis_key|
      delete_dependencies(redis_key) rescue next
    end
  else
    puts "==> Database dependency is OK. No need to fix it!"
  end
end

.clear_filters(key) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/global_error_handler/redis.rb', line 96

def clear_filters(key)
  FILTER_FIELDS.each do |field|
    retry_count = 0
    field_value = build_filter_value(redis.hget key, field)
    begin
      filter_keys_for(field, field_value).each do |filter_key|
        redis.lrem filter_key, 1, key
      end
    rescue
      field_value = ''
      retry if (retry_count += 1) < 2
    end
  end
end

.current_idObject



34
35
36
# File 'lib/global_error_handler/redis.rb', line 34

def current_id
  redis.get(CURRENT_ID_KEY)
end

.delete(key) ⇒ Object



70
71
72
73
# File 'lib/global_error_handler/redis.rb', line 70

def delete(key)
  delete_dependencies key
  redis.del key
end

.delete_all(keys) ⇒ Object



75
76
77
# File 'lib/global_error_handler/redis.rb', line 75

def delete_all(keys)
  keys.each { |key| delete(key) rescue next }
end

.delete_dependencies(key) ⇒ Object



91
92
93
94
# File 'lib/global_error_handler/redis.rb', line 91

def delete_dependencies(key)
  redis.lrem EXCEPTIONS_REDIS_KEY, 1, key
  clear_filters key
end

.exception_key(id = current_id) ⇒ Object



83
84
85
# File 'lib/global_error_handler/redis.rb', line 83

def exception_key(id = current_id)
  "#{EXCEPTION_KEY_PREFIX}:#{id}"
end

.exception_keys(start = 0, per_page = 10) ⇒ Object



50
51
52
# File 'lib/global_error_handler/redis.rb', line 50

def exception_keys(start = 0, per_page = 10)
  redis.lrange EXCEPTIONS_REDIS_KEY, start.to_i, per_page.to_i + start.to_i - 1
end

.exceptions_countObject

def sort(field, direction = ‘ASC’, page = 0, per_page = 1000)

redis.sort(EXCEPTIONS_REDIS_KEY, by: "#{EXCEPTION_KEY_PREFIX}_*->#{field}_*", order: "#{direction}", limit: [page, per_page])

end



42
43
44
# File 'lib/global_error_handler/redis.rb', line 42

def exceptions_count
  redis.llen EXCEPTIONS_REDIS_KEY
end

.filter_exception_keys(start = 0, field = nil, filter = nil, per_page = 10) ⇒ Object



54
55
56
# File 'lib/global_error_handler/redis.rb', line 54

def filter_exception_keys(start = 0, field = nil, filter = nil, per_page = 10)
  redis.lrange filter_key(field, filter), start.to_i, per_page.to_i + start.to_i - 1
end

.filter_key(field, filter) ⇒ Object



87
88
89
# File 'lib/global_error_handler/redis.rb', line 87

def filter_key(field, filter)
  "#{FILTER_KEY_PREFIX}:#{field}:#{filter}"
end

.filter_keys_for(field, filter = '') ⇒ Object



58
59
60
# File 'lib/global_error_handler/redis.rb', line 58

def filter_keys_for(field, filter = '')
  redis.keys filter_key(field, "#{filter}*")
end

.filtered_exceptions_count(field, filter) ⇒ Object



46
47
48
# File 'lib/global_error_handler/redis.rb', line 46

def filtered_exceptions_count(field, filter)
  redis.llen filter_key(field, filter)
end

.find(key) ⇒ Object



62
63
64
# File 'lib/global_error_handler/redis.rb', line 62

def find(key)
  Hashie::Mash.new redis.hgetall(key)
end

.find_all(keys) ⇒ Object



66
67
68
# File 'lib/global_error_handler/redis.rb', line 66

def find_all(keys)
  keys.map { |key| find(key) }.compact
end

.initialize_redis_from_configObject

:nodoc:



22
23
24
25
# File 'lib/global_error_handler/redis.rb', line 22

def initialize_redis_from_config #:nodoc:
  redis_config = YAML.load_file(File.join(Rails.root, 'config', 'redis.yml'))[Rails.env]
  Redis.new(redis_config['global_exception_handler'])
end

.redisObject



27
28
29
30
31
32
# File 'lib/global_error_handler/redis.rb', line 27

def redis
  @redis ||= begin
               $redis_global_exception_handler = initialize_redis_from_config unless $redis_global_exception_handler.is_a? Redis
               $redis_global_exception_handler
             end
end

.store(info_hash) ⇒ Object



11
12
13
14
15
16
17
18
19
20
# File 'lib/global_error_handler/redis.rb', line 11

def store(info_hash)
  return if info_hash.blank?
  redis_key = exception_key(next_id!)
  redis.hmset redis_key, info_hash.merge(id: current_id).to_a.flatten
  redis.rpush EXCEPTIONS_REDIS_KEY, redis_key
  FILTER_FIELDS.each do |field|
    redis.rpush filter_key(field, build_filter_value(info_hash[field.to_sym])), redis_key
  end
  redis.expire redis_key, REDIS_TTL
end

.truncate!Object



79
80
81
# File 'lib/global_error_handler/redis.rb', line 79

def truncate!
  redis.flushdb
end