Class: SidekiqVigil::Storage
- Inherits:
-
Object
- Object
- SidekiqVigil::Storage
- Defined in:
- lib/sidekiq_vigil/storage.rb
Defined Under Namespace
Classes: KeyDefinition, MissingTTL, UnmanagedPersistentKey
Constant Summary collapse
- KEY_CATALOG =
[ KeyDefinition.new(pattern: "stats:{yyyymmddHHMM}", type: "hash", ttl: "8 days", owner: "Reporter"), KeyDefinition.new(pattern: "exec:{queue}", type: "hash", ttl: "1 hour", owner: "Reporter"), KeyDefinition.new(pattern: "alerts", type: "hash", ttl: "managed", owner: "Alert::Manager"), KeyDefinition.new(pattern: "history:{alert_id}", type: "list", ttl: "24 hours", owner: "Alert::Manager"), KeyDefinition.new(pattern: "snapshot", type: "string", ttl: "interval × 4", owner: "Checker"), KeyDefinition.new(pattern: "leader", type: "string", ttl: "interval × 3", owner: "LeaderElection"), KeyDefinition.new(pattern: "mem:{process_id}", type: "string", ttl: "flush interval × 3", owner: "Reporter"), KeyDefinition.new(pattern: "config_digest", type: "hash", ttl: "1 hour", owner: "Reporter"), KeyDefinition.new(pattern: "mute", type: "string", ttl: "requested duration", owner: "Alert::Mute"), KeyDefinition.new( pattern: "check_state:{check-specific-suffix}", type: "string", ttl: "check-specific", owner: "Checks" ) ].freeze
Instance Attribute Summary collapse
-
#prefix ⇒ Object
readonly
Returns the value of attribute prefix.
Instance Method Summary collapse
- #acquire_lock(suffix, token, ttl_ms:) ⇒ Object
- #delete(suffix) ⇒ Object
- #eval(script, keys:, argv:) ⇒ Object
- #get(suffix) ⇒ Object
- #hash_delete(suffix, *fields) ⇒ Object
- #hash_get_all(suffix) ⇒ Object
- #hash_increment(suffix, values, ttl:) ⇒ Object
- #hash_write(suffix, values, ttl:) ⇒ Object
- #info(section = nil) ⇒ Object
-
#initialize(redis: nil, key_prefix: "default") ⇒ Storage
constructor
A new instance of Storage.
- #key(suffix) ⇒ Object
- #list_push(suffix, value, ttl:, limit: 30) ⇒ Object
- #list_range(suffix) ⇒ Object
- #managed_hash_write(suffix, field, value) ⇒ Object
- #ping ⇒ Object
- #scan(pattern = "*") ⇒ Object
- #set(suffix, value, ttl:) ⇒ Object
Constructor Details
#initialize(redis: nil, key_prefix: "default") ⇒ Storage
Returns a new instance of Storage.
31 32 33 34 |
# File 'lib/sidekiq_vigil/storage.rb', line 31 def initialize(redis: nil, key_prefix: "default") @redis = redis @prefix = "vigil:#{key_prefix}:" end |
Instance Attribute Details
#prefix ⇒ Object (readonly)
Returns the value of attribute prefix.
29 30 31 |
# File 'lib/sidekiq_vigil/storage.rb', line 29 def prefix @prefix end |
Instance Method Details
#acquire_lock(suffix, token, ttl_ms:) ⇒ Object
124 125 126 127 128 |
# File 'lib/sidekiq_vigil/storage.rb', line 124 def acquire_lock(suffix, token, ttl_ms:) raise MissingTTL, "a positive ttl is required" unless ttl_ms.is_a?(Numeric) && ttl_ms.positive? with_redis { |redis| redis.call("SET", key(suffix), token, "NX", "PX", ttl_ms) == "OK" } end |
#delete(suffix) ⇒ Object
107 108 109 |
# File 'lib/sidekiq_vigil/storage.rb', line 107 def delete(suffix) with_redis { |redis| redis.call("DEL", key(suffix)) } end |
#eval(script, keys:, argv:) ⇒ Object
130 131 132 133 |
# File 'lib/sidekiq_vigil/storage.rb', line 130 def eval(script, keys:, argv:) namespaced_keys = keys.map { |item| key(item) } with_redis { |redis| redis.call("EVAL", script, namespaced_keys.length, *namespaced_keys, *argv) } end |
#get(suffix) ⇒ Object
45 46 47 |
# File 'lib/sidekiq_vigil/storage.rb', line 45 def get(suffix) with_redis { |redis| redis.call("GET", key(suffix)) } end |
#hash_delete(suffix, *fields) ⇒ Object
86 87 88 89 90 |
# File 'lib/sidekiq_vigil/storage.rb', line 86 def hash_delete(suffix, *fields) return if fields.empty? with_redis { |redis| redis.call("HDEL", key(suffix), *fields) } end |
#hash_get_all(suffix) ⇒ Object
82 83 84 |
# File 'lib/sidekiq_vigil/storage.rb', line 82 def hash_get_all(suffix) with_redis { |redis| redis.call("HGETALL", key(suffix)) } end |
#hash_increment(suffix, values, ttl:) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/sidekiq_vigil/storage.rb', line 61 def hash_increment(suffix, values, ttl:) require_ttl!(ttl) return if values.empty? with_redis do |redis| redis.pipelined do |pipeline| values.each do |field, amount| command = amount.is_a?(Integer) ? "HINCRBY" : "HINCRBYFLOAT" pipeline.call(command, key(suffix), field, amount) end pipeline.call("PEXPIRE", key(suffix), ttl_ms(ttl)) end end end |
#hash_write(suffix, values, ttl:) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/sidekiq_vigil/storage.rb', line 49 def hash_write(suffix, values, ttl:) require_ttl!(ttl) return if values.empty? with_redis do |redis| redis.pipelined do |pipeline| pipeline.call("HSET", key(suffix), *values.flatten) pipeline.call("PEXPIRE", key(suffix), ttl_ms(ttl)) end end end |
#info(section = nil) ⇒ Object
139 140 141 |
# File 'lib/sidekiq_vigil/storage.rb', line 139 def info(section = nil) with_redis { |redis| parse_info(redis.call("INFO", *Array(section))) } end |
#key(suffix) ⇒ Object
36 37 38 |
# File 'lib/sidekiq_vigil/storage.rb', line 36 def key(suffix) "#{prefix}#{suffix}" end |
#list_push(suffix, value, ttl:, limit: 30) ⇒ Object
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/sidekiq_vigil/storage.rb', line 92 def list_push(suffix, value, ttl:, limit: 30) require_ttl!(ttl) with_redis do |redis| redis.pipelined do |pipeline| pipeline.call("RPUSH", key(suffix), value) pipeline.call("LTRIM", key(suffix), -limit, -1) pipeline.call("PEXPIRE", key(suffix), ttl_ms(ttl)) end end end |
#list_range(suffix) ⇒ Object
103 104 105 |
# File 'lib/sidekiq_vigil/storage.rb', line 103 def list_range(suffix) with_redis { |redis| redis.call("LRANGE", key(suffix), 0, -1) } end |
#managed_hash_write(suffix, field, value) ⇒ Object
76 77 78 79 80 |
# File 'lib/sidekiq_vigil/storage.rb', line 76 def managed_hash_write(suffix, field, value) raise UnmanagedPersistentKey, "only alerts may be written without a ttl" unless suffix == "alerts" with_redis { |redis| redis.call("HSET", key(suffix), field, value) } end |
#ping ⇒ Object
135 136 137 |
# File 'lib/sidekiq_vigil/storage.rb', line 135 def ping with_redis { |redis| redis.call("PING") } end |
#scan(pattern = "*") ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/sidekiq_vigil/storage.rb', line 111 def scan(pattern = "*") with_redis do |redis| cursor = "0" keys = [] loop do cursor, batch = redis.call("SCAN", cursor, "MATCH", key(pattern), "COUNT", 100) keys.concat(batch) break if cursor == "0" end keys end end |
#set(suffix, value, ttl:) ⇒ Object
40 41 42 43 |
# File 'lib/sidekiq_vigil/storage.rb', line 40 def set(suffix, value, ttl:) require_ttl!(ttl) with_redis { |redis| redis.call("SET", key(suffix), value, "PX", ttl_ms(ttl)) } end |