Class: Liszt::RedisList
- Inherits:
-
Object
- Object
- Liszt::RedisList
- Defined in:
- lib/liszt/redis_list.rb
Instance Method Summary collapse
-
#all ⇒ Array<Fixnum>
(also: #to_a)
Return an Array of all the ids in the list.
-
#clear ⇒ Object
Clear all items from the list.
-
#clear_and_populate!(ids) ⇒ Array<Fixnum>
Remove existing list items and repopulate the list with the given ids (in the given order).
-
#get(index) ⇒ Object
private
Return the item at the given index in the list.
- #get_lock(timeout = lock_expiration_time) ⇒ Object private
-
#include?(id) ⇒ Boolean
Does the list currently include this id?.
-
#index(id) ⇒ Fixnum
Return the index of the given id in the list.
-
#initialize(key) ⇒ RedisList
constructor
A new instance of RedisList.
-
#initialized? ⇒ Boolean
Has the list been initialized?.
-
#length ⇒ Fixnum?
Return the number of ids in the list, or nil if it's uninitialized.
- #lock_expiration_time ⇒ Object private
- #lock_key ⇒ Object private
-
#move_down(id) ⇒ Object
Swap the position of the given id with the one below it.
-
#move_to_bottom(id) ⇒ Object
Move the given id to the bottom of the list.
-
#move_to_top(id) ⇒ Object
Move the given id to the top of the list.
-
#move_up(id) ⇒ Object
Swap the position of the given id with the one above it.
-
#push(id) ⇒ Boolean
(also: #<<)
Push the given id onto the bottom of the list, if not already present.
-
#push!(id) ⇒ Object
Push the given id onto the bottom of the list.
- #redis ⇒ Object private
- #release_lock ⇒ Object private
-
#remove(id) ⇒ Object
Remove the given id from the list.
- #set(index, value) ⇒ Object private
-
#uninitialize ⇒ Object
Completely delete the list from Redis, leaving no marker.
-
#unshift(id) ⇒ Boolean
Push the given id onto the top of the list, if not already present.
-
#unshift!(id) ⇒ Object
Push the given id onto the top of the list.
-
#with_lock ⇒ Object
private
Obtain an exclusive lock on the list, execute the given block, and then release the lock.
Constructor Details
#initialize(key) ⇒ RedisList
Returns a new instance of RedisList.
4 5 6 |
# File 'lib/liszt/redis_list.rb', line 4 def initialize(key) @key = key end |
Instance Method Details
#all ⇒ Array<Fixnum> Also known as: to_a
Return an Array of all the ids in the list.
113 114 115 |
# File 'lib/liszt/redis_list.rb', line 113 def all redis.lrange(@key, 0, -2).map(&:to_i) end |
#clear ⇒ Object
Clear all items from the list.
96 97 98 99 100 101 |
# File 'lib/liszt/redis_list.rb', line 96 def clear redis.multi do redis.del(@key) redis.rpush(@key, '*') end end |
#clear_and_populate!(ids) ⇒ Array<Fixnum>
Remove existing list items and repopulate the list with the given ids (in the given order).
17 18 19 20 21 22 23 24 |
# File 'lib/liszt/redis_list.rb', line 17 def clear_and_populate!(ids) redis.multi do clear # reverse and unshift to avoid touching the marker ids.reverse.each { |id| unshift!(id) } end ids end |
#get(index) ⇒ Object (private)
Return the item at the given index in the list.
179 180 181 |
# File 'lib/liszt/redis_list.rb', line 179 def get(index) redis.lindex(@key, index).to_i end |
#get_lock(timeout = lock_expiration_time) ⇒ Object (private)
201 202 203 204 205 206 207 208 |
# File 'lib/liszt/redis_list.rb', line 201 def get_lock(timeout=lock_expiration_time) if redis.setnx(lock_key, true) redis.expire(lock_key, timeout) true else false end end |
#include?(id) ⇒ Boolean
Does the list currently include this id?
35 36 37 |
# File 'lib/liszt/redis_list.rb', line 35 def include?(id) all.include?(id) end |
#index(id) ⇒ Fixnum
Return the index of the given id in the list.
42 43 44 |
# File 'lib/liszt/redis_list.rb', line 42 def index(id) all.index(id) end |
#initialized? ⇒ Boolean
Has the list been initialized?
28 29 30 |
# File 'lib/liszt/redis_list.rb', line 28 def initialized? redis.exists(@key) end |
#length ⇒ Fixnum?
Return the number of ids in the list, or nil if it's uninitialized.
106 107 108 109 |
# File 'lib/liszt/redis_list.rb', line 106 def length len = redis.llen(@key) (len > 0) ? (len - 1) : nil end |
#lock_expiration_time ⇒ Object (private)
218 219 220 |
# File 'lib/liszt/redis_list.rb', line 218 def lock_expiration_time 5 # seconds end |
#lock_key ⇒ Object (private)
214 215 216 |
# File 'lib/liszt/redis_list.rb', line 214 def lock_key "#{@key}:lock" end |
#move_down(id) ⇒ Object
Swap the position of the given id with the one below it. If it's at the bottom of the list or not present in the list, do nothing.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/liszt/redis_list.rb', line 139 def move_down(id) with_lock do position = index(id) if position.nil? or position == (length - 1) nil else next_id = get(position + 1) redis.multi do set(position + 1, id) set(position, next_id) end end end end |
#move_to_bottom(id) ⇒ Object
Move the given id to the bottom of the list.
165 166 167 168 169 170 |
# File 'lib/liszt/redis_list.rb', line 165 def move_to_bottom(id) redis.multi do remove(id) push!(id) end end |
#move_to_top(id) ⇒ Object
Move the given id to the top of the list.
156 157 158 159 160 161 |
# File 'lib/liszt/redis_list.rb', line 156 def move_to_top(id) redis.multi do remove(id) unshift!(id) end end |
#move_up(id) ⇒ Object
Swap the position of the given id with the one above it. If it's at the top of the list or not present in the list, do nothing.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/liszt/redis_list.rb', line 121 def move_up(id) with_lock do position = index(id) if position.nil? or position == 0 nil else prev_id = get(position - 1) redis.multi do set(position - 1, id) set(position, prev_id) end end end end |
#push(id) ⇒ Boolean Also known as: <<
Push the given id onto the bottom of the list, if not already present.
69 70 71 72 73 74 75 76 |
# File 'lib/liszt/redis_list.rb', line 69 def push(id) if include?(id) false else push!(id) true end end |
#push!(id) ⇒ Object
Push the given id onto the bottom of the list.
81 82 83 84 85 86 87 |
# File 'lib/liszt/redis_list.rb', line 81 def push!(id) redis.multi do redis.rpop(@key) redis.rpush(@key, id) redis.rpush(@key, '*') end end |
#redis ⇒ Object (private)
173 174 175 |
# File 'lib/liszt/redis_list.rb', line 173 def redis ::Liszt.redis end |
#release_lock ⇒ Object (private)
210 211 212 |
# File 'lib/liszt/redis_list.rb', line 210 def release_lock redis.del(lock_key) end |
#remove(id) ⇒ Object
Remove the given id from the list.
91 92 93 |
# File 'lib/liszt/redis_list.rb', line 91 def remove(id) redis.lrem(@key, 1, id) end |
#set(index, value) ⇒ Object (private)
183 184 185 |
# File 'lib/liszt/redis_list.rb', line 183 def set(index, value) redis.lset(@key, index, value) end |
#uninitialize ⇒ Object
Completely delete the list from Redis, leaving no marker.
9 10 11 |
# File 'lib/liszt/redis_list.rb', line 9 def uninitialize redis.del(@key) end |
#unshift(id) ⇒ Boolean
Push the given id onto the top of the list, if not already present.
50 51 52 53 54 55 56 57 |
# File 'lib/liszt/redis_list.rb', line 50 def unshift(id) if include?(id) false else unshift!(id) true end end |
#unshift!(id) ⇒ Object
Push the given id onto the top of the list.
61 62 63 |
# File 'lib/liszt/redis_list.rb', line 61 def unshift!(id) redis.lpush(@key, id) end |
#with_lock ⇒ Object (private)
Obtain an exclusive lock on the list, execute the given block, and then release the lock. If the lock is currently taken by someone else, we just block until it becomes available.
190 191 192 193 194 195 196 197 198 199 |
# File 'lib/liszt/redis_list.rb', line 190 def with_lock start_time = Time.now until get_lock sleep 0.2 raise "Timed out!" if (Time.now - start_time) > 10 end yield ensure release_lock end |