C'est ce que j'essaie d'accomplir. Je fais un appel à distance à un serveur pour l'information, et je veux bloquer pour attendre l'information. J'ai créé une fonction qui renvoie un différé tel que lorsque le RPC arrive avec la réponse, le différé est appelé. Ensuite, j'ai une fonction appelée à partir d'un fil qui va threads.blockingCallFromThread(reactor, deferredfunc, args)
.tordu: vérifier si un différé a déjà été appelé
Si quelque chose se passe mal - par exemple, le serveur tombe en panne - alors l'appel ne sera jamais débloqué. Je préférerais que le différé s'en aille avec une exception dans ces cas-là.
J'ai partiellement réussi. J'ai un différé, onConnectionLost
qui s'éteint lorsque la connexion est perdue. J'ai modifié ma fonction d'appel de blocage à:
deferred = deferredfunc(args)
self.onConnectionLost.addCallback(lambda _: deferred.errback(
failure.Failure(Exception("connection lost while getting run"))))
result = threads.blockingCallFromThread(
reactor, lambda _: deferred, None)
return result
Cela fonctionne très bien. Si le serveur tombe en panne, la connexion est perdue et le retour est déclenché. Cependant, si le serveur ne s'arrête pas et que tout se ferme correctement, onConnectionLost
est toujours déclenché et le rappel anonyme tente ici de déclencher la erreur, provoquant une exception AlreadyCalled
.
Existe-t-il un moyen simple de vérifier qu'un différé a déjà été déclenché? Je veux éviter de l'emballer dans un bloc try/except
, mais je peux toujours recourir à cela si c'est le seul moyen.
alors comment annuler le différé si je n'y ai pas accès, puisque je dois appeler 'blockingCallFromThread' pour être thread-safe? est le seul moyen de modifier cette fonction pour faire 'onConnectionLost.addCallback (lambda _: d.cancel())', où 'd' est le différé sur le point de revenir? cela signifierait que vous deviez passer l'onconnectionlost différé – Claudiu
Vous pouvez appeler 'blockingCallFromThread (self.something)', où 'self.something' reste sur' Deferred' pour vous. Le problème est d'appeler des API de réacteurs à partir du mauvais thread, pas du mauvais objet. – Glyph
Oui, j'ai fini par faire ça. Je ne pouvais pas obtenir .cancel à travailler, cependant - il semblait n'avoir aucun effet. Je viens de faire une fonction d'aide qui prend un différé et essaie de déclencher un errback. Y a-t-il des nuances à '.cancel' que je ne connais pas? à partir des docs, il semblait que si je ne faisais rien de spécial, '.cancel' devrait déclencher un errback de CancelledError s'il n'a pas été appelé, et ne rien faire autrement. – Claudiu