From 2ea754b8610b50cc93aeb1921ecdf7415efaf17e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 4 Mar 2022 01:06:33 +0100 Subject: [PATCH] Fix duplicate notifications being possible after poll expiration (#17697) --- app/controllers/api/v1/follow_requests_controller.rb | 2 +- app/lib/activitypub/activity/announce.rb | 2 +- app/lib/activitypub/activity/follow.rb | 4 ++-- app/lib/activitypub/activity/like.rb | 2 +- app/services/bootstrap_timeline_service.rb | 2 +- app/services/favourite_service.rb | 2 +- app/workers/feed_insert_worker.rb | 2 +- app/workers/poll_expiration_notify_worker.rb | 8 +++++--- 8 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb index 8276245a31..54ff0e11d0 100644 --- a/app/controllers/api/v1/follow_requests_controller.rb +++ b/app/controllers/api/v1/follow_requests_controller.rb @@ -13,7 +13,7 @@ class Api::V1::FollowRequestsController < Api::BaseController def authorize AuthorizeFollowService.new.call(account, current_account) - NotifyService.new.call(current_account, :follow, Follow.find_by(account: account, target_account: current_account)) + LocalNotificationWorker.perform_async(current_account.id, Follow.find_by(account: account, target_account: current_account).id, 'Follow', 'follow') render json: account, serializer: REST::RelationshipSerializer, relationships: relationships end diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb index 7cd5a41e8e..0674b10833 100644 --- a/app/lib/activitypub/activity/announce.rb +++ b/app/lib/activitypub/activity/announce.rb @@ -35,7 +35,7 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity def distribute # Notify the author of the original status if that status is local - NotifyService.new.call(@status.reblog.account, :reblog, @status) if reblog_of_local_account?(@status) && !reblog_by_following_group_account?(@status) + LocalNotificationWorker.perform_async(@status.reblog.account_id, @status.id, 'Status', 'reblog') if reblog_of_local_account?(@status) && !reblog_by_following_group_account?(@status) # Distribute into home and list feeds ::DistributionWorker.perform_async(@status.id) if @options[:override_timestamps] || @status.within_realtime_window? diff --git a/app/lib/activitypub/activity/follow.rb b/app/lib/activitypub/activity/follow.rb index 4efb84b8c9..97e41ab789 100644 --- a/app/lib/activitypub/activity/follow.rb +++ b/app/lib/activitypub/activity/follow.rb @@ -31,10 +31,10 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity follow_request = FollowRequest.create!(account: @account, target_account: target_account, uri: @json['id']) if target_account.locked? || @account.silenced? - NotifyService.new.call(target_account, :follow_request, follow_request) + LocalNotificationWorker.perform_async(target_account.id, follow_request.id, 'FollowRequest', 'follow_request') else AuthorizeFollowService.new.call(@account, target_account) - NotifyService.new.call(target_account, :follow, ::Follow.find_by(account: @account, target_account: target_account)) + LocalNotificationWorker.perform_async(target_account.id, ::Follow.find_by(account: @account, target_account: target_account).id, 'Follow', 'follow') end end diff --git a/app/lib/activitypub/activity/like.rb b/app/lib/activitypub/activity/like.rb index ebbda15b9f..aa1dc30403 100644 --- a/app/lib/activitypub/activity/like.rb +++ b/app/lib/activitypub/activity/like.rb @@ -8,7 +8,7 @@ class ActivityPub::Activity::Like < ActivityPub::Activity favourite = original_status.favourites.create!(account: @account) - NotifyService.new.call(original_status.account, :favourite, favourite) + LocalNotificationWorker.perform_async(original_status.account_id, favourite.id, 'Favourite', 'favourite') Trends.statuses.register(original_status) end end diff --git a/app/services/bootstrap_timeline_service.rb b/app/services/bootstrap_timeline_service.rb index 312c163e47..a02e55a6df 100644 --- a/app/services/bootstrap_timeline_service.rb +++ b/app/services/bootstrap_timeline_service.rb @@ -18,7 +18,7 @@ class BootstrapTimelineService < BaseService def notify_staff! User.staff.includes(:account).find_each do |user| - NotifyService.new.call(user.account, :'admin.sign_up', @source_account) + LocalNotificationWorker.perform_async(user.account_id, @source_account.id, 'Account', 'admin.sign_up') end end end diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb index 0ca0081b48..dc7fe88552 100644 --- a/app/services/favourite_service.rb +++ b/app/services/favourite_service.rb @@ -31,7 +31,7 @@ class FavouriteService < BaseService status = favourite.status if status.account.local? - NotifyService.new.call(status.account, :favourite, favourite) + LocalNotificationWorker.perform_async(status.account_id, favourite.id, 'Favourite', 'favourite') elsif status.account.activitypub? ActivityPub::DeliveryWorker.perform_async(build_json(favourite), favourite.account_id, status.account.inbox_url) end diff --git a/app/workers/feed_insert_worker.rb b/app/workers/feed_insert_worker.rb index 6e3472d576..40bc9cb6e2 100644 --- a/app/workers/feed_insert_worker.rb +++ b/app/workers/feed_insert_worker.rb @@ -66,7 +66,7 @@ class FeedInsertWorker end def perform_notify - NotifyService.new.call(@follower, :status, @status) + LocalNotificationWorker.perform_async(@follower.id, @status.id, 'Status', 'status') end def update? diff --git a/app/workers/poll_expiration_notify_worker.rb b/app/workers/poll_expiration_notify_worker.rb index 7613ed5f15..0e29a5f60b 100644 --- a/app/workers/poll_expiration_notify_worker.rb +++ b/app/workers/poll_expiration_notify_worker.rb @@ -38,12 +38,14 @@ class PollExpirationNotifyWorker def notify_remote_voters_and_owner! ActivityPub::DistributePollUpdateWorker.perform_async(@poll.status.id) - NotifyService.new.call(@poll.account, :poll, @poll) + LocalNotificationWorker.perform_async(@poll.account_id, @poll.id, 'Poll', 'poll') end def notify_local_voters! - @poll.voters.merge(Account.local).find_each do |account| - NotifyService.new.call(account, :poll, @poll) + @poll.voters.merge(Account.local).select(:id).find_in_batches do |accounts| + LocalNotificationWorker.push_bulk(accounts) do |account| + [account.id, @poll.id, 'Poll', 'poll'] + end end end end