2015-02-28 12 views
6

Ho un'app per i binari in cui ho una funzione che inviano alcune e-mail. Mi piacerebbe farlo asynchronously e ho pensato che il metodo deliver_later lo farebbe. Attualmente ho qualche ritardo da quando l'utente fa clic su submit fino a quando non viene inviato il modulo, il che comporta un'esperienza utente negativa (è una forma piuttosto semplice). La mia implementazione è la seguente:Rails 4 - Mailer deliver_later non sta facendo quello che mi aspetto, blocca l'interfaccia utente

def create 

    respond_to do |format| 
    if @competition.save 
     [...] 
     send_notification_to_team_members 
    end 
end 

def send_notification_to_team_members 
    @team.members.each do |member| 
    unless member.user.eql?(current_user) 
     Mailer.deliver_new_competition_notification(member.user, @competition).deliver_later 
    end 
    end 
end 

Attualmente occorrono ~ 4 secondi per completare l'azione. Ho anche provato:

Mailer.deliver_new_competition_notification(member.user, @competition).deliver_later(wait: 1.minute) 

poi ci vuole anche di più - Direi ~ 1 minuto.

Quindi, sto usando erroneamente deliver_later oppure il metodo non sta facendo quello che mi aspetto. In tal caso, c'è un altro metodo che posso usare per migliorare le mie prestazioni?

+0

Quale backend di activejob stai utilizzando? –

+0

È necessario inviare la posta elettronica in modo asincrono.Se si utilizza 4.2, è possibile utilizzare ActiveJob o, in caso contrario, utilizzare soluzioni come Sidekiq o Rescue. –

+0

FYI: [Here] (https: //blog.engineyard.com/2014/getting-started-with-active-job) è un buon articolo sull'utilizzo di ActiveJob per l'invio di e-mail. –

risposta

14

deliver_later utilizza ActiveJob per fornire l'esecuzione asincrona.

Tuttavia ActiveJob non fornisce l'asincronicità stessa - è un livello API unificante che può essere soddisfatto da molti backend. Quello predefinito esegue semplicemente tutto in linea e non è asincrono.

Per ottenere un utilizzo asincrono è necessario selezionare un backend asincrono. È possibile configurare il backend in config dell'applicazione

config.active_job.queue_adapter = ... 

Nella maggior parte degli adattatori generale richiedono un corrispondente gemma (ad esempio delayed_job, sidekiq, sucker_punch) che può avere le proprie dipendenze troppo (ad esempio sidekiq richiede l'utilizzo di Redis.

+0

Grazie! Ho deciso di installare 'delayed_job', con:' gem 'delayed_job_active_record'', e ho seguito il processo di installazione qui: https://github.com/collectiveidea/delayed_job_active_record. In 'application.rb' ho aggiunto:' config.active_job.queue_adapter =: delayed_job'. E lo uso in questo modo: 'Mailer.deliver_new_competition_notification (member.user, @competition) .deliver_later!'. Non ricevo errori, ma le e-mail non vengono consegnate - su 'localhost: 3000'. Ho perso qualcosa? – Anders

+0

@Anders è necessario avviare uno o più lavoratori in differita –

+0

Grazie, ho deciso di andare con 'sidekiq' invece. Ho pensato che sembrava più facile da configurare. Ma mi sono imbattuto in altri problemi, ho posto una nuova domanda qui: http://stackoverflow.com/questions/28796293/rails-4-2-sidekiq-not-sending-emails-in-development – Anders

Problemi correlati