Arthur POULET
cbf43f741d
The cache was not working properly as it intercepted all the emails except for the first receiver.
70 lines
1.6 KiB
Ruby
70 lines
1.6 KiB
Ruby
require "net/smtp"
|
|
|
|
# High level Interface to distribute Protocols::Mail objects.
|
|
# It is robust against network loss.
|
|
class Protocols::Smtp
|
|
def initialize
|
|
reset_smtp_client!
|
|
end
|
|
|
|
class DistributedCache < Array
|
|
def initialize(max_size: 4096)
|
|
@max_size = max_size
|
|
super()
|
|
end
|
|
|
|
def <<(message_id)
|
|
prepend(message_id) if !message_id.nil?
|
|
slice! @max_size
|
|
end
|
|
end
|
|
|
|
def cache
|
|
(@cache ||= DistributedCache.new)
|
|
end
|
|
|
|
# @param mail [Protocols::Mail]
|
|
def distribute(mail)
|
|
if cache.include?(mail.cache_id)
|
|
$logger.warn "Already distributed #{mail.message_id}"
|
|
return
|
|
end
|
|
|
|
$logger.info "SEND #{mail.from}\t -> #{mail.to}:\t#{mail.subject}"
|
|
smtp_raw = mail.to_smtp
|
|
$logger.debug smtp_raw.join("=====")
|
|
send_message_safe(*smtp_raw)
|
|
cache << mail.cache_id
|
|
rescue StandardError => e
|
|
$logger.warn "FAILED #{mail.from}\t -> #{mail.to}:\t#{mail.subject}"
|
|
$logger.debug e
|
|
end
|
|
|
|
# :nodoc:
|
|
private def reset_smtp_client!
|
|
@smtp = Net::SMTP.new(
|
|
ENV["SMTP_HOST"], ENV["SMTP_PORT"], tls: ENV["SMTP_TLS"] == "true",
|
|
).start(
|
|
user: ENV["SMTP_USER"],
|
|
secret: ENV["SMTP_PASSWORD"],
|
|
authtype: :login,
|
|
)
|
|
end
|
|
|
|
# :nodoc:
|
|
private def send_message_safe(*raw, max_tries: 3)
|
|
return $logger.error("send_message_safe reached max_tries_limit") if max_tries == 0
|
|
|
|
begin
|
|
@smtp.send_message(*raw)
|
|
rescue EOFError, Net::SMTPServerBusy => e
|
|
$logger.warn e.message
|
|
reset_smtp_client!
|
|
send_message_safe(*raw, max_tries: max_tries - 1)
|
|
rescue => e
|
|
$logger.error e.full_message
|
|
reset_smtp_client!
|
|
end
|
|
end
|
|
end
|