Class: Schematic::RedisCacheProvider

Inherits:
Object
  • Object
show all
Includes:
CacheProvider
Defined in:
lib/schematic/redis_cache.rb

Constant Summary collapse

DEFAULT_TTL =

seconds

5
DEFAULT_KEY_PREFIX =
"schematic:"
BATCH_DELETE_SIZE =
1000

Instance Method Summary collapse

Constructor Details

#initialize(client:, ttl: DEFAULT_TTL, key_prefix: DEFAULT_KEY_PREFIX) ⇒ RedisCacheProvider

Returns a new instance of RedisCacheProvider.



37
38
39
40
41
# File 'lib/schematic/redis_cache.rb', line 37

def initialize(client:, ttl: DEFAULT_TTL, key_prefix: DEFAULT_KEY_PREFIX)
  @client = client
  @default_ttl = ttl
  @key_prefix = key_prefix
end

Instance Method Details

#delete(key) ⇒ Object



65
66
67
68
# File 'lib/schematic/redis_cache.rb', line 65

def delete(key)
  full_key = prefixed_key(key)
  @client.del(full_key)
end

#delete_missing(keys_to_keep, scope:) ⇒ Object

Scans ‘#key_prefix#scope*` only, so callers sharing a key_prefix across cache types (e.g. flags/company/user all under “schematic:”) do not wipe sibling caches when pruning one of them.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/schematic/redis_cache.rb', line 73

def delete_missing(keys_to_keep, scope:)
  full_keys_to_keep = keys_to_keep.to_set { |k| prefixed_key(k) }
  keys_to_delete = []

  @client.scan_each(match: "#{@key_prefix}#{scope}*", count: BATCH_DELETE_SIZE) do |key|
    unless full_keys_to_keep.include?(key)
      keys_to_delete << key

      if keys_to_delete.size >= BATCH_DELETE_SIZE
        @client.del(*keys_to_delete)
        keys_to_delete.clear
      end
    end
  end

  @client.del(*keys_to_delete) if keys_to_delete.any?
end

#get(key) ⇒ Object



43
44
45
46
47
48
49
50
51
# File 'lib/schematic/redis_cache.rb', line 43

def get(key)
  full_key = prefixed_key(key)
  value = @client.get(full_key)
  return nil if value.nil?

  JSON.parse(value, symbolize_names: true)
rescue JSON::ParserError
  nil
end

#set(key, value, ttl: nil) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/schematic/redis_cache.rb', line 53

def set(key, value, ttl: nil)
  full_key = prefixed_key(key)
  serialized = JSON.generate(value.respond_to?(:to_h) ? value.to_h : value)
  actual_ttl = ttl || @default_ttl

  if actual_ttl.positive?
    @client.setex(full_key, actual_ttl.to_i, serialized)
  else
    @client.set(full_key, serialized)
  end
end