2010-11-08 21 views
19

Possiedo un'applicazione Rails 3 che utilizza Devise su Heroku. Il problema è che sto inviando e-mail con Sendgrid e la consegna delle e-mail è lenta, rende l'app bloccata. Quindi sono interessato all'utilizzo di delayed_job per accodare la consegna delle email in background, quindi la mia app è reattiva all'utente.Rails + Devise + delayed_job?

In che modo è possibile utilizzare Devise con delayed_job? Qualche modo per configurare Devise per usare delayed_job?

risposta

24

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

Aggiungi ad un file nella directory 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

Aggiungi quel codice in qualche file.rb nella directory 'config/initializers'. – Zabba

+0

Questo non ha funzionato per me forse a causa del fatto che questo metodo non è supportato se si usano probabilmente i mailer di Rails 3 che escogitano. Vedi questo link per maggiori informazioni: https://github.com/collectiveidea/delayed_job e vai alla sezione Rails 3 Mailers – sq1020

0

Non sono sicuro del motivo per cui è necessario autenticare uno qualsiasi dei task delayed_job. Basta fare in modo che le azioni del controllore autenticate Devise mettano in coda il recapito della posta elettronica a un metodo di libreria.

1

Non sono sicuro che Devise offra un modo semplice per eseguire lo sfondo della consegna delle e-mail. Tuttavia ci sono modi per essere in grado di farlo con DelayedJoy. DelyedJob fornisce una funzione "handle_asynchronously" che, se inserita nel DeviseMailer, può garantire che le consegne avvengano in background.

Prova questo nella configurazione/application.rb

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

Sarà necessario sperimentare con questo. Si potrebbe anche provare ad ereditare DeviseMailer e impostarlo in modo asincrono in un inizializzatore in config/initializer/devise_mailer_setup.rb o qualcosa del genere.

-4

In genere ho trovato il modo migliore per evitare tutti i task manager di background-job disponibili per Ruby e Rails, punto. Fanno schifo.

Invece, io uso crontab che è un programma antico e molto bravo nel suo lavoro. Basta fare uno script per fare il tuo lavoro sporco ogni tanto e dire a crontab di eseguirlo al momento giusto usando il runner dei binari. Ciò mantiene quelle fastidiose attività di lunga durata al di fuori del tempo di esecuzione del resto dell'applicazione Rails, ma si ha comunque accesso al database e all'intero stack di Rails se lo si desidera/ha bisogno.

+5

Non sono d'accordo con l'affermazione che "ogni e qualsiasi background-job task manager" succhiare. Ruby Toolbox ha un buon confronto sulle opzioni di accodamento per Ruby: http://ruby-toolbox.com/categories/queueing.html –

+2

Quindi, diciamo che hai un'importazione che inserisce nuovi prodotti o nuove informazioni sui prodotti nell'app. Ora i nuovi prodotti devono generare alcuni metadati o cosa no. Stai per aggiungere un flag alla tabella dei prodotti in modo che il tuo cronjob possa captare quegli articoli? Quanto spesso esegui quel cronjob? Ogni dieci minuti? Cosa succede se una esecuzione di esecuzione richiede più di 10 minuti. Avrai processi concorrenti in esecuzione. Sembra più che mai quello che provi ad hackerare con crontab finirà per essere un'implementazione di una coda di lavoro. Meglio dell'uso di una coda dedicata che non incrinerà lo schema ei modelli del tuo database. –

0

Io uso il plug-in delayed_job_mailer per realizzare questo nelle app Rails 2. Non sono sicuro se funziona con Rails 3.

6

ho scoperto che nessuna delle precedenti ha lavorato per me. Sto usando Devise 2.0.4 e Rails 3.2.2 con delayed_job_active_record 0.3.2

Il modo in cui devise parla effettivamente di fare qualcosa di simile nei commenti nel codice è quello di sovrascrivere i metodi nella classe User. Così, ho risolto in questo modo, e funziona perfettamente:

app/modelli/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

superando questi metodi clobbers altre funzionalità ... sembrava funzionare, ma non ha impostato il reset_password_token su il modello utente vede la mia soluzione – fringd

+2

Se si guarda il codice per send_reset_password_instructions nell'ultima versione: # Reimposta il token della password e invia le istruzioni per la reimpostazione della password via e-mail def send_reset_password_instructions generate_reset_password_token! if should_generate_reset_token? self.devise_mailer.reset_password_instructions (self) .deliver end Il suggerimento sopra comporta che il token della password non venga generato. – justingordon

3

questa è la cosa che ha funzionato per me:

in app/modelli/utente .RB

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

potrebbe non essere necessario tutti loro a seconda di quale escogitare moduli si includono

+0

Funziona per me con Rails 3.2.16 e Devise 3.2.3. Sto anche usando devise_invitable 1.3.4, per cui ho aggiunto 'handle_asynchronously: deliver_invitation'. –

+0

Bene, ho commentato troppo presto. Ho anche avuto un override di "send_reset_password_instructions" nel mio modello User. Non ha funzionato correttamente quando eseguito in modo asincrono. Il commento [1/6/2014 su Github] di ZachBeta (https://github.com/scambra/devise_invitable/issues/58) mi ha portato a provare 'handle_asynchronously: send_devise_notification' che sembra gestire tutto compreso gli inviti. Il codice sorgente di Devise contiene anche un [lungo commento] (https://github.com/plataformatec/devise/blob/3d9dea39b2978e3168604ccda956fb6ec17c5e27/lib/devise/models/authenticatable.rb#L129-L174) sul ritardo della messa in coda. –

+0

come realizzare questo per gemma "devise_token_auth"? – vipin8169

0

Per delayed_job_active_record con Devise, utilizzare solo quanto segue. (Aggiungerlo al user.rb model)

handle_asynchronously :send_devise_notification, :queue => 'devise' 
Problemi correlati