]> cat aescling's git repositories - mastodon.git/commitdiff
Ensure that feed renegeration restores non-zero items (#5409)
authorEugen Rochko <eugen@zeonfederated.com>
Mon, 16 Oct 2017 14:08:51 +0000 (16:08 +0200)
committerGitHub <noreply@github.com>
Mon, 16 Oct 2017 14:08:51 +0000 (16:08 +0200)
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

index dfd11a23b29df1f262d3d0a3b756211b6afbaa22..cc19c1d1af85feec17acb87653bb0ab9ea0e9138 100644 (file)
@@ -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