-
-
Save ismaelga/f09c6312421473a9e4c2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/indicator.rb | |
## | |
# Example usage: | |
# indicator = Indicator::UserActivity.new(user_id) | |
# | |
# When a new activity is added to a user's feed: | |
# indicator.increment | |
# | |
# When a user views their unseen activity: | |
# indicator.clear | |
# | |
# Does the user have any unseen activity? | |
# indicator.set? | |
# | |
# How many unseen activities does the user have? (for the iOS app) | |
# indicator.value | |
module Indicator | |
class Base # Abstract base class | |
# Store at most this many entries per hash. | |
# Allows ~7x memory compression with small CPU trade-off. | |
# Benchmark: http://git.io/Yo_lYA | |
# Docs: http://redis.io/topics/memory-optimization | |
MAX_HASH_ENTRIES = 512 | |
attr_accessor :obj_id | |
def initialize(obj) | |
self.obj_id = obj.respond_to?(:id) ? obj.id : obj.to_i | |
end | |
# Increment ids in bulk | |
def self.increment(ids) | |
redis.pipelined do | |
Array(ids).each {|id| new(id).increment } | |
end | |
end | |
def key_prefix | |
raise NotImplementedError | |
end | |
def hash_key | |
"#{key_prefix}:#{obj_id/MAX_HASH_ENTRIES}" | |
end | |
def clear | |
@value = nil | |
redis.hdel(hash_key, obj_id) | |
end | |
def increment | |
@value = nil | |
redis.hincrby(hash_key, obj_id, 1) | |
end | |
# Directly set the value. Only used for backfilling | |
def set(value) | |
@value = nil | |
redis.hset(hash_key, obj_id, value) | |
end | |
def value | |
@value ||= redis.hget(hash_key, obj_id).to_i | |
rescue ::Redis::BaseError | |
# Return 0 if anything goes wrong | |
# Prevent errors from bubbling up to views | |
0 | |
end | |
def set? | |
value > 0 | |
end | |
end | |
# Concrete classes must implement the `key_prefix` method | |
class UserActivity < Base | |
def key_prefix; 'indicators/user_activity'; end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Copyright 2014 Kickstarter, Inc. | |
Released under an MIT License. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/user.rb | |
class User < ActiveRecord::Base | |
def activity_indicator | |
@activity_indicator ||= Indicator::UserActivity.new(id) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment