1module EmailAllPetitionSignatories |
|
2 # Concern to add shared functionality to ActiveJob classes |
|
3 # that are responsible for enqueuing send email jobs |
|
5 extend ActiveSupport::Concern |
|
7 included do |
|
8 before_perform :set_appsignal_namespace |
|
10 class_attribute :email_delivery_job_class |
|
11 class_attribute :timestamp_name |
|
13 attr_reader :petition, :requested_at |
|
15 queue_as :high_priority |
|
16 end |
|
18 module ClassMethods |
|
19 def run_later_tonight(**args) |
|
20 petition, @requested_at = args[:petition], nil |
|
22 petition.set_email_requested_at_for(timestamp_name, to: requested_at) |
|
23 set(wait_until: later_tonight).perform_later(**args.merge(requested_at: requested_at_iso8601)) |
|
24 end |
|
26 private
|
|
28 def requested_at |
|
29 @requested_at ||= Time.current |
|
30 end |
|
32 def requested_at_iso8601 |
|
33 requested_at.getutc.iso8601(6) |
|
34 end |
|
36 def later_tonight |
|
37 midnight + random_interval
|
|
38 end |
|
40 def midnight |
|
41 requested_at.end_of_day
|
|
42 end |
|
44 def random_interval |
|
45 rand(240).minutes + rand(60).seconds |
|
46 end |
|
47 end |
|
|
49 def perform(**args) |
50 @petition, @requested_at = args[:petition], args[:requested_at] |
|
52 # If the petition has been updated since the job |
|
53 # was queued then don't send the emails. |
|
54 unless petition_has_been_updated? |
|
55 enqueue_send_email_jobs
|
|
56 end |
|
57 end |
|
59 private
|
|
61 # Batches the signataries to send emails to in groups of 1000 |
|
62 # and enqueues a job to do the actual sending |
|
|
63 def enqueue_send_email_jobs |
64 Appsignal.without_instrumentation do |
|
65 signatures_to_email.find_each do |signature| |
|
66 email_delivery_job_class.perform_later(**mailer_arguments(signature))
|
|
67 end |
|
68 end |
|
69 end |
|
|
71 def mailer_arguments(signature) |
72 {
|
|
73 signature: signature, |
|
74 timestamp_name: timestamp_name, |
|
75 petition: petition, |
|
76 requested_at: requested_at |
|
77 }
|
|
78 end |
|
80 # admins can ask to send the email multiple times and each time they |
|
81 # ask we enqueues a new job to send out emails with a new timestamp |
|
82 # we want to execute only the latest job enqueued |
|
|
83 def petition_has_been_updated? |
84 (petition_timestamp - requested_at.in_time_zone).abs > 1 |
|
85 end |
|
|
87 def petition_timestamp |
88 petition.get_email_requested_at_for(timestamp_name)
|
|
89 end |
|
|
91 def signatures_to_email |
92 petition.signatures_to_email_for(timestamp_name)
|
|
93 end |
|
|
95 def set_appsignal_namespace |
96 Appsignal.set_namespace("email") |
|
97 end |
|
98end |