2015-09-16 35 views
11

Wspólny wzór na współpracę z ActionJob w Rails jest utworzenie zadania z perform() metody, która jest wywoływana asynchronicznie poprzez perform_now lub perform_laterRóżnica między Akcja Job/Mailer na `deliver_now` i` deliver_later`

w specjalnym W przypadku Mailers można bezpośrednio zadzwonić pod numer deliver_now lub deliver_later, ponieważ ActionJob jest dobrze zintegrowany z ActionMailer.

rails documentation ma następujące uwagi -

# If you want to send the email now use #deliver_now 
UserMailer.welcome(@user).deliver_now 

# If you want to send the email through Active Job use #deliver_later 
UserMailer.welcome(@user).deliver_later 

Brzmienie sprawia, że ​​wydaje się deliver_now będzie nie użycie ActiveJob wysłać pocztę. Czy to prawda, a jeśli tak, jaka jest prawdziwa różnica między deliver_now i deliver_later? Czy ktoś nie jest asynchroniczny?

Czy ta sama różnica dotyczy również perform_now i perform_later?

Dzięki!

Odpowiedz

13

Tak jak mówisz w swoim pytaniu, deliver_now nie używa ActiveJob.

Zasadniczo deliver_later jest asynchroniczny. Gdy używasz tej metody, wiadomość e-mail nie jest wysyłana w tej chwili, ale jest wysyłana w kolejce zadania. Jeśli zadanie nie działa, wiadomość e-mail nie zostanie wysłana. deliver_now wyśle ​​wiadomość e-mail w dowolnym momencie, bez względu na stan pracy. Here można zobaczyć dokumentację dla metod deliver.

Zgodnie z drugim pytaniem, perform_now przetworzy zadanie natychmiast, bez wysyłania do kolejki. perform_later jednak doda zadanie do kolejki, a gdy tylko kolejka zadania będzie wolna, wykona zadanie. Here można zobaczyć dokumentację metod perform.

+0

co, jeśli połączenie przeglądarki jest zamknięte?Nadal będzie działać deliver_later? – gates

+2

@ gates 'dostawa_later' jest zarządzany po stronie serwera, więc nie ma znaczenia, czy połączenie przeglądarki jest zamknięte. Gdy zadanie zostanie przekazane do kolejki, zostanie wysłane (chyba że zabijesz proces pracy). –

+0

Dzięki Daniel .. – gates

2

Oprócz tego, co napisał Daniel Batalla, jest jeszcze jedna obserwacja, którą zrobiłem: deliver_later wydaje się wykonywać leniwą ocenę, podczas gdy deliver_now nie.

Mam modelu ActiveRecord z dodatkowym atrybutem reset_token, które nie są przechowywane w bazie danych (to jest od railstutorial.org Michael Hartl za; model przechowuje zaszyfrowaną wersję tokena w kolumnie reset_digest).

Podczas wykonywania deliver_now, uzyskanie dostępu do atrybutu reset_token w widoku programu pocztowego powoduje, że token resetowania jest zgodny z oczekiwaniami. Jednak podczas wykonywania deliver_later, @model.reset_token jest zawsze nil. Wygląda na to, że deliver_later aktualizuje model danymi bazy danych, a ponieważ reset_token jest dodatkowym atrybutem, który nie jest wspierany przez bazę danych, w tym miejscu będzie to nil. (Dokumentacja kodu jest zbyt głęboko zagnieżdżona, aby móc ją zweryfikować w źródle.)

Michael używa deliver_now w samouczku. Nie wiem, czy robi to, aby uniknąć leniwej oceny. Ale zajęło mi trochę czasu, zanim zdałem sobie sprawę, że muszę zmienić deliver_later na deliver_now, aby moje testy minęły.

+0

Ponieważ 'dostaw_later' jest asynchroniczny, wymagałoby przeładowania obiektu. Jak w każdym przypadku asynchronicznego zadania. Ponieważ jest to wymagane, aby wprowadzić nowe zmiany, o ile takie istnieją, wprowadzone do pracy. – Monika

+1

Dziękuję, @bovender. Właśnie miałem ten sam problem. W moim modelu istnieje kilka metod obliczania cen całkowitych/brutto i jeśli uruchomię program pocztowy w następujący sposób: 'Mailer.payment_email (model, calcul_price) .deliver_later',' price' ma zawsze wartość 'nil'. Użycie 'delivery_now' pomaga, ale niszczy wszystkie korzyści asynchronicznego dostarczania. Aby go pokonać zastąpiłem 'calcul_price' przez' calculate_price.to_f', wymusza to ocenę metody. W innych przypadkach może to być 'to_i',' to_s', etc, w zależności od typu danych zwracanego przez metodę. – ololobus