From 02a13d1619058b2a73a5040c24d80f3caeb01ed9 Mon Sep 17 00:00:00 2001 From: lnu Date: Thu, 21 Apr 2005 20:54:26 +0000 Subject: git-svn-id: svn+ssh://svn.gna.org/svn/feed2imap/trunk/feed2imap@21 f70e237a-67f3-0310-a06c-d2b8a7116972 --- ChangeLog | 2 ++ lib/feed2imap/cache.rb | 45 +++++++++++++++++++++++++++++++++++---------- lib/feed2imap/feed2imap.rb | 2 +- test/tc_cache.rb | 12 ++++++++---- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5a82c63..6560126 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ Feed2Imap 0.2 (date unknown) ============================ +* Fixed a problem with feeds with strange caching bugs (old items going away + and coming back) * The text version is now encoded in iso-8859-1 instead of utf-8. * The subject is now MIME-encoded in utf-8. It works with mutt & evo. * No longer overwrite mail flags (Read, Important,..) when updating an item. diff --git a/lib/feed2imap/cache.rb b/lib/feed2imap/cache.rb index c984a5d..48913f0 100644 --- a/lib/feed2imap/cache.rb +++ b/lib/feed2imap/cache.rb @@ -35,10 +35,10 @@ class ItemCache return @channels[id].get_new_items(items) end - # Replace the existing cached items by those ones - def update_cache(id, items) + # Commit changes to the cache + def commit_cache(id) @channels[id] ||= CachedChannel::new - @channels[id].update(items) + @channels[id].commit end # Get the last time the cache was updated @@ -91,18 +91,36 @@ class ItemCache end class CachedChannel + # Size of the cache for each feed + CACHESIZE = 50 + attr_accessor :lastcheck, :items def initialize @lastcheck = Time::at(0) @items = [] + @itemstemp = [] # see below + @nbnewitems = 0 end + # Let's explain @items and @itemstemp. + # @items contains the CachedItems serialized to the disk cache. + # The - quite complicated - get_new_items method fills in @itemstemp + # but leaves @items unchanged. + # Later, the commit() method replaces @items with @itemstemp and + # empties @itemstemp. This way, if something wrong happens during the + # upload to the IMAP server, items aren't lost. + # @nbnewitems is set by get_new_items, and is used to limit the number + # of (old) items serialized. + # Returns the really new items amongst items def get_new_items(items) + # save number of new items + @nbnewitems = items.length # set items' cached version if not set yet newitems = [] updateditems = [] + @itemstemp = @items items.each { |i| i.cacheditem ||= CachedItem::new(i) } items.each do |i| found = false @@ -111,6 +129,9 @@ class CachedChannel if i.cacheditem == j i.cacheditem.index = j.index found = true + # let's put j in front of itemstemp + @itemstemp.delete(j) + @itemstemp.unshift(j) break end end @@ -123,6 +144,9 @@ class CachedChannel i.cacheditem.updated = true updateditems.push(i) found = true + # let's put j in front of itemstemp + @itemstemp.delete(j) + @itemstemp.unshift(j) break end end @@ -130,16 +154,17 @@ class CachedChannel # add as new i.cacheditem.create_index newitems.push(i) + # add i.cacheditem to @itemstemp + @itemstemp.unshift(i.cacheditem) end return [newitems, updateditems] end - - # Replace the existing cached items by those ones - def update(items) - @items = [] - items.each do |i| - @items.push(i.cacheditem) - end + + def commit + # too old items must be dropped + n = @nbnewitems > CACHESIZE ? @nbnewitems : CACHESIZE + @items = @itemstemp[0..n] + @itemstemp = [] self end diff --git a/lib/feed2imap/feed2imap.rb b/lib/feed2imap/feed2imap.rb index daee87d..1df93bd 100644 --- a/lib/feed2imap/feed2imap.rb +++ b/lib/feed2imap/feed2imap.rb @@ -133,7 +133,7 @@ class Feed2Imap next end begin - @cache.update_cache(f.name, channel.items) + @cache.commit_cache(f.name) rescue @logger.fatal("Exception caught while updating cache for #{f.name}: #{$!}") next diff --git a/test/tc_cache.rb b/test/tc_cache.rb index d472d71..e03d81f 100755 --- a/test/tc_cache.rb +++ b/test/tc_cache.rb @@ -33,10 +33,14 @@ class ItemCacheTest < Test::Unit::TestCase i2.title = 'title2' i2.link = 'link2' i2.content = 'content2' + i3 = Item::new + i3.title = 'title3' + i3.link = 'link3' + i3.content = 'content3' assert_equal([i1, i2], c.get_new_items('id', [i1, i2])[0]) - c.update_cache('id', [i1]) - assert_equal(1, c.nbitems) - assert_equal([i2], c.get_new_items('id', [i1, i2])[0]) + c.commit_cache('id') + assert_equal(2, c.nbitems) + assert_equal([i3], c.get_new_items('id', [i2, i3])[0]) end def test_cache_management_updated @@ -57,7 +61,7 @@ class ItemCacheTest < Test::Unit::TestCase assert_equal(0, idx1) idx2 = i2.cacheditem.index assert_equal(1, idx2) - c.update_cache('id', [i1, i2]) + c.commit_cache('id') i3 = Item::new i3.title = 'title 1 - updated' i3.link = 'link1' -- cgit v1.2.3-54-g00ecf