-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(trust & safety): [SOCIALPLAT-766] Immediately remove public copy of media when status is deleted #54
feat(trust & safety): [SOCIALPLAT-766] Immediately remove public copy of media when status is deleted #54
Conversation
Immediately remove public copy of media when status is deleted. - Updated `destroy` method in StatusesController - Updated unit tests JIRA reference: https://mozilla-hub.atlassian.net/browse/SOCIALPLAT-766
de1fad1
to
e7fd119
Compare
|
||
def destroy_associated_media! | ||
@status.ordered_media_attachments.each do |media| | ||
media.destroy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this only removes the Ruby object that keeps track of the media. In order to actually delete the media from S3/filesystem/wherever it is stored, we need to use the delete
method from AttachmentBatch
, similar to how vacuum_orphaned_records
does.
if @status.with_media? | ||
# Immediately remove public copy of media instead of waiting for | ||
# the vacuum_orphaned_records job to take care of it later on | ||
destroy_associated_media |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This same logic needs to also happen in status_actions_controller.rb
when type
is delete
. See the original API design doc for why the delete action is duplicated in two places.
Kat and I were discussing the possibility of pulling this function out (e.g. it could be another option in the RemovalWorker
) so that it can be used in both places. Alternatively I don't think it's a huge deal if it's just repeated in both files since I think it can ultimately be a one-liner: AttachmentBatch.new(MediaAttachment, @status.media_attachments).delete
(see comment below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored this into a Worker and added tests - do you think there's any benefit in abstracting the if
statement into the Worker class, too? I was thinking it doesn't need to know anything about the status, only attachments, so kept it simple in the new class and used the conditional statement in both places in the code where attachments need to be deleted immediately.
@@ -48,4 +55,11 @@ def unsensitive | |||
def set_status | |||
@status = Status.find(params[:id]) | |||
end | |||
|
|||
def destroy_associated_media! | |||
@status.ordered_media_attachments.each do |media| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: doesn't need to be ordered_
2e2e63e
to
12e6e51
Compare
12e6e51
to
93250ea
Compare
054832d
to
3111e59
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @nina-py ! I'm missing context so this review might not hold up, but looks good apart from my questions below...
|
||
# Immediately remove public copy of media instead of waiting for | ||
# the vacuum_orphaned_records job to take care of it later on | ||
Admin::MediaAttachmentDeletionWorker.perform_inline(status.media_attachments) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this function be perform()
instead of perform_inline()
? I don't see perform_inline()
defined in the class, but maybe it's some sort of Rails sorcery?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Amri for having a look! We want the action to trigger immediately, so it should be perform_inline
. The worker class itself has one method - perform
, and it can be invoked with perform_inline
for sync action or perform_async
for asynchronous action behind the scenes.
There are a couple more methods like perform_in
but they delay action rather than speed it up, so perform_inline
is the best we can access, with the caveat that it will hold up that entire transaction though.
https://www.rubydoc.info/gems/sidekiq/Sidekiq/Job/ClassMethods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah – thanks for the education!
sidekiq_options queue: 'pull', lock: :until_executed, lock_ttl: 1.week.to_i | ||
|
||
def perform(media_attachments) | ||
AttachmentBatch.new(MediaAttachment, media_attachments).clear |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nina-py why did you choose clear
here instead of delete
?
class Admin::MediaAttachmentDeletionWorker | ||
include Sidekiq::Worker | ||
|
||
sidekiq_options queue: 'pull', lock: :until_executed, lock_ttl: 1.week.to_i |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 week seems too long for a Worker that will mostly be executed synchronously?
Immediately remove public copy of media when status is deleted.
destroy
method in StatusesControllerJIRA reference: https://mozilla-hub.atlassian.net/browse/SOCTRUST-31