2010-11-08 16 views
19

Tengo una aplicación de Rails 3 usando Devise on Heroku. El problema es que estoy enviando correos electrónicos con Sendgrid y la entrega de correo electrónico es lenta, hace que la aplicación se cuelgue. Por lo tanto, estoy interesado en utilizar retrayed_job para poner en cola la entrega de correo electrónico en segundo plano, para que mi aplicación responda al usuario.Rails + Devise + delayed_job?

¿Cómo se puede utilizar Devise con delayed_job? ¿Alguna manera de configurar a Devise para usar el método demorado?

Respuesta

24

De Robert May: https://gist.github.com/659514

añadir esto a un archivo en el directorio de config/initializers:

module Devise 
    module Models 
    module Confirmable 
     handle_asynchronously :send_confirmation_instructions 
    end 

    module Recoverable 
     handle_asynchronously :send_reset_password_instructions 
    end 

    module Lockable 
     handle_asynchronously :send_unlock_instructions 
    end 
    end 
end 
+3

Agregue ese código en algún archivo.rb en el directorio 'config/initializers'. – Zabba

+0

Esto no funcionó para mí, quizás debido al hecho de que este método no es compatible si se usan los anuncios publicitarios de Rails 3 que probablemente se usen. Para obtener más información, consulte este enlace: https://github.com/collectiveidea/delayed_job y vaya a la sección de Rails 3 Mailers – sq1020

0

No estoy seguro de por qué necesita autenticar cualquiera de las tareas de retraso de trabajo. Simplemente haga que las acciones de controlador autenticadas Devise pongan en cola la entrega del correo electrónico a un método de biblioteca.

1

No estoy seguro de que Devise proporcione una forma fácil de hacer trasfondo de la entrega del correo electrónico. Sin embargo, hay formas de poder hacer eso con DelayedJoy. DelyedJob proporciona una función "handle_asynchronously" que, si se inyecta en DeviseMailer, puede garantizar que las entregas se realicen en segundo plano.

Pruebe esto en su config/application.rb

config.after_initialize do 
    ::DeviseMailer.handle_asynchronously :deliver_confirmation_instructions 
    # or 
    ::DeviseMailer.handle_asynchronously :deliver! 
end 

Usted tendrá que experimentar con eso. También podría tratar de heredar el DeviseMailer y configurarlo para que se entregue de forma asíncrona en un inicializador en config/initializer/devise_mailer_setup.rb o algo por el estilo.

-4

En general, he encontrado que es mejor evitar todos y cada uno de los administradores de tareas de segundo plano disponibles para Ruby and Rails, punto. Ellos apestan.

En su lugar, utilizo crontab que es un programa antiguo y muy bueno en su trabajo. Simplemente haga un script para hacer su trabajo sucio de vez en cuando y diga a crontab que lo ejecute en el momento correcto usando Rails Runner. Esto mantiene esas molestas tareas de larga ejecución fuera del tiempo de ejecución del resto de la aplicación de Rails, pero aún tiene acceso a la base de datos y a toda la pila de Rails si la quiere/necesita.

+5

estoy de acuerdo con la afirmación de que "cualquiera y todos los gestores de tareas de fondo-trabajo" chupar. Ruby Toolbox tiene una buena comparación sobre las opciones de colas para Ruby: http://ruby-toolbox.com/categories/queueing.html –

+2

Digamos que tiene una importación que pone nuevos productos o nueva información sobre productos en su aplicación. Ahora los nuevos productos necesitan generar algunos metadatos o no. ¿Vas a agregar una bandera a la tabla de productos para que tu cronjob pueda recoger esos artículos? ¿Con qué frecuencia ejecutas ese cronjob? ¿Cada diez minutos? ¿Qué sucede si una ejecución de ejecución tarda más de 10 minutos? Tendrás procesos en competencia en ejecución. Parece que todo lo que intentes hackear con crontab terminará siendo una implementación de una cola de trabajos pobre. Es mejor utilizar una cola dedicada que no arruine el esquema y los modelos de su base de datos. –

0

Uso el complemento delayed_job_mailer para lograr esto en las aplicaciones Rails 2. No estoy seguro si funciona con Rails 3.

6

encontré que ninguna de las anteriores trabajó para mí. Estoy usando Devise 2.0.4 y Rails 3.2.2 con retraso_job_activo_registro 0.3.2

La forma en que el diseño realmente habla de hacer algo como esto en los comentarios en el código es anular los métodos en la clase de Usuario. Por lo tanto, lo resolví como tal, y funciona perfectamente:

app/modelos/User.rb

def send_on_create_confirmation_instructions 
    Devise::Mailer.delay.confirmation_instructions(self) 
end 
def send_reset_password_instructions 
    Devise::Mailer.delay.reset_password_instructions(self) 
end 
def send_unlock_instructions 
    Devise::Mailer.delay.unlock_instructions(self) 
end 
+0

que anula estos métodos y daña otras funciones ... parecía funcionar, pero no configuró el reset_password_token en el modelo de usuario vea mi solución – fringd

+2

Si mira el código para send_reset_password_instructions en el último Devise: # Restablece el token de contraseña de restablecimiento y envía las instrucciones de restablecimiento de contraseña por correo electrónico def send_reset_password_instructions generate_reset_password_token! si should_generate_reset_token? self.devise_mailer.reset_password_instructions (self) .deliver end La sugerencia anterior da como resultado que el token de contraseña no se genere. – justingordon

3

esto es lo que funcionó para mí:

en app/modelos/usuario .RB

# after your devise declarations 
    handle_asynchronously :send_reset_password_instructions 
    handle_asynchronously :send_confirmation_instructions 
    handle_asynchronously :send_on_create_confirmation_instructions 

puede que no necesite todos ellos dependiendo de qué traman los módulos está incluyendo

+0

Funciona para mí con Rails 3.2.16 y Devise 3.2.3. También estoy usando devise_invitable 1.3.4, para lo cual agregué 'handle_asynchronously: deliver_invitation'. –

+0

Bueno, lo comento demasiado pronto. También tuve una anulación de 'send_reset_password_instructions' en mi modelo de Usuario. No funcionó bien cuando se ejecuta de forma asíncrona. El comentario de ZachBeta [1/6/2014 sobre Github] (https://github.com/scambra/devise_invitable/issues/58) me llevó a probar 'handle_asynchronously: send_devise_notification', que parece manejar todo, incluidas las invitaciones. El código fuente de Devise también tiene un [comentario extenso] (https://github.com/plataformatec/devise/blob/3d9dea39b2978e3168604ccda956fb6ec17c5e27/lib/devise/models/authenticatable.rb#L129-L174) sobre retrasar las colas. –

+0

cómo lograr esto para la gema "devise_token_auth"? – vipin8169

Cuestiones relacionadas