Filter Duplicate Boosts: Difference between revisions
(Created page with "{{Project |Description=Prevent duplicated boosts in public timelines like in home timelines |Part Of=Mastodon/Hacking |Parts= |Contributors=Jonny |Has Git Repository=https://github.com/NeuromatchAcademy/mastodon |Completion Status=Stub |Active Status=Inactive }}") |
No edit summary |
||
Line 8: | Line 8: | ||
|Active Status=Inactive | |Active Status=Inactive | ||
}} | }} | ||
== Problem == | |||
People like boosts in local timeline, but don't like seeing the same boost a zillion times. | |||
Public feeds work differently than home feeds: | |||
* Public feeds use a [https://github.com/NeuromatchAcademy/mastodon/blob/main/app/models/public_feed.rb public_feed] model that is a scoped database query | |||
<syntaxhighlight lang="ruby"> | |||
def get(limit, max_id = nil, since_id = nil, min_id = nil) | |||
scope = public_scope | |||
scope.merge!(without_local_only_scope) unless allow_local_only? | |||
scope.merge!(without_replies_scope) unless with_replies? | |||
scope.merge!(without_reblogs_scope) unless with_reblogs? | |||
scope.merge!(local_only_scope) if local_only? | |||
scope.merge!(remote_only_scope) if remote_only? | |||
scope.merge!(account_filters_scope) if account? | |||
scope.merge!(media_only_scope) if media_only? | |||
scope.merge!(language_scope) if account&.chosen_languages.present? | |||
scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) | |||
end | |||
</syntaxhighlight> | |||
* Home feeds use a [https://github.com/NeuromatchAcademy/mastodon/blob/main/app/lib/feed_manager.rb feed_manager] class that inserts posts into a persistent list, which applies the boost filter at the time of that insertion: | |||
<syntaxhighlight lang="ruby"> | |||
def add_to_feed(timeline_type, account_id, status, aggregate_reblogs: true) | |||
timeline_key = key(timeline_type, account_id) | |||
reblog_key = key(timeline_type, account_id, 'reblogs') | |||
if status.reblog? && (aggregate_reblogs.nil? || aggregate_reblogs) | |||
# If the original status or a reblog of it is within | |||
# REBLOG_FALLOFF statuses from the top, do not re-insert it into | |||
# the feed | |||
rank = redis.zrevrank(timeline_key, status.reblog_of_id) | |||
return false if !rank.nil? && rank < FeedManager::REBLOG_FALLOFF | |||
# The ordered set at `reblog_key` holds statuses which have a reblog | |||
# in the top `REBLOG_FALLOFF` statuses of the timeline | |||
if redis.zadd(reblog_key, status.id, status.reblog_of_id, nx: true) | |||
# This is not something we've already seen reblogged, so we | |||
# can just add it to the feed (and note that we're reblogging it). | |||
redis.zadd(timeline_key, status.id, status.id) | |||
else | |||
# Another reblog of the same status was already in the | |||
# REBLOG_FALLOFF most recent statuses, so we note that this | |||
# is an "extra" reblog, by storing it in reblog_set_key. | |||
reblog_set_key = key(timeline_type, account_id, "reblogs:#{status.reblog_of_id}") | |||
redis.sadd(reblog_set_key, status.id) | |||
return false | |||
end | |||
else | |||
# A reblog may reach earlier than the original status because of the | |||
# delay of the worker delivering the original status, the late addition | |||
# by merging timelines, and other reasons. | |||
# If such a reblog already exists, just do not re-insert it into the feed. | |||
return false unless redis.zscore(reblog_key, status.id).nil? | |||
redis.zadd(timeline_key, status.id, status.id) | |||
end | |||
true | |||
end | |||
</syntaxhighlight> | |||
== References == | |||
* https://github.com/glitch-soc/mastodon/issues/2481 |
Revision as of 17:34, 24 January 2024
Filter Duplicate Boosts | |
---|---|
Description | Prevent duplicated boosts in public timelines like in home timelines |
Part Of | Mastodon/Hacking |
Contributors | Jonny |
Has Git Repository | https://github.com/NeuromatchAcademy/mastodon |
Completion Status | Stub |
Active Status | Inactive |
Problem
People like boosts in local timeline, but don't like seeing the same boost a zillion times.
Public feeds work differently than home feeds:
- Public feeds use a public_feed model that is a scoped database query
def get(limit, max_id = nil, since_id = nil, min_id = nil)
scope = public_scope
scope.merge!(without_local_only_scope) unless allow_local_only?
scope.merge!(without_replies_scope) unless with_replies?
scope.merge!(without_reblogs_scope) unless with_reblogs?
scope.merge!(local_only_scope) if local_only?
scope.merge!(remote_only_scope) if remote_only?
scope.merge!(account_filters_scope) if account?
scope.merge!(media_only_scope) if media_only?
scope.merge!(language_scope) if account&.chosen_languages.present?
scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
end
- Home feeds use a feed_manager class that inserts posts into a persistent list, which applies the boost filter at the time of that insertion:
def add_to_feed(timeline_type, account_id, status, aggregate_reblogs: true)
timeline_key = key(timeline_type, account_id)
reblog_key = key(timeline_type, account_id, 'reblogs')
if status.reblog? && (aggregate_reblogs.nil? || aggregate_reblogs)
# If the original status or a reblog of it is within
# REBLOG_FALLOFF statuses from the top, do not re-insert it into
# the feed
rank = redis.zrevrank(timeline_key, status.reblog_of_id)
return false if !rank.nil? && rank < FeedManager::REBLOG_FALLOFF
# The ordered set at `reblog_key` holds statuses which have a reblog
# in the top `REBLOG_FALLOFF` statuses of the timeline
if redis.zadd(reblog_key, status.id, status.reblog_of_id, nx: true)
# This is not something we've already seen reblogged, so we
# can just add it to the feed (and note that we're reblogging it).
redis.zadd(timeline_key, status.id, status.id)
else
# Another reblog of the same status was already in the
# REBLOG_FALLOFF most recent statuses, so we note that this
# is an "extra" reblog, by storing it in reblog_set_key.
reblog_set_key = key(timeline_type, account_id, "reblogs:#{status.reblog_of_id}")
redis.sadd(reblog_set_key, status.id)
return false
end
else
# A reblog may reach earlier than the original status because of the
# delay of the worker delivering the original status, the late addition
# by merging timelines, and other reasons.
# If such a reblog already exists, just do not re-insert it into the feed.
return false unless redis.zscore(reblog_key, status.id).nil?
redis.zadd(timeline_key, status.id, status.id)
end
true
end