Le modèle courant d'interfaçage avec ActionJob
dans Rails consiste à configurer un Job avec une méthode perform()
qui est appelée de manière asynchrone via perform_now
ou perform_later
Dans le cas particulier des Mailers, vous pouvez appeler directement deliver_now
Ou deliver_later
Car ActionJob
est bien intégré à ActionMailer
.
Le documentation Rails a les commentaires suivants -
# 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
Le libellé donne l'impression que deliver_now
n'utilisera pas ActiveJob
pour envoyer le courrier. Est-ce exact, et si oui, quelle est la vraie différence entre deliver_now
Et deliver_later
? N'est-on pas asynchrone?
De même, la même différence s'applique-t-elle à perform_now
Et perform_later
?
Merci!
Comme vous le dites dans votre question, deliver_now
n'utilise pas ActiveJob
.
Fondamentalement, deliver_later
est asynchrone. Lorsque vous utilisez cette méthode, l'e-mail n'est pas envoyé pour le moment, mais est plutôt poussé dans la file d'attente d'un travail. Si le travail n'est pas en cours d'exécution, l'e-mail ne sera pas envoyé. deliver_now
enverra l'e-mail pour le moment, quel que soit l'état de la tâche. Ici vous pouvez voir la documentation des méthodes deliver
.
Selon votre deuxième question, perform_now
traitera le travail immédiatement sans l'envoyer à la file d'attente. perform_later
, cependant, ajoutera le travail à la file d'attente, et dès que la file d'attente du travail sera libre, exécutera le travail. Ici vous pouvez voir la documentation des méthodes perform
.
En plus de ce que Daniel Batalla a écrit, voici une autre observation que j'ai faite: deliver_later
semble effectuer une évaluation paresseuse, tandis que deliver_now
ne fait pas.
J'ai un modèle ActiveRecord avec un attribut supplémentaire reset_token
qui n'est pas stocké dans la base de données (ceci provient de railstutorial.org de Michael Hartl; le modèle stocke une version hachée du jeton dans le reset_digest
colonne).
Lors de l'exécution de deliver_now
, accéder à @model
's reset_token
l'attribut à l'intérieur de la vue de l'expéditeur produit le jeton de réinitialisation comme prévu. Cependant, lors de l'exécution de deliver_later
, @model.reset_token
est toujours nil
. Il semble que deliver_later
met à jour le modèle avec les données de la base de données et parce que reset_token
est un attribut supplémentaire qui n'est pas soutenu par la base de données, il sera nil
à ce stade. (La documentation du code est trop profondément imbriquée pour que je puisse vérifier cela dans la source.)
Michael utilise deliver_now
dans le didacticiel. Je ne sais pas s'il le fait pour éviter une évaluation paresseuse. Mais il m'a fallu un certain temps pour réaliser que je devais juste changer deliver_later
à deliver_now
pour réussir mes tests.