Module: Cachengue::Caching

Defined in:
lib/cachengue/caching.rb

Constant Summary collapse

ALL_KEYS =

Reduce memory use and its faster.

%w[*].freeze
NONE_KEYS =
[].freeze

Class Method Summary collapse

Class Method Details

.clear(namespace = nil, strategy = :all) ⇒ Object



61
62
63
64
65
# File 'lib/cachengue/caching.rb', line 61

def clear(namespace = nil, strategy = :all)
  keys_to_clear = keys(namespace, strategy)

  clear_keys(keys_to_clear)
end

.clear_by(options) ⇒ Object



67
68
69
70
71
72
73
74
75
76
# File 'lib/cachengue/caching.rb', line 67

def clear_by(options)
  key = format_key(
    options.fetch(:namespace),
    options[:key] || options.fetch(:method),
    options.fetch(:args),
    options[:args_hash]
  )

  clear_keys([key])
end

.clear_keys(keys_to_clear) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/cachengue/caching.rb', line 78

def clear_keys(keys_to_clear)
  return if Rails.env.test?

  keys_to_clear.sum do |k|
    Rails.cache.delete(k)
  end
end

.fetch(namespace, method_name, args, options = {}, &block) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/cachengue/caching.rb', line 96

def fetch(namespace, method_name, args, options = {}, &block)
  if options[:multi]
    fetch_multi(namespace, method_name, args, options, &block)
  else
    fetch_one(namespace, method_name, args, options, &block)
  end
end

.fetch_multi(namespace, method_name, args_list, options = {}) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/cachengue/caching.rb', line 113

def fetch_multi(namespace, method_name, args_list, options = {})
  return {} if args_list.empty?

  args_keys = {}

  args_list.each do |args|
    key = format_key_by_options(namespace, method_name, args, options)

    args_keys[key] = args
  end

  options = format_options(options)
  results = read_multi(args_keys.keys)

  computed_keys = args_keys.keys - results.keys
  computed_values = computed_keys.map { |key| args_keys.fetch(key) }
  computed = write_multi(computed_keys, computed_values, options, &Proc.new)

  results.merge!(computed)
  results.transform_keys! { |key| args_keys.fetch(key) }
  results
end

.fetch_one(namespace, method_name, args, options = {}, &block) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/cachengue/caching.rb', line 104

def fetch_one(namespace, method_name, args, options = {}, &block)
  key = format_key_by_options(namespace, method_name, args, options)
  options = format_options(options)

  Rails.cache.fetch(key, options) do
    get_value_by(args, &block)
  end
end

.format_key(namespace, method_name, args, args_hash) ⇒ Object



20
21
22
23
24
25
26
# File 'lib/cachengue/caching.rb', line 20

def format_key(namespace, method_name, args, args_hash)
  args = args.is_a?(Array) ? args.map(&:as_json) : [args.as_json]
  args = Digest::SHA256.base64digest(String(args)) if args_hash
  namespace = key_prefix(namespace)

  "#{namespace}:#{method_name}:#{args}"
end

.format_key_by_options(namespace, method_name, args, options) ⇒ Object



11
12
13
14
15
16
17
18
# File 'lib/cachengue/caching.rb', line 11

def format_key_by_options(namespace, method_name, args, options)
  format_key(
    options[:namespace] || namespace,
    options[:key] || options[:method] || method_name,
    options[:args] || args,
    options[:args_hash]
  )
end

.format_options(options) ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'lib/cachengue/caching.rb', line 28

def format_options(options)
  options.without(
    :args,
    :key,
    :args_hash,
    :method,
    :multi,
    :namespace
  )
end

.get_value_by(args) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/cachengue/caching.rb', line 86

def get_value_by(args)
  value = yield(*args)

  if defined?(::ActiveRecord) && value.is_a?(::ActiveRecord::Relation)
    value.to_a
  else
    value
  end
end

.key_prefix(namespace = nil) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/cachengue/caching.rb', line 39

def key_prefix(namespace = nil)
  if namespace.present?
    "cachengue:#{namespace.to_s.underscore}"
  else
    'cachengue'
  end
end

.key_suffix(strategy) ⇒ Object



47
48
49
# File 'lib/cachengue/caching.rb', line 47

def key_suffix(strategy)
  strategy == :all ? ALL_KEYS : NONE_KEYS
end

.keys(namespace = nil, strategy = :all) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'lib/cachengue/caching.rb', line 51

def keys(namespace = nil, strategy = :all)
  return [] if Rails.env.test?

  prefix = key_prefix(namespace)

  key_suffix(strategy).flat_map do |suffix|
    Rails.cache.data.keys("#{prefix}:#{suffix}")
  end
end

.read_multi(keys) ⇒ Object



136
137
138
# File 'lib/cachengue/caching.rb', line 136

def read_multi(keys)
  Rails.cache.read_multi(*keys)
end

.write_multi(keys, values, options) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
# File 'lib/cachengue/caching.rb', line 140

def write_multi(keys, values, options)
  results = {}

  keys.each_with_index do |key, index|
    results[key] = get_value_by(values.fetch(index), &Proc.new)
  end

  Rails.cache.write_multi(results, options)

  results
end