Strict Standards: Non-static method themeGluedIdeas_Subtle::initOptions() should not be called statically in /home/riopro/www/blog.riopro.com.br/wp-content/themes/gluedideas_subtle/header.php on line 19
Riopro Blog - » Envio de e-mails assincronamente com Backgroundjob (Bj)

Envio de e-mails assincronamente com Backgroundjob (Bj)



Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Durante o desenvolvimento do Zest, nos deparamos com uma situação padrão: enviar e-mails assincronamente. Já havíamos usado no VoteBolsa o ARMailer e ele vem funcionando bem. Dois motivos nos fizeram pensar em fazer algo diferente desta vez:

1) No Zest, já usávamos o Backgroundjob (Bj) para os outros processos assíncronos;

2) Usar o ARMailer implica, principalmente, em termos que configurar uma tarefa no cron do servidor de aplicações para efetivamente enviar os emails. O cron é excelente, mas ficar dependendo de configurar o cron em cada novo servidor é algo que estamos tentando evitar.

Por isso, optamos por criar um job para o Bj que tratasse de chamar o enviador de e-mails corretamente (classe mailer que herda de ActionMailer::Base). O nosso job ficou assim:

Criando o Job:

def self.create(args={})
raise RailsJobArgumentError, "arguments must be a Hash" unless args.is_a?(Hash)
raise RailsJobArgumentError, "hash should contain a symbol key called mailer_class" unless args.has_key?(:mailer_class)
raise RailsJobArgumentError, "mailer_class should ends with _mailer" unless args[:mailer_class] =~ /(_mailer)$/
raise RailsJobArgumentError, "hash should contain a symbol key called method" unless args.has_key?(:method)
Bj.submit("./script/runner '#{self}.run(#{args.inspect})'")
end

Para executar o Job, fazemos:

def self.execute(args)
params = {}
mailer_class = args.delete(:mailer_class)
deliver_method = args.delete(:method)
raise RailsJobArgumentError, ":mailer_class not specified" unless mailer_class
raise RailsJobArgumentError, ":method not specified" unless deliver_method
args.each do |key, value|
unless (key.to_s =~ /_id\z/).blank?
obj = key.to_s.gsub("_id","").camelize.constantize.find(value)
params.store obj.class.to_s.underscore.to_sym, obj
else
params.store key.to_sym, value
end
end
mailer_obj = mailer_class.camelize.constantize
# check if mailer_class constantizes do send email
raise RailsJobArgumentError, "mailer_class should have ActionMailer::Base as it superclass" unless mailer_obj.superclass.to_s == "ActionMailer::Base"
mailer_obj.send("deliver_#{ deliver_method }", params)
end

Para usar esse Job, vamos supor que queremos enviar um email para o usuário que acaba de se cadastrar. Então, criaríamos um observer como:

class UserObserver < ActiveRecord::Observer
after_create(user)
SendMailJob.create(
:mailer_class => "user_mailer",
:method => "activation",
:user_id => user.id
)
end
end

Uma  diferença importante é que o ArMailer o email é apagado do banco de dados tão logo é enviado, enquanto no Bj o email permanece na tarefas já executadas (veja na tabela bj_job_archive o campo stdout). Portanto, não armazene dados sensíveis (como senha) em seu job.

Informações e Links

Junte-se comentando, lendo o que os outros dizem ou colocando um link a partir do seu blog.


Outros Artigos

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
KillBill, o plugin matador para gerar boletos

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
Rails e um bug chamado IE6

Comente

Tire um tempo para comentar e nos dizer o que você acha. Alguns códigos HTML são permitidos para formatação.

Comentários dos Leitores


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Deem uma olhada no backgroundrb (bdrb). Mto bacana, tenho usado com mto sucesso.
Ah, tem o starling tb!! BJ meio defasa…


Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

Na verdade, essa solução pode ser facilmente modificada para o starling. Para falar a verdade, no momento estamos usando o Workling para o Zist (o sistema de invoices). O que ele fornece é uma camada de abstração para usar com o Starling ou o BJ. Mas o BJ cumpre muito bem sua função. A limitação dele é apenas 1 processo por máquina. Mas para nos está perfeito por enquanto (nada no cron, processos assíncronos iniciando o consumo imediatamente, …).