1

Ich habe eine Rails 4.2.5 App auf Heroku mit ActionMailer, SendGrid und DelayedJob/Resque für die Hintergrundverarbeitung. Ich habe ein seltsames Problem, das ich nicht auf localhost reproduzieren kann.ActionMailer + DelayedJob + Resque + SendGrid = nicht alle E-Mails gesendet

Ich sende eine Charge von E-Mails. Es werden keine Fehler gemeldet, daher scheinen die E-Mails erfolgreich gesendet zu werden. Ich überprüfe dann die Aktivität von SendGrid und sehe dort nur die Hälfte der E-Mails.

Ich habe nicht viel mit SendGrid oder ActionMailer gemacht, also bin ich nicht wirklich sicher, wie man das Problem debuggt oder es lokal reproduziert. Ich habe versucht, reproduzieren durch Erstellen von 100 contacts in meiner App und dann senden sie die gleiche Benachrichtigungsnachricht (genau wie in der App auf Produktion passieren würde), aber sie alle erfolgreich durchlaufen.

In development.rb und production.rb ich habe:

config.action_mailer.raise_delivery_errors = true 

In production.rb ich habe:

config.action_mailer.default_url_options = { :host => 'http://firmplay.com' } 
# config.action_mailer.delivery_method = :sendmail 
# config.action_mailer.sendmail_settings = { 
# :location => '/usr/sbin/sendmail', 
# :arguments => '-i -t' 
# } 

# config.action_mailer.perform_deliveries = true 
# config.action_mailer.raise_delivery_errors = true 

Ich bin mir nicht sicher, ob der kommentierten Code uncommented sein soll oder nicht.

In environment.rb ich habe:

ActionMailer::Base.smtp_settings = { 
    :address  => 'smtp.sendgrid.net', 
    :port   => '587', 
    :authentication => :plain, 
    :user_name  => ENV['SENDGRID_USERNAME'], 
    :password  => ENV['SENDGRID_PASSWORD'], 
    :domain   => 'heroku.com', 
    :enable_starttls_auto => true 
} 

In application.rb ich habe:

config.active_job.queue_adapter = :resque 

Ich bin nicht sicher, was ich falsch hier tun oder auch, wenn das Problem begann, obwohl ich vermute, Es hängt mit meinem letzten Upgrade von Rails 4.0 auf 4.2.5 zusammen. Ich fragte mich, ob die E-Mails irgendwo in DelayedJob/Resque versagten, also überprüfte ich die Resque-Logs und fand nichts Ungewöhnliches.

Aktualisierung mit Teillösung

ich es geschafft, obwohl einige Fortschritte bei der Bewältigung der Frage zu machen. Als ich in der Produktion getestet habe, wurde mir klar, dass mein Timeout nach 10 Sekunden abgelaufen ist, wenn ich meinen Web-Dyno dazu nutze, E-Mails als Hintergrundjobs einzureihen. Das ist das Limit für die App. Selbst nachdem der Web-Mitarbeiter das Zeitlimit überschritten hatte, wurde die E-Mail weiterhin in die Warteschlange gestellt, bis der Arbeitsspeicher erschöpft war (einige R14-Fehler in den Protokollen waren zu sehen).

Ich konnte nicht feststellen, warum nicht genügend Arbeitsspeicher zur Verfügung stand, wenn E-Mails in die Warteschlange gestellt wurden. Ich habe die E-Mails nicht im Speicher als Variable gespeichert, aber ich nehme an, es ist möglich, dass sie versehentlich gespeichert wurden, während ich meine Kontaktliste durchblätterte.

Was ich getan habe, ist, einen Hintergrundjob zu erstellen, dem ich die Kontaktliste übergeben konnte. Dann sendet der Hintergrundjob die E-Mails direkt aus. Als ich diesen Ansatz getestet habe, hat alles super geklappt und es ist gut skaliert. Im Wesentlichen ist mein Problem gelöst, obwohl ich immer noch herausfinden möchte, warum der Web-Dyno beim Einreihen von E-Mails nicht mehr genügend Speicher hatte, während der Hintergrund-Job-Mitarbeiter, der Resque betrieb, keine derartigen Probleme hatte.

Ich durchlief zunächst meine Kontakte mit .map, die das letzte in jeder Schleife im Speicher zurückgegebene Element speichert. Ich wechselte stattdessen zu .each und dachte, dass das das Problem lösen würde, aber es tat es nicht. In jedem Fall scheint das Problem darin zu bestehen, dass Ruby die E-Mails für die Lebensdauer des Controllers im Speicher speichert.

Antwort

1

Die Quelle Ihres Problems scheint in this Heroku article behandelt zu werden.

+1

Ich habe Ihre Antwort akzeptiert, weil es sich teilweise um ein Timeout-Problem handelte. Es war auch ein Speicherproblem, da der Hintergrundjob die Vorlage für jede E-Mail rendert und im Speicher speichert, bis der Job abgeschlossen ist. Auch wenn sie jetzt über HTTP an die SendGrid-API gesendet werden, verbrauchen diese Vorlagen nach einigen hundert Nachrichten den gesamten Speicher auf dem Prüfstand. Ich werde das Templating wahrscheinlich zu SendGrid verschieben, um es vollständig zu lösen, aber im Moment scheint meine Lösung für meine Bedürfnisse ausreichend zu skalieren. – ACIDSTEALTH