Class: ArMailerAWS::Sender

Inherits:
Object
  • Object
show all
Defined in:
lib/ar_mailer_aws/sender.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Sender

Returns a new instance of Sender.



5
6
7
8
9
10
11
# File 'lib/ar_mailer_aws/sender.rb', line 5

def initialize(options={})
  @options = options.is_a?(Hash) ? OpenStruct.new(options) : options
  @model = ArMailerAWS.email_class.constantize
  @ses = AWS::SimpleEmailService.new ArMailerAWS.ses_options
  @day = Date.today
  @sent_count = 0
end

Instance Attribute Details

#modelObject (readonly)

Returns the value of attribute model.



3
4
5
# File 'lib/ar_mailer_aws/sender.rb', line 3

def model
  @model
end

#optionsObject (readonly)

Returns the value of attribute options.



3
4
5
# File 'lib/ar_mailer_aws/sender.rb', line 3

def options
  @options
end

#sesObject (readonly)

Returns the value of attribute ses.



3
4
5
# File 'lib/ar_mailer_aws/sender.rb', line 3

def ses
  @ses
end

Instance Method Details

#cleanupObject



68
69
70
71
72
73
74
# File 'lib/ar_mailer_aws/sender.rb', line 68

def cleanup
  return if options.max_age.to_i.zero?
  timeout = Time.now - options.max_age
  emails = @model.destroy_all(['last_send_attempt_at IS NOT NULL AND created_at < ?', timeout])

  log "expired #{emails.length} emails"
end

#exceed_quota?Boolean

Returns:

  • (Boolean)


46
47
48
49
50
51
52
53
54
# File 'lib/ar_mailer_aws/sender.rb', line 46

def exceed_quota?
  if @day == Date.today
    options.quota <= @sent_count + sent_last_24_hours
  else
    @sent_count = 0
    @sent_last_24_hours = nil
    false
  end
end

#find_emailsObject



64
65
66
# File 'lib/ar_mailer_aws/sender.rb', line 64

def find_emails
  @model.where('last_send_attempt_at IS NULL OR last_send_attempt_at < ?', Time.now - 300).limit(options.batch_size)
end

#log(msg, level = :info) ⇒ Object



76
77
78
79
80
81
82
83
84
# File 'lib/ar_mailer_aws/sender.rb', line 76

def log(msg, level=:info)
  formatted_msg = "[#{Time.now}] ar_mailer_aws: #{msg}"
  puts formatted_msg if options.verbose
  if logger
    logger.send(level, msg)
  elsif options.verbose && defined? Rails
    Rails.logger.send(level, formatted_msg)
  end
end

#loggerObject



86
87
88
# File 'lib/ar_mailer_aws/sender.rb', line 86

def logger
  ArMailerAWS.logger
end

#send_batchObject



13
14
15
16
17
18
# File 'lib/ar_mailer_aws/sender.rb', line 13

def send_batch
  cleanup
  emails = find_emails
  log "found #{emails.length} emails to deliver"
  send_emails(emails) unless emails.empty?
end

#send_emails(emails) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ar_mailer_aws/sender.rb', line 20

def send_emails(emails)
  sent_per_second = 0
  emails.each do |email|
    if exceed_quota?
      log "exceed daily quota in #{@quota}, sent by mailer #{@sent_count}, other #{@sent_last_24_hours}"
      return
    end
    begin
      if sent_per_second == options.rate
        sleep 1
        sent_per_second = 0
      else
        sent_per_second += 1
      end
      log "send email to #{email.to}"
      @ses.send_raw_email email.mail, from: email.from, to: email.to
      email.destroy
      @sent_count += 1
    rescue => e
      log "ERROR sending email #{email.id} - #{email.inspect}: #{e.message}\n   #{e.backtrace.join("\n   ")}", :error
      ArMailerAWS.error_proc.call(email, e) if ArMailerAWS.error_proc
      email.update_column(:last_send_attempt_at, Time.now)
    end
  end
end

#sent_last_24_hoursObject



56
57
58
59
60
61
62
# File 'lib/ar_mailer_aws/sender.rb', line 56

def sent_last_24_hours
  @sent_last_24_hours ||= begin
    count = @ses.quotas[:sent_last_24_hours]
    log "#{count} emails sent last 24 hours"
    count
  end
end