3 votes

Sidekiq ne trouve pas d'objet dans le travailleur

Lorsque je crée un nouveau User dans mon application, je lance un after_create qui déclenche ensuite de manière asynchrone un travailleur Sidekiq.

Ce travailleur ...

def perform user_id
    @user = ::User.find user_id
    # ...
end

... renvoie toujours l'erreur suivante :

ActiveRecord::RecordNotFound : Impossible de trouver l'utilisateur avec 'id'=315928979197048617

Mais en utilisant la console rails pour vérifier si l'identifiant de l'utilisateur est trouvable :

User.find(315928979197048617)
=> #<User id: 315928979197048617>

Cela se produit-il parce que la création du nouvel utilisateur prend un certain temps et que le travailleur a déjà exécuté la méthode lorsqu'il a terminé ? Si oui, comment puis-je corriger ce comportement ?

6voto

philnash Points 8783

Vous avez tout à fait raison, le after_create dans Active Record s'exécute en fait avant que l'enregistrement ne soit entièrement validé dans la base de données. Cela provoque une condition de course avec votre script et la base de données, dont les résultats sont les suivants ActiveRecord::RecordNotFound des erreurs dans le travailleur (bien que si la base de données gagne la course, tout semble se passer comme prévu).

Pour s'assurer que votre utilisateur a été sauvegardé dans la base de données avant que votre travailleur n'essaie d'y accéder, vous devriez utiliser l'option after_commit callback. Puisque vous n'effectuez cette opération qu'à la création, vous avez besoin de after_commit on: :create .

Cela pose un dernier problème, after_commit ne semblent jamais s'exécuter lors des tests. Cela est dû au fait que Rails intègre les tests dans des transactions et que la transaction de test n'est jamais validée, de sorte que le rappel ne s'exécute pas. Cet article de blog contient un bon article sur l'utilisation after_commit et recommande le test_after_commit pierre précieuse pour surmonter ce problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X