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