From 7cc71748cecfa6cb35bc53e656df39d6f9219ae2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 16 Oct 2017 16:08:51 +0200 Subject: [PATCH] Ensure that feed renegeration restores non-zero items (#5409) Fix #5398 Ordering the home timeline query by account_id meant that the first 100 items belonged to a single account. There was also no reason to reverse-iterate over the statuses. Assuming the user accesses the feed halfway-through, it's better to have recent statuses already available at the top. Therefore working from newer->older is ideal. If the algorithm ends up filtering all items out during last-mile filtering, repeat again a page further. The algorithm terminates when either at least one item has been added, or if the database query returns nothing (end of data reached) --- app/lib/feed_manager.rb | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index dfd11a23b..cc19c1d1a 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -100,11 +100,24 @@ class FeedManager end def populate_feed(account) - prepopulate_limit = FeedManager::MAX_ITEMS / 4 - statuses = Status.as_home_timeline(account).order(account_id: :desc).limit(prepopulate_limit) - statuses.reverse_each do |status| - next if filter_from_home?(status, account) - add_to_feed(:home, account, status) + added = 0 + limit = FeedManager::MAX_ITEMS / 2 + max_id = nil + + loop do + statuses = Status.as_home_timeline(account) + .paginate_by_max_id(limit, max_id) + + break if statuses.empty? + + statuses.each do |status| + next if filter_from_home?(status, account) + added += 1 if add_to_feed(:home, account, status) + end + + break unless added.zero? + + max_id = statuses.last.id end end