Spawn FeedInsertWorker to deliver status into personal feed
This commit is contained in:
		| @@ -11,11 +11,11 @@ class FeedManager | ||||
|     "feed:#{type}:#{id}" | ||||
|   end | ||||
|  | ||||
|   def filter?(timeline_type, status, receiver) | ||||
|   def filter?(timeline_type, status, receiver_id) | ||||
|     if timeline_type == :home | ||||
|       filter_from_home?(status, receiver) | ||||
|       filter_from_home?(status, receiver_id) | ||||
|     elsif timeline_type == :mentions | ||||
|       filter_from_mentions?(status, receiver) | ||||
|       filter_from_mentions?(status, receiver_id) | ||||
|     else | ||||
|       false | ||||
|     end | ||||
| @@ -91,39 +91,39 @@ class FeedManager | ||||
|     Redis.current | ||||
|   end | ||||
|  | ||||
|   def filter_from_home?(status, receiver) | ||||
|   def filter_from_home?(status, receiver_id) | ||||
|     return true if status.reply? && status.in_reply_to_id.nil? | ||||
|  | ||||
|     check_for_mutes = [status.account_id] | ||||
|     check_for_mutes.concat([status.reblog.account_id]) if status.reblog? | ||||
|  | ||||
|     return true if receiver.muting?(check_for_mutes) | ||||
|     return true if Mute.where(account_id: receiver_id, target_account_id: check_for_mutes).any? | ||||
|  | ||||
|     check_for_blocks = status.mentions.map(&:account_id) | ||||
|     check_for_blocks.concat([status.reblog.account_id]) if status.reblog? | ||||
|  | ||||
|     return true if receiver.blocking?(check_for_blocks) | ||||
|     return true if Block.where(account_id: receiver_id, target_account_id: check_for_blocks).any? | ||||
|  | ||||
|     if status.reply? && !status.in_reply_to_account_id.nil?                   # Filter out if it's a reply | ||||
|       should_filter   = !receiver.following?(status.in_reply_to_account)      # and I'm not following the person it's a reply to | ||||
|       should_filter &&= !(receiver.id == status.in_reply_to_account_id)       # and it's not a reply to me | ||||
|       should_filter &&= !(status.account_id == status.in_reply_to_account_id) # and it's not a self-reply | ||||
|     if status.reply? && !status.in_reply_to_account_id.nil?                                                              # Filter out if it's a reply | ||||
|       should_filter   = !Follow.where(account_id: receiver_id, target_account_id: status.in_reply_to_account_id).exists? # and I'm not following the person it's a reply to | ||||
|       should_filter &&= !(receiver_id == status.in_reply_to_account_id)                                                  # and it's not a reply to me | ||||
|       should_filter &&= !(status.account_id == status.in_reply_to_account_id)                                            # and it's not a self-reply | ||||
|       return should_filter | ||||
|     elsif status.reblog?                                                      # Filter out a reblog | ||||
|       return status.reblog.account.blocking?(receiver)                        # or if the author of the reblogged status is blocking me | ||||
|     elsif status.reblog?                                                                                                 # Filter out a reblog | ||||
|       return Block.where(account_id: status.reblog.account_id, target_account_id: receiver_id).exists?                   # or if the author of the reblogged status is blocking me | ||||
|     end | ||||
|  | ||||
|     false | ||||
|   end | ||||
|  | ||||
|   def filter_from_mentions?(status, receiver) | ||||
|   def filter_from_mentions?(status, receiver_id) | ||||
|     check_for_blocks = [status.account_id] | ||||
|     check_for_blocks.concat(status.mentions.select('account_id').map(&:account_id)) | ||||
|     check_for_blocks.concat([status.in_reply_to_account]) if status.reply? && !status.in_reply_to_account_id.nil? | ||||
|  | ||||
|     should_filter   = receiver.id == status.account_id                                      # Filter if I'm mentioning myself | ||||
|     should_filter ||= receiver.blocking?(check_for_blocks)                                  # or it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked | ||||
|     should_filter ||= (status.account.silenced? && !receiver.following?(status.account))    # of if the account is silenced and I'm not following them | ||||
|     should_filter   = receiver_id == status.account_id                                                                                   # Filter if I'm mentioning myself | ||||
|     should_filter ||= Block.where(account_id: receiver_id, target_account_id: check_for_blocks).any?                                     # or it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked | ||||
|     should_filter ||= (status.account.silenced? && !Follow.where(account_id: receiver_id, target_account_id: status.account_id).exists?) # of if the account is silenced and I'm not following them | ||||
|  | ||||
|     should_filter | ||||
|   end | ||||
|   | ||||
| @@ -33,9 +33,8 @@ class FanOutOnWriteService < BaseService | ||||
|   def deliver_to_followers(status) | ||||
|     Rails.logger.debug "Delivering status #{status.id} to followers" | ||||
|  | ||||
|     status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).find_each do |follower| | ||||
|       next if FeedManager.instance.filter?(:home, status, follower) | ||||
|       FeedManager.instance.push(:home, follower, status) | ||||
|     status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).select(:id).find_each do |follower| | ||||
|       FeedInsertWorker.perform_async(status.id, follower.id) | ||||
|     end | ||||
|   end | ||||
|  | ||||
| @@ -44,7 +43,7 @@ class FanOutOnWriteService < BaseService | ||||
|  | ||||
|     status.mentions.includes(:account).each do |mention| | ||||
|       mentioned_account = mention.account | ||||
|       next if !mentioned_account.local? || !mentioned_account.following?(status.account) || FeedManager.instance.filter?(:home, status, mentioned_account) | ||||
|       next if !mentioned_account.local? || !mentioned_account.following?(status.account) || FeedManager.instance.filter?(:home, status, mention.account_id) | ||||
|       FeedManager.instance.push(:home, mentioned_account, status) | ||||
|     end | ||||
|   end | ||||
| @@ -54,9 +53,9 @@ class FanOutOnWriteService < BaseService | ||||
|  | ||||
|     payload = FeedManager.instance.inline_render(nil, 'api/v1/statuses/show', status) | ||||
|  | ||||
|     status.tags.find_each do |tag| | ||||
|       FeedManager.instance.broadcast("hashtag:#{tag.name}", event: 'update', payload: payload) | ||||
|       FeedManager.instance.broadcast("hashtag:#{tag.name}:local", event: 'update', payload: payload) if status.account.local? | ||||
|     status.tags.pluck(:name).each do |hashtag| | ||||
|       FeedManager.instance.broadcast("hashtag:#{hashtag}", event: 'update', payload: payload) | ||||
|       FeedManager.instance.broadcast("hashtag:#{hashtag}:local", event: 'update', payload: payload) if status.account.local? | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ class NotifyService < BaseService | ||||
|   private | ||||
|  | ||||
|   def blocked_mention? | ||||
|     FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient) | ||||
|     FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient.id) | ||||
|   end | ||||
|  | ||||
|   def blocked_favourite? | ||||
|   | ||||
| @@ -7,7 +7,7 @@ class PrecomputeFeedService < BaseService | ||||
|   def call(_, account) | ||||
|     redis.pipelined do | ||||
|       Status.as_home_timeline(account).limit(FeedManager::MAX_ITEMS / 4).each do |status| | ||||
|         next if status.direct_visibility? || FeedManager.instance.filter?(:home, status, account) | ||||
|         next if status.direct_visibility? || FeedManager.instance.filter?(:home, status, account.id) | ||||
|         redis.zadd(FeedManager.instance.key(:home, account.id), status.id, status.reblog? ? status.reblog_of_id : status.id) | ||||
|       end | ||||
|     end | ||||
|   | ||||
							
								
								
									
										15
									
								
								app/workers/feed_insert_worker.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/workers/feed_insert_worker.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| # frozen_string_literal: true | ||||
|  | ||||
| class FeedInsertWorker | ||||
|   include Sidekiq::Worker | ||||
|  | ||||
|   def perform(status_id, follower_id) | ||||
|     status   = Status.find(status_id) | ||||
|     follower = Account.find(follower_id) | ||||
|  | ||||
|     return if FeedManager.instance.filter?(:home, status, follower.id) | ||||
|     FeedManager.instance.push(:home, follower, status) | ||||
|   rescue ActiveRecord::RecordNotFound | ||||
|     true | ||||
|   end | ||||
| end | ||||
		Reference in New Issue
	
	Block a user