J'espère obtenir des éclaircissements sur la meilleure façon de traiter le "premier" différé, c'est-à-dire non seulement ajouter des rappels et des erreurs aux méthodes Twisted existantes qui renvoient un différé, mais la meilleure façon de créer ces originaux différés.Python Twisted différé: clarification nécessaire
Comme exemple concret, voici 2 variantes de la même méthode: il compte seulement le nombre de lignes dans certains fichiers texte assez grand, et est utilisé comme point de départ pour une chaîne de deferreds.
Procédé 1: Celui-ci ne se sent pas très bien, car le différé est déclenché directement par la méthode reactor.callLater.
def get_line_count(self):
deferred = defer.Deferred()
def count_lines(result):
try:
print_file = file(self.print_file_path, "r")
self.line_count = sum(1 for line in print_file)
print_file.close()
return self.line_count
except Exception as inst:
raise InvalidFile()
deferred.addCallback(count_lines)
reactor.callLater(1, deferred.callback, None)
return deferred
Méthode 2: légèrement mieux, que le report est en fait tiré lorsque le résultat est disponible
def get_line_count(self):
deferred = defer.Deferred()
def count_lines():
try:
print_file = file(self.print_file_path, "r")
self.line_count = sum(1 for line in print_file)
print_file.close()
deferred.callback(self.line_count)
except Exception as inst:
deferred.errback(InvalidFile())
reactor.callLater(1, count_lines)
return deferred
Note: Vous pouvez également remarquer que ces deux sont méthodes réellement synchrones, et potentiellement bloquantes, (et je pourrais peut-être utiliser "MaybeDeferred"?). Mais bon, c'est en fait l'un des aspects qui me déroute.
Pour Méthode 2, si la méthode count_lines est très lent (en comptant les lignes dans certains gros fichiers, etc.), sera potentiellement « bloquer » l'ensemble app Twisted? Je lis beaucoup de documentation sur la façon dont les callbacks et les erreurs et le réacteur se comportent ensemble (les callbacks doivent être exécutés rapidement, ou renvoyés différemment, etc.), mais dans ce cas, je ne vois pas et j'apprécierais vraiment/etc exemples
y at-il des articles/ claires explications qui traitent de la meilleure approche à la création de ces « premiers » deferreds? J'ai lu these excellent articles, et ils ont beaucoup aidé avec une compréhension de base, mais je me sens toujours comme si je manquais un morceau.
Pour blocage de code, serait-ce ce cas typicall pour DeferToThread ou reactor.spawnprocess? J'ai lu beaucoup de questions comme this one et this article, mais je ne suis toujours pas sûr à 100% sur la façon de traiter avec le code potentiellement bloquer, pour la plupart lorsqu'ils traitent avec le fichier i/o
Désolé si tout cela semble trop basique, mais je veux vraiment avoir l'habitude d'utiliser Twisted de manière plus approfondie. (Il a été un outil très puissant pour tous les aspects plus orientés réseau). Merci pour votre temps!
Merci beaucoup pour la réponse rapide et complète, Martin! 1. et 2. D'accord, l'approche Thread/Threadpool * a du sens dans ce cas. –
3. J'ai tendance à me méfier des threads en Python à cause du GIL, mais normalement ** devrait ** être capable de gérer 3-4 threads utilisant les méthodes 'count_lines' à peu près en même temps sans gâcher l'événement Twisted loop (la méthode est utilisée dans de petites "tâches" qui envoient ensuite les données depuis les fichiers vers les périphériques via la série) –
Merci pour l'info sur le module select, il semble être "lié" aux différents types de réacteurs dans Twisted. Je vais regarder dans plus de détails! Pour une utilisation pratique, malheureusement, il ne supporte que les sockets sur les plates-formes Windows (d'où les limitations plutôt étranges que j'avais lors de l'utilisation de support série torsadée sur Windows). –