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)
This commit is contained in:
		| @ -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 | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user