Class: Cloudtasker::RedisClient
- Inherits:
-
Object
- Object
- Cloudtasker::RedisClient
- Defined in:
- lib/cloudtasker/redis_client.rb
Overview
A wrapper with helper methods for redis
Constant Summary collapse
- LOCK_KEY_PREFIX =
Suffix added to cache keys when locking them
'cloudtasker/lock'
- LOCK_DURATION =
seconds
2
- LOCK_WAIT_DURATION =
seconds
0.03
- DEFAULT_POOL_SIZE =
Default pool size used for Redis
ENV.fetch('RAILS_MAX_THREADS') { 25 }
- DEFAULT_POOL_TIMEOUT =
5
Class Method Summary collapse
Instance Method Summary collapse
-
#clear ⇒ Integer
Clear all redis keys.
-
#client ⇒ Redis
Return the underlying redis client.
-
#fetch(key) ⇒ Hash, Array
Get a cache entry and parse it as JSON.
-
#method_missing(name, *args, **kwargs, &block) ⇒ Any
Delegate all methods to the redis client.
-
#respond_to_missing?(name, include_private = false) ⇒ Boolean
Check if the class respond to a certain method.
-
#search(pattern) ⇒ Array<String>
Return all keys matching the provided patterns.
-
#with_lock(cache_key, max_wait: nil) ⇒ Object
Acquire a lock on a cache entry.
-
#write(key, content) ⇒ String
Write a cache entry as JSON.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, **kwargs, &block) ⇒ Any
Delegate all methods to the redis client. Ruby 3 delegation method style.
148 149 150 151 152 153 154 |
# File 'lib/cloudtasker/redis_client.rb', line 148 def method_missing(name, *args, &block) if Redis.method_defined?(name) client.with { |c| c.send(name, *args, &block) } else super end end |
Class Method Details
.client ⇒ Object
18 19 20 21 22 23 24 25 26 |
# File 'lib/cloudtasker/redis_client.rb', line 18 def self.client @client ||= begin pool_size = Cloudtasker.config.redis&.dig(:pool_size) || DEFAULT_POOL_SIZE pool_timeout = Cloudtasker.config.redis&.dig(:pool_timeout) || DEFAULT_POOL_TIMEOUT ConnectionPool.new(size: pool_size, timeout: pool_timeout) do Redis.new(Cloudtasker.config.redis || {}) end end end |
Instance Method Details
#clear ⇒ Integer
Clear all redis keys
103 104 105 106 107 108 109 |
# File 'lib/cloudtasker/redis_client.rb', line 103 def clear all_keys = keys return 0 if all_keys.empty? # Delete all keys del(*all_keys) end |
#client ⇒ Redis
Return the underlying redis client.
33 34 35 |
# File 'lib/cloudtasker/redis_client.rb', line 33 def client @client ||= self.class.client end |
#fetch(key) ⇒ Hash, Array
Get a cache entry and parse it as JSON.
44 45 46 47 48 49 50 |
# File 'lib/cloudtasker/redis_client.rb', line 44 def fetch(key) return nil unless (val = get(key.to_s)) JSON.parse(val, symbolize_names: true) rescue JSON::ParserError nil end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean
Check if the class respond to a certain method.
185 186 187 |
# File 'lib/cloudtasker/redis_client.rb', line 185 def respond_to_missing?(name, include_private = false) Redis.method_defined?(name) || super end |
#search(pattern) ⇒ Array<String>
Return all keys matching the provided patterns.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/cloudtasker/redis_client.rb', line 118 def search(pattern) # Initialize loop variables cursor = nil list = [] # Scan and capture matching keys client.with do |conn| while cursor != 0 scan = conn.scan(cursor || 0, match: pattern) list += scan[1] cursor = scan[0].to_i end end list end |
#with_lock(cache_key, max_wait: nil) ⇒ Object
Acquire a lock on a cache entry.
Locks are enforced to be short-lived (2s). The yielded block should limit its logic to short operations (e.g. redis get/set).
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/cloudtasker/redis_client.rb', line 80 def with_lock(cache_key, max_wait: nil) return nil unless cache_key # Set max wait max_wait = (max_wait || LOCK_DURATION).to_i # Wait to acquire lock lock_key = [LOCK_KEY_PREFIX, cache_key].join('/') client.with do |conn| sleep(LOCK_WAIT_DURATION) until conn.set(lock_key, true, nx: true, ex: max_wait) end # yield content yield ensure del(lock_key) end |
#write(key, content) ⇒ String
Write a cache entry as JSON.
60 61 62 |
# File 'lib/cloudtasker/redis_client.rb', line 60 def write(key, content) set(key.to_s, content.to_json) end |