diaspora/lib/diaspora/redis_cache.rb
Maxwell Salzberg 254860bddc SM MS; Read email sent to diaspora-dev for more information about this
commit. Add migration and rake task to copy hidden information from
share_visibilities to users. see: http://devblog.joindiaspora.com/?p=44
2012-01-17 19:29:01 -08:00

143 lines
3.1 KiB
Ruby

# Copyright (c) 2010-2011, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
class RedisCache
SUPPORTED_CACHES = [:created_at]
CACHE_LIMIT = 100
def initialize(user, order_field=:created_at)
@user = user
@order_field = order_field.to_s
end
# Checks to see if the necessary redis cache variables are set in application.yml
#
# @return [Boolean]
def self.configured?
AppConfig[:redis_cache].present?
end
def self.update_cache_for(user, post, post_was_hidden)
return unless RedisCache.configured?
cache = RedisCache.new(user, 'created_at')
if post_was_hidden
cache.remove(post.id)
else
cache.add(post.created_at.to_i, post.id)
end
end
# @return [Boolean]
def cache_exists?
self.redis.exists(set_key)
end
# @return [Integer] the cardinality of the redis set
def size
redis.zcard(set_key)
end
def post_ids(time=Time.now, limit=15)
post_ids = redis.zrevrangebyscore(set_key, time.to_i, "-inf")
post_ids[0...limit]
end
def ensure_populated!(opts = {})
self.repopulate!(opts) unless cache_exists?
end
def repopulate!(opts = {})
self.purge!
self.populate!(opts) && self.trim!
end
def purge!
self.redis.del(set_key)
end
def populate!(opts = {})
# user executes query and gets back hashes
opts.merge!({
:type => RedisCache.acceptable_types,
:limit => CACHE_LIMIT,
:order => self.order
})
sql = @user.visible_shareable_sql(Post, opts)
hashes = Post.connection.select_all(sql)
# hashes are inserted into set in a single transaction
redis.multi do
hashes.each do |h|
self.redis.zadd(set_key, h[@order_field].to_i, h["id"])
end
end
end
def trim!
self.redis.zremrangebyrank(set_key, 0, -(CACHE_LIMIT+1))
end
# @param order [Symbol, String]
# @return [Boolean]
def self.supported_order?(order)
SUPPORTED_CACHES.include?(order.to_sym)
end
def order
"#{@order_field} DESC"
end
def add(score, id)
return unless self.cache_exists?
self.redis.zadd(set_key, score.to_i, id)
self.trim!
end
def remove(id)
return unless self.cache_exists?
self.redis.zrem(set_key, id)
end
# exposing the need to tie cache to a stream
# @return [Array<String>] Acceptable Post types for the given cache
def self.acceptable_types
Stream::Base::TYPES_OF_POST_IN_STREAM
end
# Instantiate a redis connection
#
# @return [Redis]
def self.redis_connection
Redis.new(:host => RedisCache.redis_host, :port => RedisCache.redis_port)
end
protected
# @see .redis_connection
# @return [Redis]
def redis
@redis ||= RedisCache.redis_connection
end
def self.redis_host
(AppConfig[:redis_location].blank?) ? nil : AppConfig[:redis_location]
end
def self.redis_port
(AppConfig[:redis_port].blank?) ? nil : AppConfig[:redis_port]
end
# @return [String]
def self.cache_prefix
"cache_stream"
end
# @return [String]
def set_key
@set_key ||= "#{RedisCache.cache_prefix}_#{@user.id}_#{@order_field}"
end
end