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.
109 110 111 |
# File 'lib/liszt/redis_list.rb', line 109 def all redis.lrange(@key, 0, -2).map(&:to_i) end |
#clear ⇒ Object
Clear all items from the list.
94 95 96 97 |
# File 'lib/liszt/redis_list.rb', line 94 def clear redis.del(@key) redis.rpush(@key, '*') 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.
175 176 177 |
# File 'lib/liszt/redis_list.rb', line 175 def get(index) redis.lindex(@key, index).to_i end |
#get_lock(timeout = lock_expiration_time) ⇒ Object (private)
197 198 199 200 201 202 203 204 |
# File 'lib/liszt/redis_list.rb', line 197 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.
102 103 104 105 |
# File 'lib/liszt/redis_list.rb', line 102 def length len = redis.llen(@key) (len > 0) ? (len - 1) : nil end |
#lock_expiration_time ⇒ Object (private)
214 215 216 |
# File 'lib/liszt/redis_list.rb', line 214 def lock_expiration_time 5 # seconds end |
#lock_key ⇒ Object (private)
210 211 212 |
# File 'lib/liszt/redis_list.rb', line 210 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.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/liszt/redis_list.rb', line 135 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.
161 162 163 164 165 166 |
# File 'lib/liszt/redis_list.rb', line 161 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.
152 153 154 155 156 157 |
# File 'lib/liszt/redis_list.rb', line 152 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.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/liszt/redis_list.rb', line 117 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 |
# File 'lib/liszt/redis_list.rb', line 81 def push!(id) redis.rpop(@key) redis.rpush(@key, id) redis.rpush(@key, '*') end |
#redis ⇒ Object (private)
169 170 171 |
# File 'lib/liszt/redis_list.rb', line 169 def redis ::Liszt.redis end |
#release_lock ⇒ Object (private)
206 207 208 |
# File 'lib/liszt/redis_list.rb', line 206 def release_lock redis.del(lock_key) end |
#remove(id) ⇒ Object
Remove the given id from the list.
89 90 91 |
# File 'lib/liszt/redis_list.rb', line 89 def remove(id) redis.lrem(@key, 1, id) end |
#set(index, value) ⇒ Object (private)
179 180 181 |
# File 'lib/liszt/redis_list.rb', line 179 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.
186 187 188 189 190 191 192 193 194 195 |
# File 'lib/liszt/redis_list.rb', line 186 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 |