Class: DiscordRDA::RedisStore

Inherits:
CacheStore
  • Object
show all
Defined in:
lib/discord_rda/cache/redis_store.rb

Overview

Redis-backed cache store. Provides distributed caching with Redis.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(redis: nil, prefix: 'discord_rda:', default_ttl: 3600) ⇒ RedisStore

Initialize Redis store

Parameters:

  • redis (Redis) (defaults to: nil)

    Redis client or connection options

  • prefix (String) (defaults to: 'discord_rda:')

    Key prefix

  • default_ttl (Integer) (defaults to: 3600)

    Default TTL in seconds



21
22
23
24
25
# File 'lib/discord_rda/cache/redis_store.rb', line 21

def initialize(redis: nil, prefix: 'discord_rda:', default_ttl: 3600)
  @redis = redis.is_a?(Redis) ? redis : Redis.new(redis || {})
  @prefix = prefix
  @default_ttl = default_ttl
end

Instance Attribute Details

#default_ttlInteger (readonly)

Returns Default TTL.

Returns:

  • (Integer)

    Default TTL



15
16
17
# File 'lib/discord_rda/cache/redis_store.rb', line 15

def default_ttl
  @default_ttl
end

#prefixString (readonly)

Returns Key prefix.

Returns:

  • (String)

    Key prefix



12
13
14
# File 'lib/discord_rda/cache/redis_store.rb', line 12

def prefix
  @prefix
end

#redisRedis (readonly)

Returns Redis client.

Returns:

  • (Redis)

    Redis client



9
10
11
# File 'lib/discord_rda/cache/redis_store.rb', line 9

def redis
  @redis
end

Instance Method Details

#clearvoid

This method returns an undefined value.

Clear all cached values (matching prefix)



71
72
73
74
# File 'lib/discord_rda/cache/redis_store.rb', line 71

def clear
  keys = @redis.keys("#{@prefix}*")
  @redis.del(*keys) unless keys.empty?
end

#delete(key) ⇒ void

This method returns an undefined value.

Delete a value from cache

Parameters:

  • key (String)

    Cache key



58
59
60
# File 'lib/discord_rda/cache/redis_store.rb', line 58

def delete(key)
  @redis.del(prefixed_key(key))
end

#exist?(key) ⇒ Boolean

Check if key exists

Parameters:

  • key (String)

    Cache key

Returns:

  • (Boolean)

    True if exists



65
66
67
# File 'lib/discord_rda/cache/redis_store.rb', line 65

def exist?(key)
  @redis.exists?(prefixed_key(key))
end

#get(key) ⇒ Object?

Get a value from cache

Parameters:

  • key (String)

    Cache key

Returns:

  • (Object, nil)

    Cached value or nil



30
31
32
33
34
35
36
37
# File 'lib/discord_rda/cache/redis_store.rb', line 30

def get(key)
  value = @redis.get(prefixed_key(key))
  return nil unless value

  Marshal.load(value)
rescue => e
  nil
end

#keys(pattern) ⇒ Array<String>

Get keys matching a pattern using SCAN (non-blocking)

Parameters:

  • pattern (String, Regexp)

    Pattern to match

Returns:

  • (Array<String>)

    Matching keys (without prefix)



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/discord_rda/cache/redis_store.rb', line 112

def keys(pattern)
  glob_pattern = pattern.is_a?(Regexp) ? "#{@prefix}*" : "#{@prefix}#{pattern}"
  keys = []

  # Use SCAN to iterate without blocking Redis
  cursor = '0'
  loop do
    cursor, results = @redis.scan(cursor, match: glob_pattern, count: 100)
    keys.concat(results)
    break if cursor == '0'
  end

  # Strip prefix from keys
  keys.map { |k| k.delete_prefix(@prefix) }
rescue => e
  []
end

#mget(keys) ⇒ Hash

Get multiple values

Parameters:

  • keys (Array<String>)

    Cache keys

Returns:

  • (Hash)

    Key-value pairs



79
80
81
82
83
84
85
86
87
88
# File 'lib/discord_rda/cache/redis_store.rb', line 79

def mget(keys)
  prefixed = keys.map { |k| prefixed_key(k) }
  values = @redis.mget(prefixed)

  keys.zip(values).to_h do |k, v|
    [k, v ? Marshal.load(v) : nil]
  end
rescue
  {}
end

#mset(pairs, ttl: nil) ⇒ void

This method returns an undefined value.

Set multiple values

Parameters:

  • pairs (Hash)

    Key-value pairs

  • ttl (Integer) (defaults to: nil)

    Time to live



94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/discord_rda/cache/redis_store.rb', line 94

def mset(pairs, ttl: nil)
  ttl ||= @default_ttl

  @redis.multi do |pipeline|
    pairs.each do |k, v|
      serialized = Marshal.dump(v)
      if ttl
        pipeline.setex(prefixed_key(k), ttl, serialized)
      else
        pipeline.set(prefixed_key(k), serialized)
      end
    end
  end
end

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

This method returns an undefined value.

Set a value in cache

Parameters:

  • key (String)

    Cache key

  • value (Object)

    Value to cache

  • ttl (Integer) (defaults to: nil)

    Time to live in seconds



44
45
46
47
48
49
50
51
52
53
# File 'lib/discord_rda/cache/redis_store.rb', line 44

def set(key, value, ttl: nil)
  serialized = Marshal.dump(value)
  ttl ||= @default_ttl

  if ttl
    @redis.setex(prefixed_key(key), ttl, serialized)
  else
    @redis.set(prefixed_key(key), serialized)
  end
end