@@ -20,33 +20,35 @@ def delete_person
2020 def delete_note
2121 return if object_uri . nil?
2222
23- unless invalid_origin? ( object_uri )
24- RedisLock . acquire ( lock_options ) { |_lock | delete_later! ( object_uri ) }
25- Tombstone . find_or_create_by ( uri : object_uri , account : @account )
26- end
23+ lock_or_return ( "delete_status_in_progress:#{ object_uri } " , 5 . minutes . seconds ) do
24+ unless invalid_origin? ( object_uri )
25+ # This lock ensures a concurrent `ActivityPub::Activity::Create` either
26+ # does not create a status at all, or has finished saving it to the
27+ # database before we try to load it.
28+ # Without the lock, `delete_later!` could be called after `delete_arrived_first?`
29+ # and `Status.find` before `Status.create!`
30+ lock_or_fail ( "create:#{ object_uri } " ) { delete_later! ( object_uri ) }
2731
28- @status = Status . find_by ( uri : object_uri , account : @account )
29- @status ||= Status . find_by ( uri : @object [ 'atomUri' ] , account : @account ) if @object . is_a? ( Hash ) && @object [ 'atomUri' ] . present?
32+ Tombstone . find_or_create_by ( uri : object_uri , account : @account )
33+ end
3034
31- return if @status . nil?
35+ @status = Status . find_by ( uri : object_uri , account : @account )
36+ @status ||= Status . find_by ( uri : @object [ 'atomUri' ] , account : @account ) if @object . is_a? ( Hash ) && @object [ 'atomUri' ] . present?
3237
33- if @status . distributable?
34- forward_for_reply
35- forward_for_reblogs
36- end
38+ return if @status . nil?
3739
38- delete_now!
40+ forward! if @json [ 'signature' ] . present? && @status . distributable?
41+ delete_now!
42+ end
3943 end
4044
41- def forward_for_reblogs
42- return if @json [ 'signature' ] . blank?
43-
44- rebloggers_ids = @status . reblogs . includes ( :account ) . references ( :account ) . merge ( Account . local ) . pluck ( :account_id )
45- inboxes = Account . where ( id : ::Follow . where ( target_account_id : rebloggers_ids ) . select ( :account_id ) ) . inboxes - [ @account . preferred_inbox_url ]
45+ def rebloggers_ids
46+ return @rebloggers_ids if defined? ( @rebloggers_ids )
47+ @rebloggers_ids = @status . reblogs . includes ( :account ) . references ( :account ) . merge ( Account . local ) . pluck ( :account_id )
48+ end
4649
47- ActivityPub ::LowPriorityDeliveryWorker . push_bulk ( inboxes ) do |inbox_url |
48- [ payload , rebloggers_ids . first , inbox_url ]
49- end
50+ def inboxes_for_reblogs
51+ Account . where ( id : ::Follow . where ( target_account_id : rebloggers_ids ) . select ( :account_id ) ) . inboxes
5052 end
5153
5254 def replied_to_status
@@ -58,13 +60,19 @@ def reply_to_local?
5860 !replied_to_status . nil? && replied_to_status . account . local?
5961 end
6062
61- def forward_for_reply
62- return unless @json [ 'signature' ] . present? && reply_to_local?
63+ def inboxes_for_reply
64+ replied_to_status . account . followers . inboxes
65+ end
66+
67+ def forward!
68+ inboxes = inboxes_for_reblogs
69+ inboxes += inboxes_for_reply if reply_to_local?
70+ inboxes -= [ @account . preferred_inbox_url ]
6371
64- inboxes = replied_to_status . account . followers . inboxes - [ @account . preferred_inbox_url ]
72+ sender_id = reply_to_local? ? replied_to_status . account_id : rebloggers_ids . first
6573
66- ActivityPub ::LowPriorityDeliveryWorker . push_bulk ( inboxes ) do |inbox_url |
67- [ payload , replied_to_status . account_id , inbox_url ]
74+ ActivityPub ::LowPriorityDeliveryWorker . push_bulk ( inboxes . uniq ) do |inbox_url |
75+ [ payload , sender_id , inbox_url ]
6876 end
6977 end
7078
@@ -75,8 +83,4 @@ def delete_now!
7583 def payload
7684 @payload ||= Oj . dump ( @json )
7785 end
78-
79- def lock_options
80- { redis : Redis . current , key : "create:#{ object_uri } " }
81- end
8286end
0 commit comments