Il y a très longtemps, j'ai écrit une web-spider que j'ai multithreadée pour permettre aux requêtes simultanées de se produire en même temps. C'était dans ma jeunesse Python, dans les jours avant que je connaissais le GIL et les malheurs associés qu'il crée pour le code multithread (IE, la plupart du temps, les choses finissent par être sérialisées!) ...
Je voudrais retravailler ce code pour le rendre plus robuste et mieux performer. Il y a essentiellement deux façons de le faire: je pourrais utiliser le nouveau module de multitraitement dans 2.6+ ou je pourrais opter pour un modèle basé sur un réacteur / événement d'une certaine sorte. Je préfère faire plus tard, car il est beaucoup plus simple et moins sujet aux erreurs.
La question porte donc sur le cadre le mieux adapté à mes besoins. Voici une liste des options que je connais jusqu'à présent:
- Twisted : Le grand-père des frameworks de réacteurs Python: semble complexe et un peu gonflé cependant. Courbe d'apprentissage abrupte pour une petite tâche.
- Eventlet : Des gars du lindenlab . Cadre basé sur Greenlet et orienté vers ce type de tâches. J'ai cependant regardé le code et ce n'est pas trop joli: non compatible pep8, parsemé d'impressions (pourquoi les gens font ça dans un framework!?), L'API semble un peu incohérente.
- PyEv : Immature, il ne semble pas que quiconque l'utilise actuellement, bien qu'il soit basé sur libevent, il a donc un solide backend.
- asyncore : Du stdlib: über bas niveau, il semble que beaucoup de travail de base soit nécessaire pour faire décoller quelque chose.
- tornade : Bien qu'il s'agisse d'un produit orienté serveur conçu pour desservir des sites Web dynamiques, il dispose d'un client HTTP asynchrone et d'un simple ioloop . On dirait que cela pourrait faire le travail, mais pas ce à quoi il était destiné. [edit: ne fonctionne pas sur Windows malheureusement, ce qui compte pour moi - c'est une exigence pour moi de prendre en charge cette plate-forme boiteuse]
Y a-t-il quelque chose que j'ai manqué du tout? Il doit sûrement y avoir une bibliothèque qui correspond au bonbon d'une bibliothèque de réseau asynchrone simplifiée!
[edit: merci à intgr pour son pointeur sur cette page . Si vous faites défiler vers le bas, vous verrez qu'il y a une très belle liste de projets qui visent à aborder cette tâche d'une manière ou d'une autre. Il semble en fait que les choses aient effectivement évolué depuis la création de Twisted: les gens semblent désormais privilégier une solution basée sur la co-routine plutôt qu'une solution traditionnelle orientée réacteur / callback. Les avantages de cette approche sont un code plus clair et plus direct: j'ai certainement trouvé dans le passé, surtout lorsque vous travaillez avec boost.asioen C ++, ce code basé sur le rappel peut conduire à des conceptions difficiles à suivre et relativement obscures à l'œil non averti. L'utilisation de co-routines vous permet d'écrire du code qui semble au moins un peu plus synchrone. Je suppose que maintenant ma tâche est de déterminer laquelle de ces nombreuses bibliothèques j'aime le look et d'essayer! Heureux d'avoir demandé maintenant ...]
[modifier: peut-être d'intérêt pour quiconque a suivi ou est tombé sur cette question ou se soucie de ce sujet dans tous les sens: j'ai trouvé un très bon résumé de l'état actuel des outils disponibles pour ce travail]
select
pour le multiplexage d'E / S. Mais vous devriez pouvoir en tirer une performance décente avec tornado-pyuv . 2. Il y a maintenant asyncio dans Python 3.3+ et son trollius backport qui permet d'exécuter n'importe quelle application Tornado dans sa boucle d'événement (Twisted sera bientôt supporté).Réponses:
J'ai aimé le module Python de concurrence qui s'appuie sur des microthreads Stackless Python ou des Greenlets pour un filetage léger. Toutes les E / S de réseau bloquantes sont rendues asynchrones de manière transparente via une seule
libevent
boucle, donc elles devraient être presque aussi efficaces qu'un vrai serveur asynchrone.Je suppose que c'est similaire à Eventlet de cette façon.
L'inconvénient est que son API est assez différente de
sockets
/threading
modules de Python ; vous devez réécrire une bonne partie de votre application (ou écrire une couche de shim de compatibilité)Edit: Il semble qu'il y ait aussi cogen , qui est similaire, mais utilise des générateurs améliorés de Python 2.5 pour ses coroutines, au lieu de Greenlets. Cela le rend plus portable que la concurrence et d'autres alternatives. Les E / S réseau se font directement avec epoll / kqueue / iocp.
la source
Twisted est complexe, vous avez raison. Twisted n'est pas gonflé.
Si vous jetez un œil ici: http://twistedmatrix.com/trac/browser/trunk/twisted vous trouverez une suite organisée, complète et très bien testée de nombreux protocoles d'Internet, ainsi qu'un code d'aide à écrire et déployer des applications réseau très sophistiquées. Je ne confondrais pas ballonnement avec exhaustivité.
Il est bien connu que la documentation Twisted n'est pas la plus conviviale à première vue, et je pense que cela repousse un nombre malheureux de personnes. Mais Twisted est incroyable (à mon humble avis) si vous mettez le temps. Je l'ai fait et cela en a valu la peine, et je recommanderais à d'autres d'essayer de même.
la source
gevent est eventlet nettoyé .
Du point de vue de l'API, il suit les mêmes conventions que la bibliothèque standard (en particulier, les modules de thread et de multitraitement) où cela a du sens. Vous avez donc des choses familières comme Queue et Event avec lesquelles travailler.
Il prend uniquement en charge libevent ( mise à jour: libev depuis 1.0 ) en tant qu'implémentation du réacteur, mais en profite pleinement, avec un serveur WSGI rapide basé sur libevent-http et la résolution des requêtes DNS via libevent-dns, par opposition à l'utilisation d'un pool de threads comme la plupart des autres bibliothèques faire. ( mise à jour: puisque 1.0 c-ares est utilisé pour effectuer des requêtes DNS asynchrones; threadpool est également une option.)
Comme eventlet, il rend les rappels et les différés inutiles en utilisant des greenlets .
Consultez les exemples: téléchargement simultané de plusieurs URL , discussion en ligne longue .
la source
Une comparaison très intéressante de tels frameworks a été compilée par Nicholas Piël sur son blog: ça vaut le coup d'être lu!
la source
Aucune de ces solutions n'évitera le fait que le GIL empêche le parallélisme CPU - ce sont juste de meilleurs moyens d'obtenir le parallélisme IO que vous avez déjà avec les threads. Si vous pensez que vous pouvez faire mieux IO, poursuivez certainement l'un d'entre eux, mais si votre goulot d'étranglement est dans le traitement des résultats, rien ici ne vous aidera, sauf pour le module de multitraitement.
la source
Je n'irais pas jusqu'à appeler Twisted ballonné, mais il est difficile de se couvrir la tête. J'ai évité de m'installer vraiment dans un apprentissage pendant un bon moment car j'ai toujours voulu quelque chose d'un peu plus facile pour les «petites tâches».
Cependant, maintenant que j'ai travaillé avec, je dois dire que le fait d'avoir toutes les piles incluses est TRÈS agréable.
Toutes les autres bibliothèques asynchrones avec lesquelles j'ai travaillé finissent par être beaucoup moins matures qu'elles ne le semblent même. La boucle d'événement de Twisted est solide.
Je ne sais pas trop comment résoudre la courbe d'apprentissage Twisted raide. Il pourrait être utile que quelqu'un le fourche et nettoie quelques éléments, comme la suppression de toutes les erreurs de compatibilité descendante et les projets morts. Mais c'est la nature d'un logiciel mature, je suppose.
la source
PortableGtkReactor
?Kamaelia n'a pas encore été mentionnée. Son modèle de concurrence est basé sur le câblage des composants avec le passage de messages entre les boîtes de réception et les boîtes d'envoi. Voici un bref aperçu.
la source
J'ai commencé à utiliser le twisted pour certaines choses. La beauté de celui-ci est presque parce qu'il est "gonflé". Il existe des connecteurs pour à peu près tous les protocoles principaux disponibles. Vous pouvez avoir un robot jabber qui prendra les commandes et les publiera sur un serveur irc, les enverra par courrier électronique à quelqu'un, exécutera une commande, lira à partir d'un serveur NNTP et surveillera les modifications d'une page Web. La mauvaise nouvelle, c'est qu'il peut faire tout cela et rendre les choses trop complexes pour des tâches simples comme l'OP expliqué. L'avantage de python est que vous n'incluez que ce dont vous avez besoin. Ainsi, bien que le téléchargement puisse être de 20 Mo, vous ne pouvez inclure que 2 Mo de bibliothèques (ce qui est encore beaucoup). Ma plus grande plainte avec Twisted est bien qu'ils incluent des exemples, vous êtes tout seul au-delà d'un serveur TCP de base.
Bien que ce ne soit pas une solution python, j'ai vu node.js gagner beaucoup plus de traction ces derniers temps. En fait, j'ai envisagé d'envisager des projets plus petits, mais je grince des dents quand j'entends javascript :)
la source
Il existe un bon livre sur le sujet: "Twisted Network Programming Essentials", par Abe Fettig. Les exemples montrent comment écrire du code très Pythonic, et pour moi personnellement, ne me semble pas basé sur un framework gonflé. Regardez les solutions dans le livre, si elles ne sont pas propres, alors je ne sais pas ce que signifie propre.
Ma seule énigme est la même que celle que j'ai avec d'autres frameworks, comme Ruby. Je m'inquiète, est-ce que cela augmente Je détesterais engager un client dans un framework qui va avoir des problèmes d'évolutivité.
la source
Whizzer est un petit framework de socket asynchrone qui utilise pyev. C'est très rapide, principalement à cause de pyev. Il essaie de fournir une interface similaire comme tordue avec quelques légères modifications.
la source
Essayez également Syncless . Il est basé sur coroutine (il est donc similaire à Concurrence, Eventlet et gevent). Il implémente des remplacements non bloquants pour socket.socket, socket.gethostbyname (etc.), ssl.SSLSocket, time.sleep et select.select. C'est rapide. Il a besoin de Stackless Python et libevent. Il contient une extension Python obligatoire écrite en C (Pyrex / Cython).
la source
Je confirme la bonté de syncless . Il peut utiliser libev (la version la plus récente, la plus propre et la plus performante de libevent). Il y a quelques temps, il n'a pas autant de support que libevent, mais maintenant le processus de développement va plus loin et est très utile.
la source
Si vous voulez juste une bibliothèque de requêtes HTTP simplifiée et légère, je trouve Unirest vraiment bon
la source
Vous êtes invités à jeter un œil à PyWorks, qui adopte une approche très différente. Il permet aux instances d'objet de s'exécuter dans leur propre thread et effectue des appels de fonction à cet objet asynchrone.
Laissez simplement une classe hériter de Task au lieu d'objet et c'est async, tous les appels de méthodes sont des proxys. Les valeurs de retour (si vous en avez besoin) sont des proxys futurs.
PyWorks peut être trouvé sur http://bitbucket.org/raindog/pyworks
la source