Class: Privacy::DataDeletionWorker
- Inherits:
-
Object
- Object
- Privacy::DataDeletionWorker
- Includes:
- Sidekiq::Job
- Defined in:
- app/workers/privacy/data_deletion_worker.rb
Overview
Sidekiq worker: drives a DeletionRequest through its lifecycle.
Trigger path:
- Webhooks::V1::Facebook::DataDeletionController#create (or the admin
"approve" action for held requests) enqueues
Privacy::DataDeletionWorker.perform_async(request.id) - Worker atomically claims the row by transitioning
pending→
processingin a single UPDATE; if the row was already claimed by
a parallel run (or another state), the worker returns immediately - Resolves the FB UID → Authentication → Account → Party (or pulls
account_id/party_idalready set by the admin manual-intake form) - Runs ManualReviewDetector — bails to
held_for_reviewif
any Tier-3 trigger fires (admin gets an email; queue surfaces in
/admin/privacy/deletion_requests) - Runs ScrubService inside the transaction; on success
transitions tocompleted, on failure tofailedfor human follow-up - Enqueues ProcessorDetachWorker for async Stripe/PayPal
detach (separate worker so a flaky outbound HTTP call cannot roll
back the local scrub) - Any uncaught exception is caught at the top level, the request
is transitioned tofailedwith the error captured for the admin
review queue, then re-raised so Sidekiq's error log records it too
Sidekiq worker: scrubs a Privacy::DeletionRequest.
Instance Method Summary collapse
-
#perform(deletion_request_id) ⇒ Object
Runs the job.
Instance Method Details
#perform(deletion_request_id) ⇒ Object
Runs the job.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'app/workers/privacy/data_deletion_worker.rb', line 44 def perform(deletion_request_id) # Atomic claim: a single UPDATE WHERE state = 'pending' moves the # row to `processing`. If two workers race, only one update affects # a row; the other returns early. Eliminates the duplicate-scrub / # duplicate-email window between `find_by` and `start_processing`. claimed_rows = Privacy::DeletionRequest .where(id: deletion_request_id, state: 'pending') .update_all(state: 'processing', updated_at: Time.current) # rubocop:disable Rails/SkipsModelValidations return if claimed_rows.zero? req = Privacy::DeletionRequest.find(deletion_request_id) Rails.logger.info("Privacy::DataDeletionWorker starting request=#{req.id} source=#{req.source}") run_scrub_for(req) rescue StandardError => e # Top-level safety net. With `retry: false`, any uncaught exception # would otherwise leave the request stuck in `processing` forever. handle_uncaught_exception(req, e) raise end |