Class: Specwrk::Store::RedisAdapter
- Inherits:
-
BaseAdapter
- Object
- BaseAdapter
- Specwrk::Store::RedisAdapter
- Defined in:
- lib/specwrk/store/redis_adapter.rb
Constant Summary collapse
- VERSION =
REDIS_ADAPTER_VERSION- LOCK_TTL_MILLISECONDS =
10_000- LOCK_SCRIPT =
<<~LUA if redis.call("SET", KEYS[1], ARGV[1], "NX", "PX", ARGV[2]) then return 1 end return 0 LUA
- UNLOCK_SCRIPT =
<<~LUA if redis.call("GET", KEYS[1]) == ARGV[1] then return redis.call("DEL", KEYS[1]) end return 0 LUA
- LOCK_SCRIPT_SHA =
Digest::SHA1.hexdigest(LOCK_SCRIPT)
- UNLOCK_SCRIPT_SHA =
Digest::SHA1.hexdigest(UNLOCK_SCRIPT)
Class Method Summary collapse
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, value) ⇒ Object
- #clear ⇒ Object
- #delete(*keys) ⇒ Object
- #empty? ⇒ Boolean
- #keys ⇒ Object
- #merge!(h2) ⇒ Object
- #multi_read(*read_keys) ⇒ Object
- #multi_write(hash) ⇒ Object
Class Method Details
.connection_pool_for(uri) ⇒ Object
59 60 61 62 63 64 65 66 67 |
# File 'lib/specwrk/store/redis_adapter.rb', line 59 def connection_pool_for(uri) return @connection_pools[uri] if @connection_pools.key? uri @mutex.synchronize do @connection_pools[uri] ||= RedisClient.config(url: uri).new_pool( size: ENV.fetch("SPECWRK_THREAD_COUNT", ENV.fetch("SPECWRK_COUNT", "4")).to_i ) end end |
.reset_connections! ⇒ Object
69 70 71 |
# File 'lib/specwrk/store/redis_adapter.rb', line 69 def reset_connections! @connection_pools.clear end |
.with_lock(uri, key) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/specwrk/store/redis_adapter.rb', line 38 def with_lock(uri, key) connection_pool_for(uri).with do |connection| Thread.current[:connection] = connection id = SecureRandom.uuid lock_key = "specwrk-lock-#{key}" locked = false locked = obtain_lock(connection, lock_key, id) raise Specwrk::Store::LockUnavailableError unless locked yield ensure begin release_lock(connection, lock_key, id) if locked ensure Thread.current[:connection] = nil end end end |
Instance Method Details
#[](key) ⇒ Object
91 92 93 94 95 96 |
# File 'lib/specwrk/store/redis_adapter.rb', line 91 def [](key) with_connection do |redis| value = redis.call("HGET", scope, key) self.class.serializer.load(value) if value end end |
#[]=(key, value) ⇒ Object
98 99 100 101 102 |
# File 'lib/specwrk/store/redis_adapter.rb', line 98 def []=(key, value) with_connection do |redis| redis.call("HSET", scope, key, self.class.serializer.dump(value)) end end |
#clear ⇒ Object
110 111 112 113 114 |
# File 'lib/specwrk/store/redis_adapter.rb', line 110 def clear with_connection do |redis| redis.call("DEL", scope) end end |
#delete(*keys) ⇒ Object
116 117 118 119 120 121 122 |
# File 'lib/specwrk/store/redis_adapter.rb', line 116 def delete(*keys) return if keys.length.zero? with_connection do |redis| redis.call("HDEL", scope, *keys) end end |
#empty? ⇒ Boolean
153 154 155 156 157 |
# File 'lib/specwrk/store/redis_adapter.rb', line 153 def empty? with_connection do |redis| redis.call("HLEN", scope).zero? end end |
#keys ⇒ Object
104 105 106 107 108 |
# File 'lib/specwrk/store/redis_adapter.rb', line 104 def keys with_connection do |redis| redis.call("HKEYS", scope) end end |
#merge!(h2) ⇒ Object
124 125 126 |
# File 'lib/specwrk/store/redis_adapter.rb', line 124 def merge!(h2) multi_write(h2) end |
#multi_read(*read_keys) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/specwrk/store/redis_adapter.rb', line 128 def multi_read(*read_keys) return {} if read_keys.length.zero? values = with_connection do |redis| redis.call("HMGET", scope, *read_keys) end result = {} read_keys.zip(values).each do |key, value| next if value.nil? result[key] = self.class.serializer.load(value) end result end |
#multi_write(hash) ⇒ Object
145 146 147 148 149 150 151 |
# File 'lib/specwrk/store/redis_adapter.rb', line 145 def multi_write(hash) return if hash.nil? || hash.length.zero? with_connection do |redis| redis.call("HMSET", scope, *hash.flat_map { |key, value| [key, self.class.serializer.dump(value)] }) end end |