lib/monocle.rb in monocle-0.2.0 vs lib/monocle.rb in monocle-0.2.1
- old
+ new
@@ -11,11 +11,13 @@
class_attribute :_monocle_options,
:_monocle_view_types,
:_monocle_redis_connection
self._monocle_options = {
- cache_view_counts: false
+ cache_view_counts: false,
+ cache_threshold: 15.minutes,
+ cache_threshold_check_field: :updated_at
}
self._monocle_view_types = {
overall: -> { 'overall' },
yearly: -> { Time.now.beginning_of_year },
@@ -50,26 +52,58 @@
field.is_a?(String) ? field : field.to_i
end
end
end
- def most_viewed_since(since, limit = 1000)
- objects = self._monocle_redis_connection.zrevrangebyscore(self.monocle_key, Time.now.to_i, since.to_i, limit: [0, limit])
- objects.collect { |o| self.find(o[0]) }
+ def recently_viewed_since(since, options = {})
+ options[:limit] ||= 1000
+ options[:with_objects] = options.has_key?(:with_objects) ? options[:with_objects] : true
+
+ results = self._monocle_redis_connection.zrevrangebyscore(self.monocle_key('recently_viewed'), Time.now.to_i, since.to_i, limit:[0, options[:limit]])
+ options[:with_objects] ? results.map { |id| self.find(id) } : results
end
+
+ def most_viewed_since(since, options = {})
+ options[:limit] ||= 1000
+ options[:with_objects] = options.has_key?(:with_objects) ? options[:with_objects] : true
+
+ viewed_by_score = self._monocle_redis_connection.zrevrangebyscore(self.monocle_key('view_counts'), '+inf', '-inf', limit: [0, options[:limit]])
+ results = viewed_by_score & recently_viewed_since(since, with_objects: false, limit: options[:limit])
+ options[:with_objects] ? results.map { |id| self.find(id) } : results
+ end
end
def view!
- self._monocle_view_types.keys.each do |view_type|
- cache_field = "#{view_type}_views".to_sym
- count = self._monocle_redis_connection.hincrby(self.class.monocle_key(id), self.send("#{view_type}_views_field"), 1)
- if self._monocle_options[:cache_view_counts] && respond_to?(cache_field)
- update_column(cache_field, count) if respond_to?(:update_column)
- set(cache_field, count) if respond_to?(:set)
+ results = self._monocle_redis_connection.pipelined do
+ self._monocle_view_types.keys.each do |view_type|
+ self._monocle_redis_connection.hincrby(self.class.monocle_key(id), self.send("#{view_type}_views_field"), 1)
end
+ self._monocle_redis_connection.zadd(self.class.monocle_key('recently_viewed'), Time.now.to_i, id)
+ self._monocle_redis_connection.zincrby(self.class.monocle_key('view_counts'), 1, id)
end
- self._monocle_redis_connection.zadd(self.class.monocle_key, Time.now.to_i, id)
+ if should_cache_view_count?
+ self._monocle_view_types.keys.each_with_index do |view_type, i|
+ cache_view_count(view_type, results[i])
+ end
+ end
+ end
+
+ def cache_field_for_view(view_type)
+ :"#{view_type}_views"
+ end
+
+ def should_cache_view_count?
+ if self._monocle_options[:cache_view_counts]
+ self.send(self._monocle_options[:cache_threshold_check_field]) < (Time.now - self._monocle_options[:cache_threshold])
+ else
+ false
+ end
+ end
+
+ def cache_view_count(view_type, count)
+ update_column(cache_field_for_view(view_type), count) if respond_to?(:update_column)
+ set(cache_field_for_view(view_type), count) if respond_to?(:set)
end
def destroy_views
self._monocle_redis_connection.del(self.class.monocle_key(id))
end