Skip to content

Instantly share code, notes, and snippets.

@anomit
Last active August 29, 2015 13:59
Show Gist options
  • Select an option

  • Save anomit/10863445 to your computer and use it in GitHub Desktop.

Select an option

Save anomit/10863445 to your computer and use it in GitHub Desktop.
Hacking Rails mail delivery for an async solution with Sidekiq, Redis, Local Postfix SMTP server
class QueueDeliveryMailer < ActionMailer::Base
self.delivery_method = Rails.application.config.mail_queue_outbound_delivery_method #remember this from development.rb
layout nil
def rebuild_mail(id)
mail({:from => $redis.get("mail:#{id}:sender_address"),
:to => $redis.get("mail:#{id}:recipient_address"),
:reply_to => $redis.get("mail:#{id}:reply_to_address"),
:mime_version => $redis.get("mail:#{id}:mime_version"),
:content_type => $redis.get("mail:#{id}:content_type"),
:content_transfer_encoding => $redis.get("mail:#{id}:content_transfer_encoding"),
:subject => $redis.get("mail:#{id}:subject")
}) do |format|
format.text {render :text => $redis.get("mail:#{id}:body")}
end
end
end
class MailWorker
include Sidekiq::Worker
def perform(id)
m = QueueDeliveryMailer.rebuild_mail(id) #this is in mailers/queue_deliver_mailer.rb
puts m.delivery_method
puts m.delivery_method.settings
puts m.deliver
end
end
config.mail_queue_outbound_delivery_method = :smtp #to be used in a later mailer class used by Sidekiq worker
ActionMailer::Base.add_delivery_method :queued, MailDebug::QueuedDelivery #now all mail is routed through this
ActionMailer::Base.delivery_method = :queued
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.smtp_settings = {
address: '127.0.0.1',
port: 25,
domain: 'app.com',
}
verbose: true
:concurrency: 25
:queues:
- [mailer, 5]
- [default, 5]
module MailDebug
class QueuedDelivery
def initialize(values={})
#nothing
end
def deliver!(mail)
queue_id = Time.now.to_s + ($redis.incr "next.mail_worker.id").to_s
#Object schema mail:id:mail_field
#push all mail headers in redis queue
$redis.set "mail:#{queue_id}:mime_version", mail.mime_version
$redis.set "mail:#{queue_id}:content_type", mail.content_type
$redis.set "mail:#{queue_id}:content_transfer_encoding", mail.content_transfer_encoding
$redis.set "mail:#{queue_id}:subject", mail.subject
$redis.set "mail:#{queue_id}:body", mail.body
$redis.set "mail:#{queue_id}:recipient_address", mail.to.first
$redis.set "mail:#{queue_id}:sender_address", mail.from.first
$redis.set "mail:#{queue_id}:reply_to_address", mail.reply_to ? mail.reply_to.first : nil
MailWorker.perform_async(queue_id) #this is the sidekiq worker
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment