class Unread::GarbageCollector

Attributes

readable_class[R]

Public Class Methods

new(readable_class) click to toggle source
# File lib/unread/garbage_collector.rb, line 3
def initialize(readable_class)
  @readable_class = readable_class.readable_parent
end

Public Instance Methods

run!() click to toggle source
# File lib/unread/garbage_collector.rb, line 8
def run!
  ReadMark.reader_classes.each do |reader_class|
    readers_to_cleanup(reader_class).find_each do |reader|
      if oldest_timestamp = readable_class.read_scope(reader).
                              unread_by(reader).
                              minimum(readable_class.readable_options[:on])
        # There are unread items, so update the global read_mark for this reader to the oldest
        # unread item and delete older read_marks
        update_read_marks_for_user(reader, oldest_timestamp)
      else
        # There is no unread item, so deletes all markers and move global timestamp
        readable_class.reset_read_marks_for_user(reader)
      end
    end
  end
end

Private Instance Methods

readers_to_cleanup(reader_class) click to toggle source

Not for every reader a cleanup is needed. Look for those readers with at least one single read mark

# File lib/unread/garbage_collector.rb, line 28
def readers_to_cleanup(reader_class)
  reader_class.
    reader_scope.
    joins(:read_marks).
    where(ReadMark.table_name => { readable_type: readable_class.name }).
    group("#{ReadMark.quoted_table_name}.reader_type, #{ReadMark.quoted_table_name}.reader_id, #{reader_class.quoted_table_name}.#{reader_class.quoted_primary_key}").
    having("COUNT(#{ReadMark.quoted_table_name}.id) > 1").
    select("#{reader_class.quoted_table_name}.#{reader_class.quoted_primary_key}")
end
update_read_marks_for_user(reader, timestamp) click to toggle source
# File lib/unread/garbage_collector.rb, line 38
def update_read_marks_for_user(reader, timestamp)
  ReadMark.transaction do
    # Delete markers OLDER than the given timestamp
    reader.read_marks.
      where(readable_type: readable_class.name).
      single.
      older_than(timestamp).
      delete_all

    # Change the global timestamp for this reader
    rm = reader.read_mark_global(readable_class) || reader.read_marks.build
    rm.readable_type = readable_class.name
    rm.timestamp     = timestamp - 1.second
    rm.save!
  end
end