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