On Thursday, 18 January, 2018 11:11 PM, Sven R. Kunze wrote:
Mir ist in erster Linie wichtig, dass es funktioniert. Voreilige Optimierungen habe ich schon zur Genüge gesehen. Dafür hat es schon zu oft geklemmt, weil jemand meinte besonders schlau sein zu müssen. Wenn's brennt, dann muss es geradeaus gehen.
Was für mich ein guter Grund wäre, asyncio zu benutzen. Bei Code in der Standardlib setze ich einfach mal voraus, daß da intelligente Menschen am Werk waren. Nochmal das Disclaimer: Ich setze voraus, daß ich weiß, was ich tue. Wenn sich jemand mutwillig selbst in den Fuß schießt, ist das nicht mein Problem. Vielleicht ist das ein netter Blickwinkel: Für mich ist asyncio ein "power feature" für sehr spezielle Anwendungsfälle. Wenn ich die habe, nutze ich es, ansonsten nicht. Wenn's jemand aus Selbstzwecke oder Unwissenheit nutzt, ist das nicht mein Problem. Würde ich in einer Umgebung programmieren wollen, in der man mir meine Mündigkeit (= Option, mir im Glauben smart zu sein, selbst ins Knie zu schießen) nimmt, würde ich Java programmieren. ;-)
Und im Endeffekt ist asyncio nichts anderes als eine Optimierung. Ich denke, da sind wir uns einig.
Nein und ich bin mir nicht sicher, wie du das meinst. Also ich benutze asyncio, um meinen Code zu optimieren.
Deswegen auch das Beispiel mit dem WSGI. Richtig altmodisch klassisch hat man da einen Apache, der 20 WSGI-Worker mit Django zum Beispiel moderiert. Jeder Worker läuft in einem separatem Prozess. Dateien liefert der Apache alleine über eine entsprechende Kernel-Schnittstelle aus. Die Datenbank ist angebunden, 1 Worker 1 Connection üblicherweise. Wenn die Datenbank-Anfrage länger dauert, ist der Worker blockiert und kann keine anderen Anfragen beantworten. Es kann auch 10 bis 100 DB-Anfragen für einen WSGI-Request erfolgen, oder auch mal 10.000, wenn der Programmierer Mist gebaut hat. :D
Deswegen meine Aussage, daß die Welten nunmal unterschiedlich sind. Wenn du mit diesem klassischen WSGI Modell leben kannst, ist das toll. Dann würde ich auch dabei bleiben. Es gibt aber nunmal andere Anwendungsfälle, die quasi 100% IO gebunden sind und die viele Connections gleichzeitig aufhalten müssen.
Jetzt die blöden Fragen:
- wie fummelt man da asyncio hinein? Ich fürchte, das würde überhaupt nicht gehen. "Mal eben ausprobieren" wird hart.
Zumindest ist die Chance, daß etwas sinnvolles dabei raus kommt, relativ gering.
- *was wäre eigentlich die Zielsetzung?*
Gute Frage, die man natürlich vorher klären sollte. Die Zielsetzung könnte aber z.B. sein, 100k Websocketconnections mit möglichst wenig Resourcen bedienen zu wollen.
Angenommen, man hätte das doch irgendwie geschafft: - wie stellt man sicher, dass, wenn die Abarbeitung eines Requests furios in, z.B., einem MemoryError scheitert, nicht auf einmal die anderen 100 Anfragen den Bach runtergehen?
Gar nicht. Und?
- wie stellt man sicher, dass nicht 1 fehlerhaft implementierter View (das ist das Ding, was für einen Request eine Response erarbeitet), alle anderen 100 Anfragen blockiert - await vergessen, oder so?
Wie stellt man sicher, daß Software keine Bugs hat? ;-) Ja, das kann passieren, zeigt sich meiner Erfahrung nach aber ziemlich schnell.
Die Nachteile kooperativen Multitaskings bleiben bestehen, auch wenn diese totgeschwiegen werden. ;-)
Keine Ahnung, ob die totgeschwiegen werden. Ich bleibe da bei meinem bodenständigen "man sollte wissen, was man tut". Vermutlich wird niemand eine GUI basierend auf asyncio entwickeln wollen. Massiv paralleles IO für Batchprozesse ist jetzt in der Regel nicht soooo komplex und ich bezweifle, daß es eine ähnlich einfache Lösung gibt, die gleiche Performance auf Multicoremaschinen zu erreichen.
Ich kann mir gut vorstellen, dass asyncio bei einem kleinen, niedlichen, perfekt abgeschlossenen Projekt, wie einem HTTP-File-Server (wie z.B. nginx) super gut funktioniert. Da ist alles gut abgestimmt, niemand tritt sich gegenseitig auf die Füße und es gibt eig. nur 1 Funktion -> serve_file.
Kleine ins sich geschlossene Projekt, die eine Aufgabe gut erfüllen, sind eine tolle Sache.
Aber die meisten Web-Anwendungen, die Geschäftslogiken abbilden, sind dann doch eher ziemlich kompliziert/komplex und müssen ständig erweitert werden, wo ich mir gut vorstellen kann, dass man sich mit kooperativen Multitasking ziemlich sicher ins Knie schießt; auch je größer das Team wird. Da fehlen mir die Sicherungsmaßnahmen, die man bei einem separaten Prozess einfach hat.
Natürlich. Aber warum sollte ich für sowas asyncio verwenden wollen?
Ich hoffe ja noch immer bisschen auf golang-Einfluss. :D Aber bei vielen hier steht da noch das Ego im Weg.
Auch wenn Ego in unserer Branche ein Problem ist, sehe ich das hier anders. Die Interna von Python machen es schwer bzw. unmöglich, Code "einfach so" schlafen zu legen. Es gibt genug Vorträge von Guido bzgl. Entfernen des GIL, in denen er das besser erklärt, als ich es aus dem Kopf kann. Bei Armin Rigo kann man nichts ausschließen und evtl. baut er ja ein Python mit "software transactional memory" und ohne GIL. Aber bis dahin ist mein Verständnis, daß das, was du gerne hättest, ganz einfach nicht geht.
Der Hauptkritikpunkt, den ich gelten lassen würde, ist, daß in den meisten Beispielen eben exakt der Übergang ausgespart wird. Ich hab' mir beim ersten mal auch den Wolf gesucht, bis ich die richtigen Funktionen zur Hand hatte. Und um sie zu benutzen, muß man schon ein solides Bild davon haben, was da passiert.
Ist man von Python eben nicht gewöhnt. So etwas fühlt sich dann an, wie wenn man von Python Ganzzahlen zu C int32 wechseln muss.
Deswegen oben mein Verweis auf "power feature". Der durchschnittliche Entwickler wird nie einen Grund haben, asyncio zu verwenden. Viele werden es versuche, weil es möglich ist. Ähnlich wie bei meta classes. Daß ein Feature mißbraucht wird, macht es aber nicht per se schlecht.
Nochmal mein Fazit: Ich halte async/await für die beste Abstraktion, die in Python geht.
Ich würde diese Aussage insoweit relativieren, dass es zur Zeit als die von vielen beste Abstraktion angesehen wird.
Damit kann ich leben. ;-) Gerne höre ich mir auf der nächsten Europython deinen Vortrag darüber an, wie man's besser machen könnte. Das hätte quasi schon Tradition. :-) Nur so aus Neugier: Es gibt Sprachen wie Go, die u.a. für diese Anwendungsfälle gebaut wurden. Klar sind sie in dem Bereich besser. Hast du dir mal Lösungen in den anderen Web/Script-Sprachen angeschaut? Ruby, Php, ... Hast du da irgendwas gesehen, daß eleganter wäre, also das asyncio von Python? Grüße, Achim