commit: 7cc71748cecfa6cb35bc53e656df39d6f9219ae2
parent: aec70b44fc551db6471c8bc5210688b154ac661f
Author: Eugen Rochko <eugen@zeonfederated.com>
Date: Mon, 16 Oct 2017 16:08:51 +0200
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)
Diffstat:
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git 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