2015-12-01 1 views
1

Désolé d'abord le mur de texte. J'ai du mal à comprendre la programmation Twisted et asynchrone en général. J'utilise Python 2.7 avec Twisted 15.4.0.Comprendre la programmation Twisted et asynchrone. Pourquoi un code fonctionne-t-il et un autre ne l'est pas?

J'ai essayé this example pour downloadPage() et cela fonctionne parfaitement.

J'ai bricolé un peu avec, en changeant les rappels de lambdas aux fonctions appropriées. Ça a marché. J'ai également essayé de supprimer l'instruction reactor.stop() à la fois du callback et du errback et son seul effet est que le script ne s'arrête pas après le téléchargement. Cela rend sence puisque la boucle d'événement est toujours en cours d'exécution.

J'ai également essayé de donner une URL cassée.

Si je n'ai qu'un appel à downloadPage(), le programme bloque. Il ne déclenche pas le ratback.

Si j'ai deux appels, l'un avec une URL brisée et l'autre avec une URL correcte, il s'exécute, se termine et déclenche le rappel (je suppose pour le bon) et se termine.

Ma première question est: Pourquoi cela se produit-il? Pourquoi le errback n'est-il pas déclenché pour une URL brisée? Une URL rompue ne devrait-elle pas générer une erreur?


J'ai un code distinct, qui ressemble à ceci:

def receive_some_data(): 
    # Do some non twisted stuff - The script runs and passes these lines 
    While True: 
     try: 
      # Do some other non twisted stuff 
      print "1" 
      downloadPage("http//:www.google.com", "foo").addCallbacks(
       lambda value:(println('Good'),reactor.stop()), 
       lambda error:(println("an error occurred",error),reactor.stop())) 
      print "2" 
     except Exceptions as e: 
      print str(e) 

def main(): 
    reactor.callWhenRunning(receive_some_data) 
    reactor.run() 

Ce code ne fonctionne pas. Il imprime "1", il imprime "2", mais il n'y a pas de callback ou d'appel errback. La page n'est pas non plus téléchargée sur "foo".

Ma deuxième question est: Pourquoi ce code ne fonctionne-t-il pas? Est-ce à cause de la boucle While? Si oui, comment la boucle while affecte-t-elle la chaîne de rappel et sa chaîne de rappel?


Edit 1: Je change le "Bien vrai" à "While condition" qui se termine après 3 itérations. Maintenant, les fichiers sont téléchargés et les rappels sont appelés. Pourquoi la boucle infinie interfère-t-elle avec le téléchargement?

En outre, mes lignes "# Faire d'autres choses non tordues" à l'intérieur de la boucle While effectue une lecture à partir d'un tuyau. C'est là que je reçois mes urls.

Quelle est la meilleure façon de lire continuellement mes URL et de programmer un rappel pour le moment où le téléchargement est terminé?


Edit 2: j'ai changé le code à quelque chose comme ceci:

def receive_some_data(): 
    # Do some non twisted stuff 
    if condition: 
     # Request more urls 
     downloadPage(url,file).addCallbacks(success,fail) 
    else: 
     # Ask sender not to send urls atm 

def main(): 
    reactor.callWhenRunning(receive_some_data) 
    reactor.run() 

J'ai changé la structure du code à cette callWhenRunning de pensée() va continuer à appeler la fonction receive_some_data (comme un boucle infinie). Ce n'est pas le cas. Comment faire pour que la boucle d'événements continue à appeler cette fonction?


Edit 3: Réussi à obtenir ce travail un peu. J'ai découvert la méthode Looping Call. J'appelle mon code de Modifier 2 toutes les x secondes avec appel en boucle. Ça marche. Y a-t-il d'autres méthodes?


Merci!

+0

Qu'est-ce qui est cassé sur vos URL brisées? Renvoie-t-il une erreur ou expire-t-il après plusieurs secondes? –

+0

Par URL cassée, je veux dire quelque chose comme: "httwgoogle.c" (je viens de supprimer une partie de l'URL). Si je n'ai qu'un seul appel de downloadPage comme downloadPage (brokenURL, fichier) .addCallbacks (succès, échec), il se bloque, pas de timeout, pas d'appel errback, rien. Si j'ai 2 appels, un avec un URL cassé et un autre avec une bonne URL (http://www.google.com) le programme se termine avec un seul callback réussi et aucun errback. – RandomGuyqwert

Répondre

2

Fondamentalement, ce que vous faites lorsque vous appelez downloadPage plusieurs fois est de commencer le téléchargement multiple en parallèle. Le premier à finir sera alors le premier à l'appeler callback ou errorback et cela arrêtera le réacteur et avec lui tous les autres téléchargements. Par conséquent, lorsque vous modifiez l'URL d'un appel vers un hôte incorrect, la demande expire. D'ici là, l'autre (bon) téléchargement aura fini, et arrêter le réacteur. C'est pourquoi votre code fonctionne avec une bonne URL seulement.

Votre while dans l'autre exemple créera un téléchargement après l'autre et ne reviendra pas de la fonction receive_some_data. Mais il doit revenir afin de permettre l'exécution des appels/erreurs des téléchargements. Twisted ne fait qu'un appel à la fois.

+0

Merci pour la réponse et l'explication! – RandomGuyqwert