class SimpleFeed::Providers::Redis::Provider
Internal data structure:
```YAML u.afkj234.data: - [ 'John liked Robert', '2016-11-20 23:32:56 -0800' ] - [ 'Debbie liked Robert', '2016-11-20 23:35:56 -0800' ] u.afkj234.meta: { total: 2, unread: 2, last_read: 2016-11-20 22:00:34 -08:00 GMT } ```
Constants
- FEED_METHODS
Public Instance Methods
delete(user_ids:, value:, **)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 44 def delete(user_ids:, value:, **) with_response_pipelined(user_ids) do |redis, key| redis.zrem(key.data, value) end end
delete_if(user_ids:) { |event, consumer| ... }
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 50 def delete_if(user_ids:) raise ArgumentError, '#delete_if must be called with a block that receives (user_id, event) as arguments.' unless block_given? with_response_batched(user_ids) do |key| fetch(user_ids: [key.consumer])[key.consumer].map do |event| with_redis do |redis| if yield(event, key.consumer) redis.zrem(key.data, event.value) ? event : nil end end end.compact end end
fetch(user_ids:, since: nil, reset_last_read: false)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 84 def fetch(user_ids:, since: nil, reset_last_read: false) if since == :unread last_read_response = with_response_pipelined(user_ids) do |redis, key| get_users_last_read(redis, key) end end response = with_response_pipelined(user_ids) do |redis, key| if since == :unread redis.zrevrangebyscore(key.data, '+inf', (last_read_response.delete(key.consumer) || 0).to_f, withscores: true) elsif since redis.zrevrangebyscore(key.data, '+inf', since.to_f, withscores: true) else redis.zrevrange(key.data, 0, -1, withscores: true) end end reset_last_read_value(user_ids: user_ids, at: reset_last_read) if reset_last_read response end
last_read(user_ids:)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 128 def last_read(user_ids:) with_response_pipelined(user_ids) do |redis, key, *| get_users_last_read(redis, key) end end
paginate(user_ids:, page:, per_page: feed.per_page, with_total: false, reset_last_read: false)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 70 def paginate(user_ids:, page:, per_page: feed.per_page, with_total: false, reset_last_read: false) reset_last_read_value(user_ids: user_ids, at: reset_last_read) if reset_last_read with_response_pipelined(user_ids) do |redis, key| events = paginated_events(page, per_page, redis, key) with_total ? { events: events, total_count: redis.zcard(key.data) } : events end end
reset_last_read(user_ids:, at: Time.now)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 106 def reset_last_read(user_ids:, at: Time.now) with_response_pipelined(user_ids) do |redis, key, *| reset_users_last_read(redis, key, at.to_f) end end
store(user_ids:, value:, at: Time.now)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 36 def store(user_ids:, value:, at: Time.now) with_response_pipelined(user_ids) do |redis, key| tap redis.zadd(key.data, at.to_f, value) do redis.zremrangebyrank(key.data, 0, -feed.max_size - 1) end end end
total_count(user_ids:)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 112 def total_count(user_ids:) with_response_pipelined(user_ids) do |redis, key| redis.zcard(key.data) end end
total_memory_bytes()
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 136 def total_memory_bytes with_stats(:used_memory_since_boot) end
total_users()
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 140 def total_users with_redis { |redis| redis.dbsize / 2 } end
transform_response(user_id = nil, result)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 150 def transform_response(user_id = nil, result) case result when ::Redis::Future transform_response(user_id, result.value) when ::Hash if result.values.any? { |v| transformable_type?(v) } result.each { |k, v| result[k] = transform_response(user_id, v) } else result end when ::Array if result.any? { |v| transformable_type?(v) } result = result.map { |v| transform_response(user_id, v) } end if result.size == 2 && result[1].is_a?(Float) SimpleFeed::Event.new(value: result[0], at: Time.at(result[1])) else result end when ::String if result =~ /^\d+\.\d+$/ result.to_f elsif result =~ /^\d+$/ result.to_i else result end else result end end
transformable_type?(value)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 188 def transformable_type?(value) [ ::Redis::Future, ::Hash, ::Array, ::String ].include?(value.class) end
unread_count(user_ids:)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 118 def unread_count(user_ids:) response = with_response_pipelined(user_ids) do |redis, key| get_users_last_read(redis, key) end with_response_pipelined(response.user_ids, response) do |redis, key, _response| last_read = _response.delete(key.consumer).to_f redis.zcount(key.data, last_read, '+inf') end end
wipe(user_ids:)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 64 def wipe(user_ids:) with_response_pipelined(user_ids) do |redis, key| key.keys.all? { |redis_key| redis.del(redis_key) } end end
with_stats(operation)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 144 def with_stats(operation) with_redis do |redis| SimpleFeed::Providers::Redis::Stats.new(redis).send(operation) end end
Private Instance Methods
batch_multi(user_ids) { |redis, key(user_id)| ... }
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 264 def batch_multi(user_ids) to_array(user_ids).each_slice(batch_size) do |batch| batch.each do |user_id| with_multi do |redis| yield(redis, key(user_id)) end end end end
batch_pipelined(user_ids) { |redis, key(user_id)| ... }
click to toggle source
—————————————————————————————————————————————————————————————————————————————————————— Batch operations ——————————————————————————————————————————————————————————————————————————————————————
# File lib/simplefeed/providers/redis/provider.rb, line 242 def batch_pipelined(user_ids) to_array(user_ids).each_slice(batch_size) do |batch| with_pipelined do |redis| batch.each do |user_id| yield(redis, key(user_id)) end end end end
batch_pipelined_multi(user_ids) { |redis, key(user_id)| ... }
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 252 def batch_pipelined_multi(user_ids) to_array(user_ids).each_slice(batch_size) do |batch| with_pipelined do batch.each do |user_id| with_multi do |redis| yield(redis, key(user_id)) end end end end end
get_users_last_read(redis, key)
click to toggle source
returns a string containing a float, which must then be converted into float in transform
# File lib/simplefeed/providers/redis/provider.rb, line 211 def get_users_last_read(redis, key) redis.hget(key.meta, 'last_read') end
paginated_events(page, per_page, redis, key)
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 215 def paginated_events(page, per_page, redis, key) redis.zrevrange(key.data, (page - 1) * per_page, page * per_page - 1, withscores: true) end
reset_users_last_read(redis, key, time = nil)
click to toggle source
—————————————————————————————————————————————————————————————————————————————————————— helpers ——————————————————————————————————————————————————————————————————————————————————————
# File lib/simplefeed/providers/redis/provider.rb, line 203 def reset_users_last_read(redis, key, time = nil) time = time.nil? ? Time.now.to_f : time.to_f redis.hset(key.meta, 'last_read', time) Time.at(time) end
with_response_multi(user_ids, response = nil) { |redis, key, response| ... }
click to toggle source
# File lib/simplefeed/providers/redis/provider.rb, line 231 def with_response_multi(user_ids, response = nil) with_response(response) do |response| batch_multi(user_ids) do |redis, key| response.for(key.consumer) { yield(redis, key, response) } end end end
with_response_pipelined(user_ids, response = nil) { |redis, key, response| ... }
click to toggle source
—————————————————————————————————————————————————————————————————————————————————————— Operations with response ——————————————————————————————————————————————————————————————————————————————————————
# File lib/simplefeed/providers/redis/provider.rb, line 223 def with_response_pipelined(user_ids, response = nil) with_response(response) do |response| batch_pipelined(user_ids) do |redis, key| response.for(key.consumer) { yield(redis, key, response) } end end end