Transcript: Python Async Teil 1 - am Beispiel von Django

· Back to episode

Full episode transcript. Timestamps refer to the audio playback.

Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Python-Podcast.

Heute ist die 23. Episode, also für uns wieder eine ganz besondere Zahl.

Was machen wir heute? Heute machen wir wieder Async und Multispelling und sowas.

Und zwar Django Async kommt bald raus und darüber haben wir eine eigene Folge aufgenommen.

Und zwar in dem schönen Wintergarten von Jochen. Ich bin der Dominik.

Und diesmal haben wir natürlich wieder einen Gast. Den kennt ihr vielleicht schon.

Hallo Johannes.

Hallo Dominik. Hallo Jochen.

Und hallo Jochen.

Hallo, genau. Auch wieder dabei.

Falls euch irgendwas gefällt oder nicht gefällt,

dann schreibt uns doch wie immer gerne eine E-Mail an

hallo.python.gc

Und wir möchten uns auch gerne noch für ein paar Abonnenten bedanken.

Und zwar haben wir allein auf Spotify

mittlerweile über 1111 Abonnenten.

Herzlichen Dank dafür und wuhu!

Sehr cool, wir freuen uns.

Ich finde es toll.

Naja.

Dir reicht es noch nicht, du bist die Weltforscherin.

Du guckst zu viele YouTube-Channels.

Ich weiß nicht genau.

Ist das da so üblich?

Ich weiß nicht, ob das auf dem Podcast auch so üblich ist.

Ach was denn, ich habe mich einfach gefreut

Ja, ist schon toll, aber

keine Ahnung

Ja, wo wir gerade schon bei so anderen Sachen sind

Ihr habt ja vielleicht den Thomas gehört, der mit uns eine

schöne Folge gemacht hat und der hat

jetzt seinen Podcast umgenannt, also wir hatten ihn das letzte Mal

zu wenig erwähnt, deswegen müssen wir es auch einmal extra erwähnen

Der ist ein ziemlich cooler Podcast, den er da

hat, wie heißt der jetzt, Jochen?

Dads instead

Dads instead, und Kevin ist schon dabei

in einem letzten Talk und redet über PyMC3

Ich glaube, das ist sehr hörenswert

Ja, ich habe es gestern schon gehört, fand es sehr gut

Also, ja.

Ja, vielen Dank.

Und ich hätte jetzt gar nicht gedacht, ich meine, dass Instagram

Python macht, aber dass sich halt deren Gründer

und Ex-CEO irgendwie so viel mit

Statistik und Machine Learning Kram

so beschäftigt ist und Data Science.

Oder naja, gut, das hat er ja vorher nicht so gemacht, aber das macht er jetzt halt.

Das fand ich schon sehr interessant und

war auf jeden Fall eine

interessante Geschichte. Ja, hört doch da mal rein, wenn ihr möchtet.

Ja, wir machen

heute wieder Dango, vor allen Dingen halt, weil

Dango 3.1 jetzt im August

erscheint und tatsächlich jetzt mehr

Async-Features unterstützt als in der 3.0-Version,

die seit Dezember draußen ist.

Und wir möchten ein bisschen mit euch

darüber reden oder untereinander darüber

reden, was das überhaupt heißt, was das alles so ist.

Was ist überhaupt dieses

Multispring? Wir hatten das in irgendeiner Episode schon mal so ein bisschen

angerissen, vielleicht auch so ein bisschen kurz

verbrochen, aber uns sind noch so ein paar andere Erkenntnisse

gekommen und darüber wollten wir

halt so sprechen. Warum

macht man so ein Spread und warum macht man so ein Multiprocess

und warum macht man das dann irgendwie Async und

warum macht man das mit Async.io und was gibt es da noch

für Alternativen, wann braucht man das überhaupt

und warum und warum vielleicht auch überhaupt nicht

und irgendwie so.

Ja, wollten wir vielleicht erst mal

so ein bisschen News machen?

Oh, News, ja, du hast natürlich recht.

Neuigkeiten aus der Szene.

Ja, wobei so wahnsinnig viel gab es nicht.

Ich habe mir nur so ein paar Dinge aufgeschrieben.

Ich weiß nicht, ob du das verwendest.

Insofern kannst du vielleicht...

Pylance.

Ja, sehr gut. Ja, also Pylance ist ein neues Plugin,

was für VS Code rausgekommen ist, also ein neuer Language-Server,

wenn ich das richtig verstehe.

der ziemlich coole Sachen macht, also mit der Auto-Import-Sätze

in VS Code und so und fast alle

Features, die man sonst so auf PyCharm eher hatte

und also ich mag ihn sehr gerne. Hast du ihn auch schon

aktiv im Einsatz? Ich hab das auch schon

aktiviert und finde es auch ziemlich gut.

Also ich mache ja jetzt gar nicht so viel

mit Type-Annotationen, aber

die Verlockung wird stärker.

Und das Ding kann da

irgendwie einiges rausholen, ja.

Tja, Johannes, da bist du raus, denn du nutzt PyCharm, ne?

Ja, tut mir leid, ich hab die Features alle schon.

Ja, ich meine, ich benutze

ja auch PyCharm.

also insofern, also ich finde das auch gar nicht schlecht.

Du wurdest dazu gezwungen, habe ich gehört, Jochen.

Naja, mehr oder weniger.

Ich meine, ich finde es ja auch interessant.

Also ab und zu mal andere Dinge verwenden, ist vielleicht gar nicht so wichtig.

Bei uns nutzen uns alle VS Code.

Achso, wer übrigens auch VS Code

natürlich nutzt, ist Daniel Feldtroy,

falls ihn kennt, der Autor von Two Scrooge of Django,

der ja bald das 3X-Version-Buch

rausnimmt. Und ich war letztens bei ihm

ein, zwei Mal in seinem Twitch-Stream, weil er irgendwie

streamt irgendwie Twitch und er hat mir versprochen,

dass er in Düsseldorf zum Essen vorbeikommt.

Ich bin natürlich ganz gespannt, ob das irgendwie nicht nur blöd ist.

Ja, das kann man leicht versprechen, solange keine Flugzeuge fliegen.

Ich glaube, ein zweites Mal, als ich da war, hat er gedacht, oh, warst du nicht der aus Istanbul?

Ich so, nee, das war aus Düsseldorf.

Das ist ja relativ gesehen nach Düsseldorf.

Kann man sich dann da Bücher signieren lassen?

Ja, also wenn die Altenbühne auf dem Ball, ja, das hat er ja auch gesagt.

Vielleicht verliege ich dann sogar dahin und dann quatschen wir ein bisschen.

Nein, das fand ich super, wollte ich nur mal kurz erwähnen haben.

Ja, aber es stimmt, ich gucke in letzter Zeit auch gerade in Vorbereitung auf diese Episode, habe ich relativ viele YouTube-Channels und so geguckt und da verwenden doch sehr viele VS Code.

Du hast dich vorbereitet?

Ja, ausnahmsweise mache ich das eigentlich nicht, aber ich fand es auch sehr unangenehm, ehrlich gesagt, wenn ich das nochmal machen möchte.

Aber gerade zum Beispiel, da gab es eine Serie von Lukas Langer, der hat auch VS Code verwendet.

zu Async.io und so.

Auch sehr empfehlenswert, kommt auch noch in die Show.

Ansonsten war ich glaube ich

irgendwie für 3.7

ist die letzte

Bugfix-Release irgendwie

gerade erschienen. Für 3.6

noch irgendeine Security-Geschichte

Python und das

war es dann so ziemlich irgendwie mit...

Ja, bald ist 3.9 durch.

Ja, bald kommt dann 3.9, genau.

Was ist denn das Tolle an 3.9?

Wie hast du das jetzt mal gefragt?

aus dem falschen Fuß erwischt.

Also ich meine, das Tolle an 3.8

ist ja der Walrus Operator und den wir auch

alle ständig immer benutzen.

Ich wüsste nicht, was in 3.9 neues drin ist.

Doch, also ich habe gehört,

dass zum Beispiel diese

Subinterpreter-Geschichte da irgendwie

mit drin sein soll.

Also das war fraglich eine Zeit lang

und dann gab es...

Was ist ein Subinterpreter?

Ja, das ist im Grunde auch so eine Methode,

um dann halt eventuell...

Also, ja, um halt in Gil so ein bisschen loszuwerden oder halt das so ein bisschen...

Gil ist der Global Interpreter-Log, ja?

Ja, um das so...

Da werden wir sicherlich gleich noch ganz viel drüber sprechen.

Genau, die Konsequenzen so ein bisschen zu mitigieren.

Und das sollte...

Obwohl, ich weiß es nicht, was ich da erzählen soll.

Ich habe keine Ahnung.

Also, ich habe gehört, Python 3.9 unterstützt einen neuen Parser und der macht ganz viel anders.

Und deswegen kann man jetzt auf einmal ganz viele andere Code-Analyse-Tools oder irgendwas benutzen.

Ja.

Aber...

Ja, diese Back-Parser-Geschichte, ja.

Ja, weiß ich aber auch nicht so viel zu.

Also für den normalen

Programmierer erstmal keine Unterschiede.

Ja, nicht so richtig viel.

Also muss man sich mal mit

beschäftigen, vielleicht gibt es auch irgendwelche total coolen Sachen.

Na gut.

Ansonsten Django, genau, war auch

2.2.14 und 3.0.18

sind irgendwie vor kurzem raus.

Ja. Ja, also Django ist

hart an der Entwicklung zu 3.1

und das ist ja das, worüber wir heute reden wollen,

weil es halt tatsächlich diese Async-Features jetzt gibt.

Oder hast du noch mehr News aus der Szene?

Ja, ich habe welche aus dem Hintergrat, beziehungsweise aus dem persönlichen Setup.

Und zwar, genau, ich weiß nicht, ob man es hören kann, aber wir haben eine große Bohrmaschine genommen

und dann irgendwie immer die Außenmauer durchlöchert und jetzt ist hier tatsächlich kabelbasiertes Netz.

Oh!

Es könnte sein, dass es jetzt deutlich weniger knackst als vorher.

Also du meinst nicht, weil es weniger WiFi gibt und jetzt mehr konstantes LAN?

und es gibt halt richtig ordentliches...

Stimmt, ich sehe sogar da hinten das Kabel, das durch die Wand

in den Raum geht.

Und eine zweite

Geschichte, die auch neu ist

und die ich eigentlich ganz cool finde,

weil ich nicht wusste,

also ich habe das Ding einfach mal so auf Verdacht gekauft

und wusste nicht, ob es geht, aber es ging tatsächlich,

war, ich habe mir so eine

Caldigit Docking Station

besorgt. Eine was?

Caldigit.

Ja, ja, ja.

Das Ding

versorgt gleichzeitig

einen Rechner mit Strom, macht irgendwie

Thunderbolt und du kannst

Monitore dran anschließen und was ich halt da drin habe,

also ich habe sozusagen nur noch ein Kabel, das ich

halt immer an den Rechner stecke, weil ich hatte

nämlich jetzt, weil ich jetzt Netzwerkkabel habe,

das Problem, okay, wie mache ich denn das

Netzwerkkabel an meinem Rechner fest, der hat ja nur OSWC,

da so irgendwie

so ein Dongle dran zu hängen, der dann so rumbaumelt,

ist auch irgendwie etwas unschön,

zusätzlich zu den ganzen anderen Adaptern

und Dongle, die da sowieso schon rumbaumeln.

und das geht damit halt ganz gut, weil da steckt man einfach Ethernet hinten rein plus irgendwie das, was zum Monitor geht

und hat halt nur ein einziges Kabel, was zum Laptop geht und alles andere geht dann über die Dockingstation

und was tatsächlich funktioniert ist, ich habe da hinten halt dann noch Storage dran

und das ist schnell, also so eine externe SSD und das ist ordentlich schnell, der Monitor ist so ein ultrafein LG 5K

und da dachte ich auch so, oh, ob das funktioniert,

aber es funktioniert tatsächlich und es kommt auch noch Strom durch.

Also ich suche auch schon was ähnliches.

Ich möchte gerne meine Monitore umschalten

mit so einem Switch und zwar einmal auf

eine Workstation und einmal auf meinen

normalen Rechner.

Eine KVM-Switch. Ja, genau, eine KVM-Switch und ich habe mich

dann gefragt, ob es da was Vernünftiges für gibt, weil ich hätte gerne

auch die Auflösung der Monitore

und mit Switch immer hin und her

geschaltet zwischen allen Setups.

Das finde ich cool, aber ich habe noch keine Ahnung,

was es da gibt. Also falls ihr da irgendjemanden kennt oder

einen guten Tipp habt, her damit. Ich freue mich drüber.

und schaue ich mir an und probiere das mal aus.

Ansonsten, nö, sonst habe ich nichts mehr.

Johannes, hast du eine News, eine Neuigkeit?

Nee, ich bin immer noch im WLAN, ich habe kein Kabel.

Du bist tatsächlich im WLAN bei dir im Haus?

Ja, das geht ja nicht anders.

Das ist zu weit weg.

Vormaschine?

Ja, nicht in den Meters.

Und ich habe schon lange so ein relativ altes Lenovo-Dock.

Das gehört auch gar nicht zu meinem Rechner,

sondern das habe ich einfach mal irgendwo gekriegt für, keine Ahnung, 50 Euro oder so.

Und das ist super.

Ein Dock ist total gut.

Da ist einfach alles eingesteckt.

Tastatur eingesteckt, Maus eingesteckt, Monitore eingesteckt, Storage ist auch dran.

Das ist total gut.

Und du sitzt diesmal auf einem anderen Stuhl und auf einem anderen Schreibtisch,

also vor einem anderen Schreibtisch in deinem Büro.

Naja, nee, ich habe ja zwei Arbeitsplätze in meinem Büro.

Ja, genau.

Und nicht auf einem anderen Arbeitsplatz.

Er ist ja Vatikan nicht zu Hause, na gut.

Es gibt den

mobilen Arbeitsplatz und den immobilen

Arbeitsplatz und das ist jetzt der fest installierte

mit den großen Monitoren

Ja, cool, okay, dann würde ich sagen

von mir aus

tatsächlich das Thema

Ich bin absolut begeistert, das ist eine Weltpremiere

ja heute, liebe Hörerinnen und Hörer

hört zu, ihr wisst genau, was euch jetzt erwartet

Weltpremiere Dango Async 3.1

Ja, also

genau, ich habe mich da

Ich habe direkt mal eine Frage.

Was ist denn der Async?

Muss ich irgendwas beachten, wenn ich jetzt von 3.0

auf 3.1 upgrade, muss ich dann irgendwas

machen oder geht es dann auch noch alles?

Das geht alles genauso wie vorher auch.

Wichtigste Frage direkt geklärt.

Also erstmal nochmal

ganz kurz zum Frame, zum Rahmen,

worum es eigentlich geht.

Was Async dann überhaupt bedeutet

und was man jetzt damit machen kann, was vorher

schon so ging, so diese Geschichte

und wofür man das eigentlich braucht.

Womit wollt ihr denn anfangen?

vielleicht, was das ist, Async überhaupt und ja, dann kommt man vielleicht darauf, warum man das vielleicht haben wollen möchte oder vielleicht auch gar nicht braucht.

Das ist gleich eine schwierige Frage am Anfang.

Also ich glaube, ich würde tatsächlich mit der Motivation starten, weil sonst wird das direkt so trocken und alle Leute schalten sofort auf Durchzug und wenn man so zumindest weiß, dass es irgendwie vielleicht nicht so super unwichtig ist und dass tatsächlich irgendwie interessante Dinge damit gehen,

Dann vielleicht hält man ein bisschen

länger durch. Also du weißt schon, dass da

EVE Online steht und das ist ja gleich sonst ein Exkurs

von mir zu EVE Online.

Ja, genau, das wäre interessant.

Aber die sind doch noch auf

2.7, die kriegen da ja doch die ganzen

Sachen gar nicht mit alle.

Aber es gibt wahrscheinlich Gründe, warum das so ist.

Also okay, ich fange einfach mal so an.

Das ist der Grund.

EVE Online hat

von Anfang an gesagt, wir haben, keine Ahnung,

15 Millionen Codezeilen in unserem Server, wir fangen

jetzt nicht an, die auf Python 3.

Genau, EVE Online basiert

viel auf Python, falls ihr das noch nicht gehört habt.

Ja, genau. Und soweit ich weiß,

ich weiß nicht, ob das immer noch so ist, aber soweit ich

das gehört habe,

auch auf Slackless Python.

Oh ja, das ist interessant.

Da umgehen sie ja gleich viele von den Dingen, was

halt mein Async überhaupt braucht.

Genau, also

beziehungsweise zu der Zeit, wo sie das

gemacht haben, gab es das halt einfach noch nicht.

Und Slackless Python war halt eine Lösung für die

Probleme, die sich da gegeben haben. Und ich meine, gut, wir können

auch einfach direkt so einsteigen, weil das ist ja auch eine gute

Motivation, warum braucht man sowas überhaupt

und was die wohl können.

Also hieß es jedenfalls,

ist, dass

da das alles in Stackless Python

halt auch so

Userland Threads oder Green Threads

oder wie auch immer man die nennt, sind

Stackless Python

halt im Grunde braucht es keinen

Execution Stack dafür im Betriebssystem.

Kennst du die, was

Stackless Python kann, ist, du kannst diese Threads

picklen.

Ja, vor allem kannst du

mehr als einen ausführen, oder?

Ja, das auch, du kannst ganz gerne ausführen

Das hat auch keinen Global Interpreter-Log, das heißt, du kannst einfach

Also ihr erkennt jetzt gerade

wieder die ganze Bagage

mit dem Graphics-Collector in den Müll

Moment, stopp, stopp, stopp

da sind wir doch noch nicht

Also, ich wollte eigentlich

nur mal kurz, warum man das eigentlich machen will

was das Coole daran ist, also

dadurch, dass diese Threads, also wenn ich jetzt zum Beispiel

halt ein Ding, ich habe keine Ahnung, wie die

funktioniert. Ja, ich kenne das nicht gar nicht.

Aber ich glaube, es geht irgendwie um Raumschiffe und so, die da

in den Weltraum rumfliegen.

Excellent Space.

Gut, wenn es Spaß macht, aber naja.

Und du hast jetzt irgendwie

einen Thread, der jetzt so ein Raumschiff simuliert,

das da so durch die Gegend fliegt, dann kannst du halt

das Ding pickeln, in eine Datenbank

schreiben, irgendwo anders

wieder auspacken

und weiter ausführen.

Ja, das ist eine sogenannte Continuation,

wäre mal die akademische

Fachliteratur.

Ah, okay, gut

Und das ist natürlich, wenn man ein riesen

Universum hat, vielleicht eine ganz gute Sache

wenn man das machen kann, weil eventuell

will man halt nicht alles immer laufen haben

sondern möchte halt auch

Teile von dem Universum, das man simuliert

da irgendwie auch einfach mal

einfrieren und in die Datenbank

schreiben und erst dann wieder auftauen, wenn man es

tatsächlich benötigt, damit man nicht immer alles

gleichzeitig ausführen muss oder so

Wäre eine gute Idee für Zeitreisen

Aber wir wollten über die Motivationen nochmal

dann doch vielleicht kurz, lass das doch mal kurz, heute

ausnahmsweise strukturierter angehen.

Und dann, wir gehen auch versprochen wieder zu EVE Online

zurück. Ja, also

genau, die Frage ist halt

sozusagen, ob

nicht es

valide Use Cases gibt für

so sehr,

das deutsche Wort ist so ein bisschen

doof, aber ich

weiß auch nicht,

ob man da ein besseres finden kann,

massiv nebenläufige Programme.

Also man braucht halt viel Concurrency.

und die Programmiersprache Python.

in Go, es gibt diverse Geschichten in Node.js

oder Rust

oder Erlang. Erlang ist

auch ziemlich en vogue gerade und die Frage

wäre halt, wenn man jetzt so einen Use Case hat,

bedeutet das, dass man die Programmiersprache wechseln muss

und dann halt Erlang machen muss oder

kann man das auch in Python machen?

Eigentlich kann man das auch in Python machen,

ist jetzt sozusagen dafür die Infrastruktur

noch nicht so ausgeprägt

wie in anderen Sprachen, aber so prinzipiell

geht das schon

und man könnte jetzt sagen, na gut, das hat

ein bisschen lange gedauert, also die Geschichte von

von Async in Python ist wahnsinnig lang.

Aber in letzter Zeit wird es halt

sehr interessant. Zum Beispiel, wenn man jetzt Django als Beispiel

nimmt, dann geht das jetzt gerade erst

so richtig. Und der Grund dafür ist,

dass eigentlich will man

die Syntax dafür haben,

für Kuroutinen.

Und die ist erst seit 3.5 so richtig

in der Sprache. Das heißt, vor 3.5 ist

sowieso schwierig.

Und Django hat mit

Version 1.11 noch Python 2

supported. Dann geht es auch nicht.

Das kann man einfach vergessen.

und mit Django, glaube ich, 2.1, 2.2 weiß ich gar nicht mehr,

aber noch Python 3.4 und mit 3.4 geht es auch nicht.

Das heißt sozusagen, also bis vor kurzem konnte Django das gar nicht mit der nativen Syntax machen,

weil Python-Versionen supportet wurden, bei denen das einfach nicht geht.

Und jetzt ist es halt sozusagen alt und abgehangen genug,

dass sozusagen nur noch Python-Versionen unterstützt werden,

mit denen man das dann tatsächlich nativ machen kann.

und jetzt kann man halt anfangen, das umzustellen.

Beziehungsweise die Arbeiten daran sind ja jetzt auch schon was älter,

aber jetzt ist es halt so weit, dass es tatsächlich mal in einer

für User verwendbaren Form halt tatsächlich in Django ankommt.

Und wenn man sich sowas überlegt, also was ich zum Beispiel mir angeguckt habe,

Erlang ist ja relativ irgendwo gerade, beziehungsweise halt so ein Dialekt,

der oft dann so für Webentwicklungsgeschichten benutzt wird, Elixir.

Und da gibt es auch so ein Webframework Phoenix zum Beispiel

und da kann man auch mal sich angucken, so Phoenix Elixier,

LiveView,

solche Sachen und das

sieht alles schon sehr beeindruckend aus und

ist auch sehr nett. Und die Frage

wäre halt, kann man sowas in Django und Python

auch machen? Und die Antwort ist eigentlich ja.

Eigentlich gibt es nichts, was einen davon prinzipiell abhält.

Außer, dass es

halt nicht, dass man nicht so unterstützt wird

in den Frameworks und so, aber prinzipiell

geht das schon. Was macht das denn jetzt so

bei dir so schön?

Ja,

Keine Ahnung, habt ihr noch was?

Oder wegen Motivation oder was?

Ich überlege gerade, ob ich jetzt schon ausreichend motiviert habe

Ja, da fehlt noch

ein kleines bisschen vielleicht, warum

man das vielleicht macht, könnte man bei der Motivation

direkt sagen, oder? Also was für Problemfälle

gibt es denn, die man jetzt

Ja, es gibt ja schon immer, also ich meine, es gibt ja schon

immer Anstrengungen

Sachen zu parallelisieren

und da gibt es auch schon ganz

alte Sachen

nur damals war es halt

damals, also vor 10 Jahren war es halt noch so

dass Computer 2 Cores hatten oder 4 Cores

und da ist es nicht so wild

wenn du nur einen benutzt

aber heutzutage ist es ja relativ leicht

gerade im Serverbereich Sachen zu kriegen

die 64 oder 128 Cores haben

oder noch mehr wenn man das unbedingt

haben möchte oder wenn man auf Grafikkarten geht

kriegt man direkt in die Tausenden von Cores

deshalb ist das

man darf da nicht so viel Python verdammen

weil das einfach vor 10 Jahren noch kein Problem war

Moment, aber das ist jetzt glaube ich ein anderes Problem, oder?

Also aus meiner Perspektive ist es ein anderes Problem

Generell die

Nebenläufigkeit, die man da jetzt braucht

Aber das braucht man

Das haben die anderen auch nicht

Das kriegst du auch auf Node.js nicht hin

Das mag sein, dass

das mit Node.js nicht unbedingt hinkriegst

Aber mit C und Erlang und Rust

und so weiter kriegst du die Sachen schon hin

Und Go auch

Die nutzen schon alle Cores aus

Ja, aber da weiß ich gar nicht, ob man das unbedingt braucht.

Also da würde ich jetzt denken, warum?

Doch, also ich glaube, für mich ist das schon eine Motivation, mehr Core ausnutzen zu können.

Geht zwar nicht mit Async, das weiß ich, aber generell, der Trend geht dazu, mehr Sachen gleichzeitig zu machen, um es mal so auszudrücken.

Und dafür braucht man halt irgendeine Syntax.

Und klar, es gibt die ganzen Sachen, die man früher machen konnte.

da gibt es die coolen

Message Passing Interfaces und die coolen

was weiß ich

verteiltes Rechnen Ansätze und dann

gibt es Threads und Multiprocessing und so weiter

aber die haben halt alle ihre

Nachteile und die haben halt alle ihre

sagen wir mal

Schwierigkeiten

und gerade wenn man anfängt mit Threads

zu arbeiten in Python merkt man halt sehr schnell

dass das von der Geschwindigkeit her überhaupt gar nichts bringt

also

ist die Frage was man mit Geschwindigkeit meint

ja wenn es um

quasi, wie schnell kann man Dinge machen,

geht, dann bringt einem das nichts, sondern

macht die Sachen langsam.

Nicht viele Sachen gleichzeitig kann ich machen.

Wir helfen einem

im Verhältnis in Python ja erstmal gar nichts.

Ja, wobei, da würde ich direkt

unterscheiden zwischen Sachen

parallel machen, das heißt

und Sachen concurrent

und danebenläufig, ja, weiß nicht, ob das eine gute Übersetzung

ist, könnte man nicht.

Die deutschen Worte sind da total blöd.

weil parallel geht halt

in Python nicht, aber ich glaube auch nicht, dass das

das Problem ist.

Oder geht noch nicht.

Da gibt es verschiedene Workloads, glaube ich, die du da

bedenken musst.

Also multiprocessing parallel?

Dann hast du ja schon Parallelität. Mit NumPy kriegst

du die Cores schon alle voll.

Ja, klar, genau. Insofern würde ich sagen, das ist auch ein Problem.

Vielleicht müssen wir erst noch erklären, was Parallelität und Nebenläufigkeit sind.

Ja, bitte, bitte. Einmal kurz da einschalten.

Ja, aber ist

Multiprocessing nicht sowas wie

parallel?

oder...

Ja, Multiprocessing ist parallel, aber auch das

kannst du nur machen, wenn du

wenig Kommunikation hast, weil

du da eben zwischen Prozessen kommunizieren musst

und das ist langsam.

Das ist generell die Krankheit, die du hast,

wenn du solche Message-Parsing-Sachen

machst.

Das hatten wir ja früher auch schon gehabt.

Als ich studiert habe, hatten wir einen großen

Cluster, der hatte 16 Prozessoren

an der Universität.

Und das waren halt unterschiedlich, es waren halt 16

Computer.

die mit einem schnellen Netzwerk verbunden waren.

Aber je weniger Nachrichten du schicken musstest,

umso schneller war das dann halt.

Das heißt, im Wesentlichen warst du da gar nicht

durch die CPU gedrosselt,

sondern eben durchs Netzwerk.

Ja, ja, gut.

So ein bisschen ist es bei Multiprocessing ja auch.

Je weniger Nachrichten du schicken musst, umso

besser.

Irgendwie, dass man sagt, man hat

so eine gemeinsame Verwaltung.

Genau, es gibt Chat-Memory, kannst du einfach wenden, musst du gar keine Nachrichten schicken.

Cool, sowas gibt es schon?

Ja, ja, das ist auch eingebaut. Seit Python 3.8 ist das drin.

Also du kannst sagen, hier irgendwie...

Ja, umso besser.

Aber dann hast du trotzdem noch

irgendwelche Locking-Mechanismen, die dir da

gut erraten mussten.

Aber wenn du CPU-bound bist, ist das alles nicht mehr schlimm.

Also das ist alles...

Ich würde sagen, wenn du Dinge einfach...

Wenn du jetzt irgendwie Number-Crunch-Geschichten machst,

da alle Cores zu verwenden,

ist in Python überhaupt kein Problem.

Das geht super. Das ist tatsächlich einer

der beliebtesten Anwendungsfälle für Python.

Also ich würde sagen, Data Science...

Python ist wahrscheinlich die Sprache Nummer 1

gerade und das ist ja

hauptsächlich so ein Zeugs und da geht das super.

Da werden immer alle Cores benutzt, gar kein Problem.

Ja klar.

Im Wesentlichen ist der Trick halt daran, dass die

aus Python rausgehen, die

Bibliotheken und dass die das halt in C machen.

Ja, oder du kannst halt auch so Dinge machen,

nee, nee, nicht nur. Also

du kannst auch pure Python-Funktionen parallelisieren.

Also mit REST geht das.

Auch mit mehreren Maschinen hinweg.

Achso, ja, okay.

Aber das ist, also

ich habe hier gerade die...

Das ist jedenfalls Parallelität.

Man macht Berechnungen auf mehreren

Prozessoren und die sind gleichzeitig

im Wesentlichen. Und es spielt keine Rolle,

ob es die gleiche Berechnung ist oder eine andere Berechnung.

In den meisten Fällen werden es ja die

gleichen Berechnungen sein.

Auf allen

Teilen dieser Tabelle möchte ich

jetzt ausgerechnet haben, was die Summe ist.

Genau.

Also ich habe hier die

Definition von

Rob Pike,

der sich da mal ausgedacht

hat und der sagt halt,

Concurrency is about dealing with lots of

things at once. Parallelism

is about doing lots of things at once.

Not the same, but related.

One is about structure, one

is about execution. Concurrency

provides a way to structure a solution

to solve a problem that may,

but may not necessarily be

parallelizable.

Ja, das hätte ich erst mal.

Ich dachte, das hätte ich gerade.

Nee, das fand ich jetzt auch

nicht arg erhellend, aber

Verdammt, na gut

Ja, Parallelität ist halt

Sachen gleichzeitig machen

und Concurrency ist verschiedene Sachen machen

Das ist so wie es in meinem Kopf ist

Ja, eine Erklärung, die ich mal gehört habe

vielleicht ist die besser

ein paar durchprobieren

ist das halt sozusagen

ein Bartender kann

irgendwie viele Kunden

concurrent

behandeln, sozusagen, oder wenn ein Bartender

viele Kunden hat, die er

mit Drinks beschickt,

dann ist das irgendwie Concurrency.

Aber wenn du mehrere Drinks gleichzeitig machen willst,

brauchst du mehrere Bartender. Da reicht einer nicht.

Und das wäre dann

Parallelität sozusagen.

Ja, also

mehr Arme für den Barkeeper.

In meinem Kopf

geht es bei mir ganz viel um das Wort gleichzeitig Parallelit hei du machst mehrere Sachen gleichzeitig Und Nebenl oder Concurrency hei du machst mehrere Sachen nebeneinander her

Also nicht an einem abschließenden Schritt erstmal den einen Drink mixen,

sondern fünf Gläser hinstellen, jedes Mal einmal ein bisschen Zitrone rein und dann ein bisschen Drink.

Genau, also du hast fünf Drinks, die du zubereiten musst und du machst halt die Schritte von denen

und du machst erstmal was an dem Drink 1, dann machst du was an Drink 2, dann machst du was an Drink 3.

am Ende sind alle fertig. Die Gesamtzeit

ist dann ja genau dieselbe, also

du wirst ja fünf Einzel machen, nur du hast halt

dann fünf gleichzeitig rausgeschickt und alle haben

quasi die Zeit gewartet, anstatt

dass du jeweils erstmal den ersten, den zweiten, den dritten, den vierten,

den fünften... Genau, also du machst

eventuell die Latenz

geringer. Du kannst schon mal die Bestellung

des Nächsten annehmen, während

ein Drink noch in Bearbeitung ist.

Ja, du kannst halt den Nächsten bearbeiten, während einer noch,

weiß ich nicht, während in einem irgendeine

fürchterliche chemische Reaktion läuft, die halt eine Zeit lang

braucht und du wartest halt jetzt nicht stumpf

davor ab, sondern du wartest auf den

Assistenten.

Der Erste, der sonst seinen Drink sofort bekommen hätte, weil er das erste

in der Stange stand, der muss jetzt länger warten.

Potenziell ja.

Aber guck mal, wenn da gerade kein

Eis da ist, dann kannst du ja einen

anderen Drink machen, während du aufs Eis wartest.

Oder während dir jemand was aus dem Lager holt.

Das merkt der erste Kunde

überhaupt gar nicht, weil der muss so oder so

drauf warten, bis sein Eis da ist.

Ja, aber nur dann kannst du was anderes machen.

sein, Tasks.

Ja, genau, wenn du Wartezeiten hast

und dann bemerkt der

erste Kunde gar nichts, dann hast du automatisch

weniger Latenz und mehr

Durchsatz, weil du Wartezeiten

nutzen kannst. Und das ist ja eine der großen

Allüren dieser ganzen

Geschichte, dass du sagst, okay, ich muss jetzt eh auf

eine Datenbank warten oder auf die Dateien.

Ja, also sobald zwei Leute

arbeiten, also nicht nur den Barkeeper, sondern

auch die Küche und du möchtest immer einen Drink mit Essen

servieren oder sowas. Und solange das Essen noch nicht fertig ist,

dann kannst du alle anderen Drinks schon fertig.

Ja, genau. Wenn du Abhängigkeiten

hast oder wenn du Wartezeiten hast, die kannst du

überbrücken, indem du was anderes machst. Und das ist

Concurrency. Du machst nie Sachen gleichzeitig.

Der Bartender kann nie

mehrere Sachen gleichzeitig machen.

Die magst du keine 5 oder 6 Arme.

Genau, der hat halt nur einen

Prozessor.

Aber der kann mehrere Drinks gleichzeitig zubereiten.

Das heißt nicht, dass er überall gleichzeitig was reinschüttet,

aber das heißt halt, dass die alle

zu einem gleichen Zeitraum in Bearbeitung

sind. Genau wie der Jochen sagt, wenn

5 mal so viele Drinks machen willst,

brauchst du halt mehr Bartender und

die sind dann auch erstmal unabhängig voneinander.

Es gibt jetzt leider keine Simdi-Bartender,

mehrere Sachen identisch

gleich machen können, dann könntest du

5 identische Drinks gleichzeitig

zubereiten.

Da wirst du jetzt keine

Analogie in der echten Welt.

Aber Async

ist jetzt Parallelität oder

Concurrency? Also ich würde sagen,

dieses Problem Parallelität

ist, also dass du beides gleichzeitig brauchst,

also das wäre jetzt mal eine steile These,

ich meine, ich weiß jetzt auch wieder, wann wir das schon mal hatten und ich glaube, das war tatsächlich in der ersten Sendung,

wo ich halt auch meinte, so eigentlich diesen Fall, dass man beides hat,

dass man Concurrency braucht und Parallelität,

den hat man fast nie, also oder mir fällt es schwer,

mir dafür einen Use Case auszudenken. Die anderen

Fälle hat man, dass man viel Concurrency braucht,

hat man, dass man viel Parallelität braucht, hat man,

aber beides zusammen

Ja, also ich habe mir viele Sachen vorgestellt

Autonomes Fahren

oder Sport

und gleichzeitig fahren bestimmte Menschen

übers Eis oder sowas

und da musst du prognostizieren

was dann passiert, das ist echt parallel

für jeden Einzelnen

Ja, aber das ist nicht konkurrent

Du machst das Auto fahren gleichzeitig

Nein, das fahren alle gleichzeitig

und alle müssen gleichzeitig darauf reagieren

und du möchtest ja für alle gleichzeitig irgendwie Werte haben

und möchtest dann das ganze Team

Das verstehe ich nicht, tut mir leid

Also du hast mehrere Fahrzeuge

Du hast mehrere Fahrzeuge

Du hast so einen Rechner, auf dem mehrere Fahrzeuge fahren, das verstehe ich nicht

Genau, du hast die ganze Flotte, die du steuerst

Ja, aber die sind ja unabhängig

Also ich würde sagen, das ist ein Anwendungsfall

Aber du hast ein gegnerisches Team

und das ist halt nicht unter deiner Kontrolle

und du möchtest dann trotzdem alle deine Leute,

deren Informationen du dann halt gerade erst

live einlesen kannst

dazu bringen, dass sie parallel

die Entscheidung treffen

die vernünftig

statistisch wahrscheinlich ja

zu besseren Ergebnismöglichkeiten irgendwie so.

Der Dominik überspringt so die simplen

Schritte.

Also, der macht direkt komplett.

Ne, tu mir leid.

Das ist kein Newscase.

Vielleicht doch.

Der wüsste ich jetzt auch nicht.

Ne, aber wir können ja direkt mal

zu einem super guten Newscase zurückgehen

und der heißt Eve Online.

Da sind ganz viele Spieler, die gleichzeitig

Sachen machen wollen und du hast aber

trotzdem die große Statustabelle auf dem Server,

die du die ganze Zeit aktualisieren musst.

und das musste parallel machen.

Also ich meine, die Lösung, die EVE Online dafür hat, ist halt,

dass sie es langsamer machen.

Habt ihr EVE Online mal gespielt?

Nein, nur ganz viel drüber gelesen.

Ich habe es tatsächlich auch mal ausprobiert.

Ich muss gestehen, ich war nicht in dem Boot.

Das habe ich auch nicht geschafft.

Aber es gab tatsächlich tolle Schlachten.

Man hat dann so Schlachten gehabt, wo dann so 20.000, 30.000 Schiffe verloren gegangen sind.

Und man konnte da ein Business draus machen,

weil da konnte man die Schiffe kaufen.

Das war richtig Geld, was da vernichtet wurde.

Ich glaube, in der größten Schlacht wurden mehrere Millionen Dollar

an WTLM-Kapital vernichtet gleichzeitig,

weil man irgendwelche Sprungtore blockiert hat

mit riesigen Flotten an Schiffen

und alles in die Luft gesprengt hat, was dann ja nie

zu finden war. Ja, das ist das Geschäftsmodell von

EVE Online, oder? Ja.

Du kannst aber in diesem Spiel

echt Gelddinger generieren, die du halt

verkauft hast und wenn du halt ein Wirtschaftsunternehmen

Imperium in diesem Spiel aufgebaut hast, es gab eine Leute,

ich glaube, die haben über 20.000 Dollar

oder sowas im Monat gemacht, indem die für EVE Online

Businesses gebaut haben, die sie

da durch die Dachen

geschleust haben und wenn du dann halt sowas gemacht hast, wie

einen Krieg zu organisieren zwischen den einzelnen Fraktionen,

sich gegen das in die Luft sprengen und das halt alles auf dieser

spielerischen Karte, ohne dass das reale Auswirkungen hätte,

außer wirtschaftliche, für die Jungs,

die da vor dem Rechner saßen,

dann war das schon irgendwie sehr faszinierende

Geschichte, die da irgendwie losging.

Aber guck mal, Jochen, das ist doch ein perfektes Beispiel.

Du hast ganz viele Spiele, die gleichzeitig Sachen machen

wollen und du musst aber

diese Statustabelle, das ist parallel.

Ja, also ich würde sagen,

ich bin nicht so der Spiele-Experte, insofern

keine Ahnung, aber ich würde jetzt mal

und sagen, Spiele, die sind alle nur

concurrent. Da brauchst du nix.

Wenn ich jetzt so gegenseitig spiele,

ein ganz klassisches Killerspiel, ja, und wir schießen beide

gleichzeitig aufeinander.

Wo brauchen die Spiele denn bitte CPU?

Die brauchen eine offene CPU.

Die Spiele

heutzutage laufen nicht mehr auf dem Client,

sondern die laufen komplett auf dem Server.

Ja, selbst wenn die komplett auf dem Server laufen, wo brauchen die denn CPU?

Diese vorher

genannte Battle, die der

Dominik genannt hat, wo dann 30.000 Leute

teilnehmen. Der Trick an der Sache, warum

das funktioniert, ist, dass die den Timestep

runterdrehen. Das heißt, in so einer Zone,

wo viele Leute gleichzeitig

sind, die müssen

auf einem Server sein, damit diese Zone kohärent ist.

Wenn da

zu viele Leute sind, dann

tun die so, als ob die Zeit langsamer läuft.

Weil der Rechner ausgelastet

ist. Und wenn die diese

Status-Updates parallel

arbeiten könnten, auf einem Rechner,

dann müssten sie das nicht machen.

Die gehen ganz, ganz hart

ans Limit, weil die Simulation

auf dem Server passiert.

Zum Teil passiert die Physik-Simulation

auf dem Server.

Das ist im Wesentlichen der Grund.

Man hört ganz oft, dass

so und so viele Millionen Leute gleichzeitig in Fortnite sind.

Aber das stimmt nicht. Es sind nur

höchstens 50 auf einer Instanz.

Jetzt gab es

so Events, wo 10 Millionen Leute bei so einem

Konzert dabei waren. Das ist

ein kleines bisschen gelogen. Das waren 250.000

Instanzen mit jeweils

maximal 50 Leuten, weil da einfach

die Auslastung

ist der Prozessor voll.

Und da ist

Parallelität einfach

da.

Je mehr Parallelität du nutzen kannst, umso höher

kannst du diese Zahl setzen.

Umso weniger Instanzen brauchst du.

Da ist Geld drin und da ist richtig...

Vielleicht weiß ich einfach noch nicht gut genug,

wie Spiele funktionieren, dass ich mir

gar nicht so richtig vorstellen kann, warum die jetzt CPU brauchen.

Die Frage ist halt, wo ist der Flaschenhals?

Der Flaschenhals heißt, das ist CPU, das ist dann sowas wie Netzwerk.

Ich glaube eher Concurrency und Netzwerk.

Da müsste man Peer-to-Peer vielleicht machen, das würde vielleicht schneller gehen,

über Peace verteilt, als dass man irgendwie alles durch einen Hals schickt.

Bei allen Leuten irgendwie so ein bisschen...

Da gibt es sicher viele Flaschenhälse.

Ich glaube, da ist alles...

Das ist so ein blödes Problem.

Wenn du ein Problem gelöst hast, dann kommt direkt das nächste.

Wenn du einen Kopf abgeschlagen hast, wachsen direkt vier neuere.

Okay.

Aber CPU ist da einfach einer der Faktoren.

Vielleicht ist es bei Spielen so.

Ich kann es noch nicht so richtig nachvollziehen, aber okay.

Also ich meine, mir fällt auch ein Beispiel ein

und das sind halt Datenbanken.

Da hast du nämlich auch beides.

Da hast du halt sowohl I.O.

und Jochen unterhalten sich über die Programmiersprache Python

Na klar. Also außer du kodierstststststststststststststststststststststststststststststststst

auf dem Server und dann bist du ganz knallhart.

Ja, aber da würde ich sagen,

da bist du doch sowieso schon, da ist der Flaschenhals auch

wieder woanders, weil dadurch,

dass die einzelnen

Clients, die du dran hast, so fett sind,

macht es doch überhaupt nichts,

wenn du pro Verbindung dann halt was Fettes aufmachst,

wie ein Prozess oder so.

Ja klar, aber du hast auf jeden Fall Parallelität.

Ja gut, aber dann hast du halt diese 8 Streams.

Das ist auch bei dem Spiel, wenn du sagst, es gehen nur

50 Leute auf eine Instanz oder es gehen nur

50 Streams über einen Rechner, dann machst du halt

für die 50 Prozesse auf, gar kein Problem.

geht das auch mit Python. Ja klar, aber das ist dann

schon Parallelität, also du machst schon

viele Sachen gleichzeitig.

Ja, aber ein Fall, nach dem ich suche, ist,

wo du ganz, ganz viel Concurrency

hast, so viel, dass du das mit Prozessen nicht

erschlagen kannst, weil es zu viele sind.

Also sagen wir mal, du hast 10.000 Verbindungen gleichzeitig.

Aber das kannst du ja bei einem Web-Server

locker mal haben. Ja, natürlich, genau.

Also du hast 10.000 gleichzeitig, die auch gleichzeitig aktiv

sind. Nicht nur einfach eine Verbindung, die rumliegt,

sondern tatsächlich aktiv, über die irgendwas drüber geht.

Wenn du Testprobleme hast,

plus irgendwie CPU, dann kannst du es vergessen.

Dann kriegst du es mit Python nicht mehr hin, weil Prozesse kannst du dann nicht mehr nehmen.

Ich glaube, du hast das ausprobiert.

Hast du mal so eine Story erzählt auf deinem Mac

und hast da keine Panik verursacht. Kann das sein?

Ja, das habe ich jetzt genau.

Aber das waren Threads tatsächlich, keine Prozesse.

Also mit Prozessen würde das gar nicht gehen.

10.000 Prozesse ist nicht möglich.

Aber Threads sollten eigentlich möglich sein.

Nicht auf dem Mac.

Und ich habe es tatsächlich dann auch mal auf einem anderen ausprobiert,

um auszuschließen, dass irgendwie meine Hardware leicht defekt ist oder so.

auf Catalina macht das halt sofort

Kernelpanic, wenn man 10.000 Threads aufmacht.

Also die Lüfter gingen kurz an

und dann ist der Rechner aus.

Ich habe da tatsächlich auch einen Bug bei Apple aufgemacht.

Das geht ja so nicht.

Ja gut, aber ich meine,

wenn man da in die Ecken und Kanten geht,

ich habe auch schon mal mein Mac mit einem

Programm abgeschützt, was nur

das Clipboard ausgelesen hat.

Ja, es ist

ein großes

Kartenhaus.

ein großes Kartenhaus

ja, tatsächlich

ich habe es dann jetzt auch nochmal auf Linux probiert und so

und da geht es problemlos, gar kein Ding

ja gut, aber so eine Situation

wurde 10.000

also ich meine, dieses

berühmte C10K Problem

wie schaffst du es, einen Web-Server

zu machen, der 10.000 Clients

gleichzeitig benutzen, bedienen kann

wenn du das

hinkriegst, ist es besser

weil dann hast du weniger Web-Server

Aber dafür würde ich sagen, brauchst du eben keine CPU, sondern das ist rein Concurrency und das geht problemlos mit einem Prozess.

Aber ich finde bestimmt irgendeine Workload, wo du noch was berechnen musst.

Ich glaube auch, dass es sowas tatsächlich gibt.

Aber es ist so einfach, dass man sagt, ich kenne das ja dann immer so, dass Leute sagen, das ist ja gar keine richtige Programmiersprache.

Aber ich meine, wer hat solche Probleme?

Ich hatte sowas ehrlich gesagt noch nie.

Und ich habe schon eine Menge Zwochs gesehen.

also

bei mir war es entweder

vielleicht ist es einfach so

ich glaube da ist so ein bisschen Selection Bias

auch drin, oder? Gut, kann auch sein, ja

wir haben auch schon viele Sachen gesehen, aber wir sind halt

in Python unterwegs, wir sehen nur solche Sachen, die es in Python gibt

ja, ja, ja

das mag sein, das kann durchaus

ja, ja gut, wie auch immer

wie auch immer, aber genau

dieses Parallelität Ding, also wenn man beides braucht

ist halt schlecht, das ist nach wie vor nicht gut in Python

aber sagen wir mal so

dieser Concurrency Use Case

für den es ja tatsächlich auch Anwendungen gibt und

ich meine Node.js ist einer der Gründe, warum Node.js

so populär ist, ist halt

dass es damit besser

ging

oder dafür halt besser benutzt wurde,

besser benutzbar war

und ja.

Ja, auch ein besseres Programmiermodell hat,

oder? Also dieses

Promisers

und Futures und so weiter, das

ist schon sehr einfach.

Ja, aber das ist eigentlich alles, sozusagen

das gibt es halt in Python ja auch

Ja

Was gibt es denn da?

Kannst du das kurz beschreiben?

Ja, also gut, okay

Also wenn wir jetzt schon

im Grunde wissen, okay, wir wollen das

eigentlich schon haben und das ist schon cool und das kann ja

wohl nicht sein, dass ich jetzt Node.js lernen muss, nur

irgendwie um immer noch

hip zu sein

dann kann man sich ja

genau, kann man so, okay, wie macht Node.js das denn

eigentlich, weil Node.js hat

die gleichen Beschränkungen im Grunde, es ist sehr vergleichbar zu

zu Python, hat die gleichen Beschränkungen.

Da gibt es auch in GIL

ganz genauso wie in Ruby on Rails

und sonst irgendwie in PHP.

Die ganzen Skriptsprachen machen das ja alle.

Die machen das alle so, weil es halt auch sinnvoll ist.

Ja, und weil es halt auch

single-threaded die Performance, also wenn du

kein Multiprocessing brauchst, also wenn du

keine Parallelität brauchst und keine

Concurrency, dann ist es halt das Schnellste.

Ja, genau. Und was

Node.js macht, ist halt,

sie haben halt eine Event-Loop und

und dann kann man halt sozusagen Callbacks auf dieser Event-Loop,

oder sagen wir mal so, das ist halt das, was ganz früher schon immer,

ich glaube, das ist schon immer möglich, man kann halt Callbacks auf dieser Event-Loop registrieren, oder?

Ja, Callbacks sind ja was Schreckliches, das ist doch die Callback-Hell.

Genau, ja.

Gar keine lineare Programmierung mehr.

Hast du was gesagt? Hatte ich irgendwas gesagt?

Vielleicht gab es irgendjemand, der hat was gesagt, der wollte, er wartet noch auf irgendwas.

Wie heißt denn das? Wie muss ich dann da fragen, wenn ich das wissen will?

Ach Moment, da steht jemand, der hat da rumgegangen.

Ach nee, da war doch jemand anders. Ach Moment,

da war doch jemand, der hat aber was gesagt.

Ach Callback, achso da hinten, ach nee, da unten.

A, O. Das ist ja gar nicht so schlimm.

Diese Vermischung kriegst du ja immer. Das Problem ist,

dass dein Programm dann auch so aussieht, weil

du die Callbacks quasi in der falschen

Reihenfolge definieren musst.

Du kannst nicht sagen, erst A, dann B, dann C,

sondern du musst erst sagen, erst A und wenn

es erfolgreich ist, dann B, ansonsten

C und wenn B erfolgreich ist, dann

zwischendurch D und E und dann hast du

A, B, E, F und

C kommt dann irgendwo ganz anders.

Das heißt, du kannst dein Programm nicht mehr von oben nach unten lesen, sondern du musst es so gemixt lesen. Und das ist ganz, ganz, ganz blöd zu programmieren. Und deshalb hat JavaScript dann irgendwann diese Promises and Futures eingeführt, wo du einfach sagen kannst, da kommt jetzt was zurück, was irgendwann fertig ist. Und sobald du es benutzt, musst du halt warten.

Ja, kann man

in Python

gibt es das halt quasi ganz genauso

also seit 3.2

gibt es concurrent

Futures

Ich weiß nicht, ob sich

JavaScript das Promises-Konzept

da so ein bisschen abgeguckt hat, also Python hat sich das

abgeguckt aus der Java-Welt tatsächlich

wo es dieses Future-Konzept wohl schon länger gibt

Aber in Java nimmt man doch viel eher Threads, oder?

Ja, aber man kann

auch das machen.

Aber sagen wir so, wenn wir jetzt schon bei den Callbacks sind

oder bei

dieser Art, das kann man halt in Python

im Grunde auch

so machen.

Das ist auch in dem Async-Teil,

man muss das wahrscheinlich

alles ein bisschen voneinander unterscheiden.

Es gibt ein riesiges Glossar machen.

Ja, genau, wie das unten drunter aussieht,

was man unten drunter für einen Mechanismus verwendet, um halt

Concurrency zu erreichen

und was man dann für Abstraktionen

darüber verwendet, weil tatsächlich

in Async.io jetzt sozusagen die

aktuell

in der Standardbibliothek befindliche

Lösungen für diese Conferency-Geschichte

ist halt... Ja, sogar in der Sprache,

oder? Ist nicht in der Bibliothek, sondern ist

richtig in die Sprache integriert mit den

Schlüsselwörtern. Ja, aber das ist

auch eine gute Sache, dass es

voneinander getrennt. Also was in der Sprache

tatsächlich drin ist, sind

halt Async-Funktionen.

Also wie man halt mit Async-Def

genau und Await. Mit diesen

Schlüsselwörtern kann man

da operieren, aber

in der Sprache ist nur definiert, dass diese

Geschichten dann, wenn du sie aufrufst, halt eine

Kurroutine zurückgeben.

Es ist nicht gesagt, wie das jetzt alles sonst

funktionieren muss. Der Rest ist halt...

Ja, okay, klar, die Event-Loop und so weiter.

Du kannst halt

Async-Def und Await auch in Trio verwenden

und Trio verwendet ein ganz anderes Modell unten drunter als

jetzt Async-Trio.

Das ist eine

Implementierung,

sowas ähnliches wie AsyncIO, bloß

mit einer etwas

moderneren, etwas anderen Zielsetzung. Also es gibt

diverse. Es gibt AsyncIO,

ist in der Standardbibliothek. Es gibt

Curio, das ist das von

David Beasley.

Ist halt sozusagen erst ab Python 3.7

und irgendwie so ein bisschen

advancer.

Und dann gibt es nochmal die advancer

Version von Nathaniel Smith

im Trio.

Und das Ding macht

im Grunde sowas ähnliches, aber halt

und anders. Also die Art, wie man es programmiert, ist halt anders.

Und benutzt aber Async-Dev kann man in all diesen Dingern verwenden,

weil das halt nur sagt, okay, wenn ich eine Async-Funktion habe,

dann gibt die halt eine Core-Routine zurück und ich kann jetzt damit irgendwas machen.

Aber wie das Programmiermodell aussieht, was ich dann mit diesen Core-Routinen mache, das ist ja demjenigen,

der das sozusagen, dieses Framework implementiert, überlassen. Und da gibt es

unterschiedliche Ansätze. Und im Grunde Trio

ist so ein bisschen das zu Ende gedacht,

dass das halt so ein Problem ist. Also das

wurde ja auch schon angedeutet mit dieser Kohlberg-Hell-Geschichte.

Also das grundsätzliche

Problem, was auch der Autor von Trio da

identifiziert hat, also

ich packe da auch mal einen Artikel, wo man das

in Detail nachlesen kann in die Shownotes,

dass er sagt, das ist alles, also

ein großer Teil der Probleme, die wir hier

sehen, sind die gleichen Probleme,

die Leute früher mit Gotoh hatten.

Oder er sagt,

das ist halt eine sehr gute Analogie dafür.

Wir sind in der Assembler-Welt angekommen, wenn wir über Gotoh

sprechen? Ja, äh, nee, nicht ganz

Assembler. Ganz viele Sprachen, die Gotoh haben.

Ja.

Also, äh, ja, also, ähm,

das Problem bei Gotoh ist halt irgendwie,

dass es dir, das ist nicht,

das ist, was das unmöglich macht, ist halt

lokal über Code nachzudenken.

Weil du weißt halt nicht, also, er hat dann halt

so ein schönes Diagramm, wo man halt, äh,

er macht halt immer, er geht von einem Gotoh zu einer

Zeile und dann, er macht das halt immer weiter,

bis du halt siehst, das ist ein riesiges Spaghetti, ein riesiges Spaghetti-Kneuel.

Das heißt, du weißt halt

nie genau, ähm,

wie du eigentlich hingekommen bist

und wo es hingeht

und zum Beispiel kannst du halt keine Facebacks

werfen, weil du weißt überhaupt nicht, wo du herkommst eigentlich

und das ist halt

relativ schrecklich

du musst halt dann das Programm immer komplett

verstehen, ansonsten

kannst du nicht sagen, was da gerade passiert, weil

es keine lokalen Blöcke

gibt, die

irgendwie, wo man sagt, okay, ich habe jetzt ungefähr verstanden

was das Ding tut

das muss ich jetzt nicht noch

also ich brauche nur zu wissen, wie die Abstraktion

davon ist und das reicht mir, um damit arbeiten

zu können. Also zum Beispiel irgendwie sowas wie

Print Hello World. Print

macht intern was relativ kompliziertes.

Das macht irgendwie

Syscalls, das macht irgendwie alle möglichen

komischen Dinge, die halt dann so zu tun sind, wenn man

irgendwie, wenn dann was

auf der Konsole erscheinen soll.

Aber das

muss man alles nicht wissen, sondern man ruft das einfach auf

und das geht. Und Funktionen sind

halt super, weil genau die

brauchst du ja eigentlich nur zu merken, was das Ding tut, aber wie

und Jochen unterhalten sich über die Programmiersprache Python

Ende der 60er, Anfang der 70er

Dijkstra und so, da gab es halt den berühmten Artikel,

die haben sich da Gedanken gemacht

und deren Vorschlag war halt,

ja, Guto rauswerfen,

verbannen, irgendwie ächten

und stattdessen sowas verwenden

wie Funktionen und Blöcke und so.

Und das hat sich durchgesetzt

und auch lustig,

die Gegenargumente damals

und auch Knut hat zum Beispiel gesagt,

oh nö, ich finde Guto eigentlich ganz gut,

auch sehr interessant.

Knut?

Ja.

Don't Include.

Ah, war das nicht der, der

sowas gesagt hat wie, premature optimization

is the root of all evil?

Genau, genau der.

Aber dieses Zitat ist mit sehr viel

Vorsicht zu genießen. Er hat auch gesagt, wenn man 3%

rausholen kann, dann ist es nicht mehr premature.

Jaja, das war...

Ach ja, andere Zeiten.

Ja, jedenfalls.

Genau, der war da auch nicht unbedingt

so totaler Fan von Gotoh rausschmeißen, weil

und eine Frage im Moment war halt so, ja, das bedeutet ja,

wir müssen ganz anders programmieren lernen.

Wir haben jetzt über Jahre irgendwie

haben wir uns

auf ein Level begeben,

dass wir damit irgendwie jetzt klarkommen und

haben uns so Methoden angewöhnt, wie man damit umgeht

und wenn wir das jetzt so ändern,

dann müssen wir im Grunde nochmal neu

programmieren lernen und ja, das ist so.

Ja, und vielleicht wird es

dann sogar langsamer, weil eben diese

Funktionsaufrufe und diese ganzen Strukturmechanismen,

die brauchen ja auch Rechenzeit.

Ja, natürlich. Und Speicherplatz.

und wenn du nochmal 3% irgendwo rausholen kannst,

dann kannst du das auch machen.

Und wenn der Mainframe super teuer ist

und Arbeitskraft super beliebt,

dann macht es vielleicht sogar Sinn.

Aber heute...

Ja, das ist halt...

Wir stehen auf den Schultern von Riesen.

Wir haben heute genügend Prozessoren.

Wir haben genügend Megahertz,

dass wir uns das leisten können.

Ja, und im Grunde,

er sagt halt,

bei Concurrent

Programmierung hat man im Grunde in gewisser Weise das gleiche Modell und

er sagt zum Beispiel, Futures findet ja ganz schrecklich, weil die

im Grunde das gleiche Problem haben wie Gotoh, weil du kriegst halt was zurück, also du rufst eine Funktion auf,

du kriegst was zurück, aber du bist ja gar nicht, es ist ja gar nicht

linear zurück, dein Code geht ja nicht linear weiter, sondern irgendwo

anders passiert irgendwas, das aber durchaus Auswirkungen darauf haben kann,

was später in dem Code, der dann jetzt sozusagen von dir ausgesehen weiterläuft,

drauf ausgeguckt hat.

Das heißt, du musst wissen, okay,

der Task, der da noch läuft, der wird später mal

irgendwas Böses machen oder vielleicht noch irgendwie

keine Ahnung. Und da muss ich auf jeden Fall dran denken,

dass der mir vielleicht irgendwie dazwischen gratscht

oder ich muss hier mal ein Lock setzen, damit das irgendwie

atomar bleibt und keine Ahnung.

Das heißt, ich kann

nicht mehr sagen, okay, ich habe jetzt

diese Funktion aufgerufen, es ist gut,

ich weiß jetzt Bescheid,

es hat funktioniert oder nicht und ich mache jetzt weiter.

Sondern, ja, ich habe dieses

Future-Ding in der Hand, aber

tatsächlich muss ich mir irgendwie selber merken,

was da noch alles passieren kann.

Und das ist natürlich schlecht, weil es macht halt genau

diese lokale

Nachdenken über Code

kaputt. Und er sagt halt so, alle

Concurrency-Lösungen, die dazu

führen, dass man nicht mehr lokal über Code nachdenken kann,

das ist alles

nicht richtig. Das sollte man so

nicht machen. Ja, was ist da die Lösung

jetzt davon? Ja, also er hat da

so ein Konzept,

das heißt da irgendwie

Nurseries.

Nurseries, die kleine Krankenschwester,

die die Babys auf der Aufsatzstation ist.

Genau, er sagt so, ja, so Tars

oder sind so wie so kleine Kinder,

die darf man nicht einfach so frei rumlaufen lassen,

das ist nicht gut.

Die muss man irgendwo einsperren, wo sie dann

gepflegt werden.

Wo sich jemand drum kümmert.

Die dürfen aber nicht raus.

Ja, genau. Und das Ganze ist in so einem

Context Manager drin und tatsächlich, also

ich habe noch nicht so viel damit rumgespielt, also es sah gut aus,

auf Ja angeblich ist das wohl eine M das so hinzukriegen dass man weiterhin lokal Sachen nachdenken kann und dieses Problem dass man Spalter hat gar nicht mehr bekommt

Und es ist sogar teilweise einfacher, Sachen damit umzusetzen. Es gibt ja diesen für IP Happy Eyeballs-Algorithmus, der auch in Twisted drin ist.

und es gibt eine Twisted-Implementierung, die ist

120 Zeilen und relativ fies

und es gibt eine in Trio und die

ist halt irgendwie, weiß ich nicht,

also ich meine, obwohl Zeilenvergleich ist auch wieder ein bisschen

Quatsch, aber also viel, viel

weniger und viel klarer.

Und als er das Ding in Trio nachgeschrieben hat, hat er auch

diverse logische Fehler in der

Twisted-Implementation gefunden,

weil das einfach super schwierig ist, das

so hinzukriegen mit den Futures.

Also in Trio gibt es keine Futures

mehr, es ist halt eher so,

es gibt diese Nurseries und

und ja, es wurde auch schon

darüber nachgedacht, ob das nicht vielleicht eine gute

Geschichte wäre, das in

Python direkt einzubauen

und statt AsyncIO zum Beispiel

zu verwenden, aber das ist

alles noch gerade so dabei,

quasi noch nicht

Der Zug ist nicht schon längst abgefahren, weil

der ist ja jetzt schon drin in Python

Ja, vielleicht ist er das schon,

viele Leute verwenden

AsyncIO, als dass man das noch

vielleicht ändern könnte und es gibt halt da

diesen Ökosystem-Split und

und ja, wahrscheinlich ist es besser dann eben

auf das zu versetzen, was eh dabei ist.

Also Trio macht ja sowas, du hast jetzt gesagt

Kontextmanager, das heißt man muss diesen lokalen

Scope nicht verlassen. Ist das nicht eigentlich das, was

Funktionen tun, sowieso schon?

Ja, ja, aber Funktionen funktioniert halt nicht so richtig.

Weil?

Die Tats laufen ja weiter.

Das ist halt

auch bei Asso, wenn du halt eine Funktion

wenn du Concurrence irgendwas machst,

dann hört das halt nicht in dem Moment auf,

wo du das aufgerufen hast, sondern das läuft halt unter

Umständen weiter. Das heißt, ich habe beispielsweise nur den halben Whisky

eingeschenkt und die andere Hälfte, die kommt aber noch. Ja, genau. Aber woanders fängt der halt an,

dann schon andere Limetten reinzubekommen.

Und was ist der Unterschied in Trio? Da macht er dann trotzdem erst

den einen Schritt fertig? Oder wieso ist das so isoliert? Also vielleicht

bei diesem Barkeeper-Beispiel das so anschaulich hinzubekommen? Ich weiß nicht, ob ich das

tatsächlich hinkriege. Also muss man sich selber angucken. Da gibt es auch

Schaubilder auf der Seite, aber das zu erklären,

weiß ich nicht, ob das...

Das ist so ein bisschen das Problem, das generelle Problem

an Concurrent Programming, oder? Dass diese Sachen alle

gleich so kompliziert werden, dass man dann

diverse Schaubilder braucht und

Leute dann irgendwann sagen, ja, lass lieber

die Finger davon, das ist nicht so.

Ja, und tatsächlich ist das vielleicht gar keine so schlechte...

Ich würde auch sagen, also auch meine Erfahrungen, die ich damit

so bisher gesammelt habe, die waren alle immer...

Es war immer ziemlich fies. Also das war immer...

Also die

Beispiele, die haben immer funktioniert,

wenn man sich irgendwie so Tutorials oder so anguckt.

Wenn man es dann tatsächlich ausprobiert mit irgendwie

in den Fällen, wo man es dann halt wirklich braucht,

wo man dann viel Last macht,

dann sind mir jedes Mal

passieren komische Sachen

und das Debugging ist jedes Mal

Das ist so bei Google, da passieren immer komische Sachen.

Ja, also wirklich, also

zum Beispiel einen Bug,

da habe ich jetzt noch, und diese

Geschichten, ich meine, das passiert anderen Leuten auch.

Zum Beispiel der

Gründer von,

der ursprüngliche Entwickler von Twisted

hat einen langen Artikel darüber geschrieben, warum man Multithreading

hasst, wo er dann

geschrieben hat, sie hatten also Probleme

und sie hatten dieses

sie hatten einen wirklich fiesen Bug in ihrem

größeren System und

der ist halt irgendwie nur ab und zu

aufgetreten, sie haben es überhaupt niemals reproduzieren

können und sie sind es nicht losgeworden

und sie haben alles from scratch

nochmal neu geschrieben, reimplementiert

um den Bug wegzukriegen, weil sie ihn einfach

über Monate nicht finden konnten

und das ist eigentlich schon echt bitter

und es ist auch super schwer zu testen

so Zeug, das ist auch super schwer zu sagen

wenn ich X mache und Y, dann passiert

Z, sondern es ist halt, wenn 37

Leute gleichzeitig X machen und einer von denen

aber Z macht und einer von denen Y

und 23 A

und B, dann passiert

irgendwas

Buchstabensuppe

dann passiert Buchstabensuppe und das ist ein Bug

ja, was ich da mal hatte

war halt, genau, ich hab halt

so ein Webcrawler-artiges geschrieben

und

mit ein paar tausend Seiten und weiß ich nicht, so

100 Seiten

gleichzeitig abfragen pro Sekunde oder so, alles gar kein Problem.

Also okay, gehen wir auf eine halbe

Million oder eine Million und machen das mal so

irgendwie ordentlich so mit ein paar tausend pro Sekunde.

Und dann passieren plötzlich

seltsame Geschichten.

Irgendwie sterben plötzlich Sachen

oder was ich dann hatte, es wird plötzlich

irgendwie seltsam langsamer.

Man weiß nicht warum. Plötzlich

kriegt man ganz eigenartige

Tracebacks aus den Tiefen von Python.

also was ich dann irgendwie

rausgefunden habe,

das war halt irgendwie die Resolver-Library

auf meinem Mac, ich habe es auf dem Mac probiert,

die hat halt irgendwie angefangen plötzlich Probleme

zu machen und

zum Glück auf Linux ging es dann, das ist auch immer

sowas, ja Mac gibt es dann

vielleicht für Smoketest gar nicht so

schlecht, der macht dann irgendwie

ein bisschen früher irgendwie, fängt an zu rauchen

dann heißt das schon, so bei Linux

gehen dann viele Sachen, wo der Mac dann schon raucht

aber also das war

und da habe ich auch lange dran rumgedebuggt und nichts gefunden

und das ist ganz schrecklich.

Ja,

Load macht Dinge kaputt,

die schwer

zu finden sind und schwer zu sehen sind.

Und

die dann auch nur so sporadisch auftauchen.

Da wird es dann auf einmal statistisch, wenn du sagst, okay,

mein Programm geht in 99%

der

Abläufe. Das ist dann der echte Bug.

Das ist dann wie, dass in der Schaltung irgendwo ein Käfer reingeklettert

ist, weil die Schaltung so groß ist, dass

da irgendein Käfer dazwischen passt und du weißt aber nicht,

Wenn halt der DNS-Resolver nur 99%

aller Anfragen korrekt beantwortet und

in einem Prozent der Anfragen halt abstürzt oder

irgendeinen Quatsch macht, dann

hast du halt so statistische Dinge. Aber das ist natürlich

sehr unbefriedigend, weil ja eigentlich

also als

Softwareentwickler oder als Informatiker ist man

ja gewöhnt, dass wenn es geht, dass es dann zu 100%

geht und immer.

Und nicht eben...

Ein anderes Beispiel, eben Lukas Langer, der hat

ja bei Facebook gearbeitet und hat dann auch so ein

Beispiel für, sie hatten halt irgendwie ein Ding,

was halt auch Async.io gemacht hat

und dann haben sie da auch Durchsatz

wenn es anfing so richtig Durchsatz

zu machen, wurde es plötzlich

irgendwie magisch langsamer

und sie haben dann

auf ihre Kurven geguckt und sie haben es nicht verstanden

und dann bis dann irgendwann jemandem aufgefallen ist

oh, wo kommen

eigentlich diese Kurven her?

Es gibt da halt noch einen Thread, der guckt sich

halt an, was die anderen Threads so machen

und was die anderen Tasks so machen

und der hatte halt in der Art, wie er

dann halt die Ergebnisse von dem, was er gesehen hat,

wie er sammelt hat, irgendwie so einen naiven

Algorithmus drin, der mit der Last nicht gut

klargekommen ist, der dann halt

schnell langsamer geworden ist und der wurde

dann so langsam, dass er alles andere aufgehalten hat.

Und da ist dann sozusagen die CPU rausgelegt.

Ja, also, aber das sind

alles so ganz ekelhafte Probleme.

Wenn man das nicht braucht, sollte man

das nicht machen, glaube ich.

Ja, oder halt

sich möglichst weit davon fernhalten.

Also ich meine, wir sind ja Django-Entwickler

und wir haben das ja schon lange.

Wir haben ja schon lange Sachen, die

Concurrency sind, weil wir halt, wenn du irgendwo

was deployst, dann machst du halt 10 Unicorn-Prozesse

an oder so. Aber die

sind ja im Wesentlichen unabhängig voneinander.

Die

kommunizieren nur über die Datenbank.

Die Datenbank ist da das, was

die Concurrency macht oder was die

Datensätze hat. Dass die Datenprobleme löst,

dass das isoliert ist. Genau.

Da bin ich ganz froh, dass es eine gute Datenbank gibt.

Genau.

Wo ich einfach sagen kann, okay,

und Jochen unterhalten sich über die Programmiersprache Python

gar nicht, dass sie keine Kommunikation machen müssen. Dann kannst du sie auf verschiedenen

Rechnern ausführen. Dann kannst du sie skalieren.

Kannst du sie wegskalieren. Entweder über Prozesse oder über Prozessoren,

über unterschiedliche Maschinen oder über Docker-Container,

oder über einen Kubernetes-Cluster, wo du dann halt

im Prinzip das Gleiche an ganz vielen verschiedenen Stellen

ausführst. Das ist ein Modell.

Ja, aber nehmen wir jetzt mal den Fall, du willst jetzt eben sowas machen wie zum Beispiel, keine Ahnung, was mit Felix Elixier und Liveview geht, du hast halt eine Webseite und pushst den Leuten quasi reaktiv irgendwie Dinge in den DOM und du hast dann natürlich eine Websocket-Connection zu jedem Client und das können ja dann Tausende sein oder Zehntausende, dann musst du all diese Verbindungen irgendwie handeln, musst damit was machen.

Wenn du jetzt dieses klassische Worker-Modell

mit Unicorn machst, das geht auch,

dann hast du aber irgendwie einen Haufen

Verbindungen und brauchst einen Haufen Server.

Wahrscheinlich kannst du das auch

mit einem machen. Ja, da würde ich

mir einfach wünschen, dass es sozusagen so eine

Verbindungsdatenbank

gibt,

die dieses schwierige Problem

wegabstrahiert, aber ich glaube, da gibt es noch nichts.

Ja, aber tatsächlich

mit Django 3.1

Async Views geht das tatsächlich.

Also ich meine, man kann auch einfach was anderes nehmen.

also womit man das schon länger machen kann

ist wahrscheinlich sowas wie man Starlet

nimmt oder so oder irgendwas

in der Richtung. Ja, aber die nehmen ja auch alle

AsyncIO, also die machen ja auch keine Magie.

Genau, genau, genau, aber da ging das halt

in Django ging es bisher halt noch nicht

also jetzt geht es halt dann halbwegs.

Was macht Django denn jetzt alles so schönes?

Genau, jetzt

kann es, also was neu

dazukommt sind AsyncViews

wo man

halt sozusagen als View tatsächlich

eine Funktion hat oder eben auch eine Klasse, wo man dann

halt die Call-Methode als async-dev markiert,

also async-Funktionen hat, die Views sind und

die dann Core-Routinen zurückgeben.

Und dafür muss das Interface, also das ist bei mir schon mit Django 3.0

passiert, das Interface zum Server, es muss möglich sein, was anderes zu benutzen als

BSGI. Und das, was man da verwendet, ist halt dann ASGI.

Und das kann halt beide Richtungen und

und ja, ist halt...

Also Web-Server-Gateway-Interface und Asynchronos

Ja, genau.

Ist sozusagen das

übertragen auf den Fall, den man jetzt halt dann hat.

Und genau,

kommt auch aus dem Channels-Projekt irgendwie.

Andrew Godwin hat das Ding halt auch in den Standard

irgendwie dafür sozusagen hauptsächlich

glaube ich irgendwie geschrieben.

Ist jetzt in der Version 2.0

oder sowas da und ist auch mehr oder weniger

fertig und wird auch von allen anderen quasi

so adaptiert. Also das hat sich wohl tatsächlich

mittlerweile eigentlich als Standard für solche

hat sich durchgesetzt

für, das ist halt der Standard, wie jetzt ein

Applikationsserver mit der Applikation irgendwie kommuniziert.

Und

genau.

Und was in Django

3.1 jetzt dazugekommen ist,

sind die

Views, das ging halt in 3.0 noch nicht.

Middlewares

und das war halt

auch einer der schwierigen Teile halt.

Das Problem ist, du musst halt

es hinkriegen. Also wenn eine synchrone Middleware dazwischen ist,

dann geht es halt schon eigentlich nicht mehr.

die ganzen Mittelbeurs-Async zu kriegen

und

auch Async-Tests

gehen halt auch.

Und damit ist halt tatsächlich schon mal was da,

womit man was machen kann. Ich meine,

tatsächlich, also die Wunschvorstellung, die ich an das Ganze

hätte, eigentlich ist da so, dass

alle Dinge, die jetzt I.O. machen

auf meinem Server, also normale Webseite,

kommt ein Request rein,

das Ding macht halt, irgendwie,

keine Ahnung, fünf Statements an

eine Datenbank, fragt irgendwie

ein Redis-Cache,

fragt noch irgendeine API oder sowas

und gibt dann irgendwie eine Antwort zurück

in dem View und momentan

ist es halt so, da wartet man dann halt

synchron auf jede einzelne Anfrage,

die man irgendwo hinstellt und alle Latenzen addieren

sich und

bis man das erste Byte am Client

empfängt, muss man halt diese ganzen

Netzwerk

Zeiten

abgewartet haben und

das kann halt sein, dass das dann irgendwann, wenn man

viele Statements macht oder wenn man viele APIs

fragt, dann wird das halt viel und man kann

im Grunde nichts tun, so wirklich.

Oder man muss es halt komplett selber machen. Das Framework

gibt einem da nichts an die Hand, womit man

das irgendwie verbessern kann.

Und sozusagen in einer goldenen

Zukunft wäre es halt

vielleicht so, dass man sagt, okay,

das wird alles async

zusammengesammelt. Alle Sachen, die

I.O. machen nach außen,

erwägtet man halt.

Und

die Latenz, die man

als Client, wenn man die Seite

abfragt, zu sehen bekommt,

ist die, die der

längste I.O.

Ding nach draußen braucht.

Aber alle anderen sind dann halt schon da.

Das heißt, es ist nicht mehr,

alle Latenzen addieren sich, sondern die Latenz, die man sieht,

ist die von dem längsten

Einzelteil, sozusagen.

Ja.

Aber ist das jetzt nicht

Parallelität?

Nö, das ist Concurrency.

Das ist alles immer nur...

Genau. Weil ich sehe da,

ich sehe echt einen ganz anderen Anwendungsfall für diese

Async-Views und Async-

Middlewares und so weiter.

Ich sehe halt, dass du

lange laufende

Views hast und nicht den

Worker

blockierst. Das heißt, du kannst derweil

andere Clients behandeln.

Das ist ja genau das,

was du bei WebSockets brauchst. Du hast ja im Wesentlichen

einen Request, der für immer läuft.

Oder solange wie der Client halt da ist.

Und zwischendurch kannst du aber was anderes machen.

und der kann prinzipiell ja dann auch mit anderen

Views kommunizieren.

Du hast dich gerade freiwillig

gemeldet, nochmal zu erklären, was WebSockets sind

und weil das kam heute

noch gar nicht dran.

Ja, WebSockets sind, also

da muss man ein kleines bisschen ausholen,

glaube ich, weil

das, was man so als Webseite kennt, ist,

das hat so ein Modell, das heißt Request Response.

Das heißt, du schickst eine Anfrage

hin und der Server

bearbeitet die und dann schickt irgendwann eine Antwort

zurück und dann ist das abgeschlossen.

Das ist alles, was da passiert.

Also das, was man da hinschickt, ist dann so eine Anfrage,

entweder will man irgendwie aus dem klassischen

Crudstream irgendwas machen, also lesen

oder schreiben oder updaten

oder löschen oder sowas und dann

bekommst du eine Antwort, die dann

irgendwie so einen Statuscode hat, den man vielleicht irgendwie so kennt.

Genau, das ist alles

Feinheiten, die da drin sind.

Dieser Request-Response-Zyklus ist einfach nur, ich schicke

dir eine Anfrage hin,

einen Arbeitsauftrag und der Server

bearbeitet diesen Arbeitsauftrag und schickt dann

das Ergebnis zurück. Und was da drin steht,

spielt erstmal keine Rolle. Das kann sein, gib mir die Homepage, das kann auch sein,

update alle Bilder in der Datenbank

und es kann auch sein, lösche alle

was weiß ich. Das spielt erstmal keine Rolle, sondern

das Wichtige ist, das ist eine abgeschlossene Welt.

Ich schicke eine Anfrage hin und die wird bearbeitet und dann

wird sie zurückgeschickt. Und wenn ich eine neue Anfrage hinschicke,

dann hat die mit der vorherigen erstmal gar nichts zu tun.

Man muss dann Tricks benutzen, damit

damit da sozusagen so eine Kohärenz da ist,

dass ich der eingeloggte Benutzer bin,

aber im Endeffekt sind das

alles Tricks, um einzelne

Request-Responses,

um einzelne solche Zyklen so zu machen,

dass die ausschauen, als ob sie zusammengehören.

Du meinst sowas wie Session oder sowas?

Genau, das mit Cookies,

wo du dann so eine Session-ID hast,

dann kannst du

simulieren, dass diese verschiedenen

Requests alle zusammengehören.

Aber im Endeffekt sind die alle unterschiedlich.

und Jochen unterhalten sich über die Programmiersprache Python

das abgeschlossen. Und wenn du danach

was Neues brauchst, schickst du eine neue Anfrage, kriegst du eine neue

Antwort zurück.

Bei WebSockets ist es anders. Bei WebSockets

machst du eine Verbindung

auf und diese Verbindung bleibt

dann bestehen.

Und du kannst dann über diese Verbindung

Daten an den Server schicken.

Der Server kann aber auch selbstständig Daten

an dich schicken.

Und das löst so ein Problem,

was man früher hatte, wenn

das klassische Beispiel ist eine Chat

Anwendung,

wo halt einer was in sein Chatfenster eintippt und die anderen sollen das dann sehen

und bei einem Request-Response-Mechanismus

heißt es, dass die halt die ganze Zeit fragen müssen, gibt es schon was Neues?

gibt es schon was Neues? gibt es schon was Neues? und der Server die ganze Zeit Nein sagt

und irgendwann sagt er halt Ja, weil da irgendjemand anderes was eingetippt hat

viel besser wäre es aber doch, wenn die alle sagen

ich bin jetzt hier und ich möchte gerne alle Nachrichten aus dem Chatraum hören

und sobald es eine neue Nachricht in diesem Chatraum gibt

sagt der Server allen angeschlossenen Clients

hier ist was Neues.

Dafür braucht man aber so eine bestehende Verbindung.

Das heißt, dafür kannst du nicht nur sagen

beantworte

mal die Anfrage, gibt es was Neues, sondern

da ist die Anfrage, informiere mich

sobald es was Neues gibt.

Man hat da früher ganz schlimme Technologien

gemacht. Man hat dann irgendwelche Long-Polling-Requests

gemacht oder irgendwelche Meteor-Sachen, die

die HTTP so ein bisschen

verbogen haben, um das eben

hinzukriegen.

Und hat dann irgendwann

Websocket zum Standard gemacht, was im Wesentlichen

das macht. Das ist eine

normale HTTP-Anfrage, die

dann upgegradet wird, damit die Verbindung

nicht geschlossen wird. Und diese Verbindung bleibt dann bestehen

und ist dann bidirektional. Das heißt,

der Client, der Browser kann Nachrichten

schicken. Es muss nicht unbedingt ein Browser sein, kann auch

was anderes sein. Und der Server kann aber auch

Nachrichten schicken. Und dadurch

wird eben so dieses

Modell, dieses Programmiermodell, was man

früher hatte, ein Request kommt rein,

erzeugt eine Response,

ausgehebelt, weil ein Request kommt rein, heißt, wir machen jetzt eine Verbindung auf

und danach können sehr viele Responses darüber gehen. Da können auch noch neue Requests

drüber kommen, weil jemand was in sein Chatfenster eingetippt hat und der

Client sagt dann, bitte veröffentliche das in diesem Kanal.

Das heißt, Websoft-Grips sind so ein bisschen die

Erweiterung, nicht eine Erweiterung,

sondern eine

eine Möglichkeit,

ruhere Netzwerkverbindungen

zu haben, länger bestehende Netzwerkverbindungen

zu haben,

aus normaler Browser-Hardware,

aus normaler Browser-Software aus.

Es gibt inzwischen auch ganz viele

andere Clients, die WebSockets verwenden.

Die meisten Native-Anwendungen

werden mit ihren

Servern über WebSockets kommunizieren,

weil das eben der Standard ist.

Wie macht man sowas in Tango?

In Django macht man sowas erstmal gar nicht.

Beziehungsweise jetzt in 3.1 kann man das eventuell machen.

Die Websocket-Verbindung muss vom Client aufgebaut werden.

Das heißt, der Client muss sich irgendwo anmelden und sagen,

ich möchte gerne einen Websocket haben.

Und dafür gab es eben in Django diese Erweiterung, die Channel-sized,

weil Django selber kann das nicht.

Django selber hat nur den Request-Response-Mechanismus.

Das ist sofort ersichtlich, wenn man die erste View-Funktion schreibt,

weil die eben einen Request kriegt.

und das ist genau der Request, der vom Browser geschickt wird.

Der sagt, mach mal bitte

folgendes.

Und das, was eine View-Funktion erzeugt, ist dann

eine Response und das ist genau der Abschluss

dieses, sobald die View-Funktion fertig ist, ist

die Verbindung weg.

Um da weiterzugehen,

um da Websockets machen zu können,

braucht man eben was anderes und das war früher Channels

und jetzt wandert das so langsam in Django

selbst rein. Wobei, also

das soll wohl nie tatsächlich nach Django reinkommen,

sondern Channels wird jetzt halt

das Ding zum Handeln von anderen

Protokollen, die nicht HTTP sind.

Und zwar nicht nur...

Das ist dann halt nicht...

Das sind halt Django Channels.

Also es ist quasi...

Genau, Django Channels macht halt sowas wie WebSockets,

aber halt nicht nur das, sondern auch WebRTC

und halt auch MQTT

und so.

Also alles, was eben lange Verbindungen braucht.

Genau, genau. Aber du kannst es

dann halt schon auch an Django damit anbinden

in gewisser Weise.

Genau. Und es wird halt natürlich

Ja, also das ist das, was ich da als Anwendungsfall sehe, dass man da leichter sozusagen in diese Welt reinkommt.

Ja, also was ich total interessant finde,

also wie gesagt nochmal, also wenn ihr das nicht kennt,

Phoenix Elixier würde ich mir im Live-View

angucken. Ja, das ist super spannend. Ja, was das Ding

nämlich macht ist, also man kennt das ja so,

also ich würde sagen, das was halt jetzt die meisten Leute schon kennen,

Single-Page-App mit JavaScript, da funktioniert

das halt so, du machst halt irgendwie auch

immer GraphQL oder REST oder

sonst was abfragen irgendwie gegen

ein Backend

und da gibt es

auch teilweise sowas wie WebSockets oder so, aber

im Grunde das ganze State-Handling

deiner Applikation machst

halt im Client.

Beliebig eklig oder halt

auch gut, keine Ahnung. Redux war

eine Zeit lang in, ist jetzt nicht mehr so.

Jetzt gibt es halt andere.

Vue X.

Aber

im Grunde, du machst das halt in der

Applikation, weil

du dann halt auch da

das ganze DOM-Diffing machen kannst

und dann halt nur die Sachen updaten,

die wirklich geändert werden müssen

und so. Und damit

das alles funktioniert, musst du das halt dann im Client

machen und so. Und

dieses Phoenix macht das

halt anders. Das macht das alles auf dem

Server. Und das schickt

sozusagen nicht irgendwie

dir jetzt gedifft irgendwie

den DOM zurück, sondern es schickt dir halt sozusagen

die Änderung an deinem State

zurück an den Client und da

wird es halt direkt im DOM geändert. Aber

dadurch, dass das halt sozusagen auf dem Server

alles ausgerechnet wird, kann das sehr blöd sein auf dem Client.

Also da ist halt irgendwie das

JavaScript halt von dem

von diesem Liveview-Dings ist halt irgendwie so 1000 Zeilen

und ich habe einen Vortrag von dem Entwickler davon gesehen,

er meinte immer so, also er muss immer aufpassen,

er hatte manchmal das Gefühl, er ist jetzt hauptsächlich JavaScript-Entwickler

und da muss er sich immer selber sagen, nein,

ich fand diese JavaScript-Frameworks alle immer ganz furchtbar

und ich wollte das anders machen und ich sollte nicht

jetzt anfangen, irgendwie das nächste verrückte

JavaScript-Font endzuschreiben, sondern das muss so wenig

JavaScript bleiben wie möglich

und es ist halt auch relativ wenig, es sind halt irgendwie tausend

Zeilen oder so und

alles andere passiert auf dem Server

und das updatet

den DOM direkt, also

was über die Leitung geht, ist tatsächlich nur so

etwas wie

Name des

Attributs von irgendeinem Formularfeld oder sowas

dann neuer Wert und dann wird es halt geändert

und zwar direkt im DOM

und das ist halt natürlich nochmal deutlich schneller

als man das normalerweise so gewöhnt ist

wenn man den JavaScript

Frameworks und es ist halt weniger

Kram auf der Leitung.

Was man normalerweise, was man selbst bei diesen

Single-Page-Apps-Geschichten halt auf der Leitung hat,

ist ja nicht nur der Payload, der

übertragen wird von den

APIs sozusagen, also

weiß ich nicht, irgendwelches JSON,

wo halt auch ganz viel immer

dupliziert wird und ganz viel Boilerplate

dabei ist, sondern

was halt auch da immer noch mitkommt, ist halt

diese ganze Protokollgeschichte und die Cookies.

So 4-Kilobyte-Cookie-Kram, der

da hin und her geschickt wird.

und es wird jedes Mal

nochmal, auch der Server

muss immer nochmal, achso,

hier ist deine Signatur, ach du bist der User,

ach sehr gut und alles klar, ich merke mir das mal

und vergesse es sofort wieder beim nächsten Request.

Das ist halt eigentlich, wenn man sich anguckt,

was da tatsächlich passiert auf der Leitung,

das ist alles ganz schön verrückt.

Und wenn man sich dem gegenüber anguckt,

was Elixir da macht, da geht einfach nur die rohen Daten,

die gebraucht werden, um den DOM

zu ändern, gehen über die Leitung und sonst nichts.

Und das ist wirklich super wenig.

Das klingt ziemlich schlau.

Und der Witz ist, genau das gleiche könnte man

mit Django eigentlich auch machen.

Du brauchst eigentlich auch nur diese tausend Zeilen.

Das müsste doch mal jemand machen.

Ich dachte auch schon,

vielleicht sollte man sich diese tausend

Zeilen JavaScript da mal genau

angucken und dann halt

das Ganze mit Channels und

WebSockets machen, weil

dass man den State mit Async

super handeln kann,

das kann man in Python und Django ganz genauso

machen.

das muss man nicht, da braucht man

das Erlangen da gar nicht

ja also

genau, das ist halt so ein bisschen das Versprechen

und das wäre natürlich schon sehr

cool, wenn man sowas machen könnte

ja

genau

wir müssen noch ein paar Schlüsselwörter

sagen, bevor wir

bevor wir aufhören können

soll ich mal einfach so W haben kooperatives Multitasking ach ja kooperatives Multitasking Genau wir haben jetzt noch gar nicht die wirklichen Unterschiede Also genau

Es gibt jetzt unterschiedliche Ansätze,

wie man diese Concurrency-Geschichte hinbekommt.

Ah, soll ich ein bisschen

was über Geschichte erzählen?

Interessiert euch das?

19. Jahrhundert, oder?

Also, damals.

Also, wie Concurrency irgendwie nach Python gekommen ist.

Ich weiß nicht, ich habe das...

Ein Großteil davon habe ich aus der...

Märchen, was man seinen Kindern erzählt.

Wie Procurrency damals nach Python gekommen ist.

Ich kann nur diese Serie von

Lukas Langer über Async.io empfehlen.

Da habe ich jetzt einen Teil von dem, was ich jetzt erzähle.

Und zwar

ist es so Mitte der 90er oder so

gab es da halt so erste Anwendungen für

man will vielleicht diverse Dinge

parallel machen. Ach verdammt,

jetzt bin ich selber in die Falle getroffen.

Procurrency machen.

Nebenläufig.

Und da gab es das Medusa

Framework für.

und das wurde zum Beispiel verwendet von Google, dann um den Webcrawler zu bauen.

Und so ist halt Python ja auch irgendwie bei Google reingekommen, halt über den Crawler.

Und das ist auch irgendwann dann in die Standardbibliothek reingekommen als AsyncCore.

Ich glaube, das Modul ist auch heute noch in der Standardbibliothek, aber ja, deprecated.

Und dann gab es halt eine ganze Zeit lang irgendwie so Ansätze.

dann kam irgendwie, glaube ich, zur Jahrtausendwende irgendwie so um den Dreh irgendwie Twisted dazu

wurde dann auch viel verwendet, war aber immer

inkompatibel zum Rest von Python

so die normalen Standardbibliothek-Funktionen, die blockieren alle, die machen alle

synchronen I.O. und so, das hat nie so richtig dazu gepasst, das heißt, das musste alles irgendwie anders

gemacht werden, das heißt, man konnte Code, den man jetzt in Twisted

wo man Twisted benutzt hatte, um das Concurrent zu machen, nicht jetzt mit irgendwas

verwendet.

Wenn man jetzt vorhatte, auf G-Event umzusteigen

oder so ging das halt nicht.

Ja,

aber Twisted ist auch ein

Riesending. Es gibt ganz viele Firmen, die

das für irgendwelche Netzwerkgeschichten benutzt haben.

Apple hat das.

Super viele Sachen, die man vorher einfach nicht machen konnte.

Genau, genau. Also es ist

schon ein Riesending.

Der Mensch, der das entwickelt hat,

Levkovits,

glaube ich, der hat auch

den Pep zu Async.io mitgeschrieben.

später, also Async.io ist dann auch sehr stark beeinflusst von Twisted.

Ein anderer starker Einfluss ist Tornado.

Auch einer aus dem Tornado-Projekt hat halt auch, ist einer von den drei Leuten,

die halt den Async.io-Pep mitgeschrieben haben, der andere ist dann Guido.

Und also Tornado und Twisted haben das beide stark beeinflusst.

Tornado auch eine ganz interessante Geschichte, ist auch ein Ding,

was Leute

geschrieben haben, oder ich glaube

ursprünglich hat das mal Brad Taylor geschrieben, Brad Taylor war

bei Google, der hat irgendwie

Gmail gemacht und Google Maps

und dann haben ein paar von den

Leuten, auch Paul Buchheit war glaube ich auch dabei

die haben dann eine neue Firma gemacht, irgendwann so

2007 oder so, Friendfeed, ich weiß nicht

ob ihr euch daran erinnert

ich habe es auch mal gehört, ich weiß nicht ob ich es mal benutzt

habe, keine Ahnung, ist dann von

Facebook gekauft worden

2009

und

und

ja,

Brad Taylor ist dann CTO von

Facebook geworden.

Und ich hatte ja, das letzte Zufall, ich war auch

glaube ich in einer Podcast-Version mit Lukas Langer,

der war ja lange bei Facebook und

erzählte dann so, dass intern bei Facebook

ein großer Teil von Facebook ist halt irgendwie

Python. Fand ich überraschend,

wusste ich gar nicht. Und so komisch,

wie kam denn da Python rein? Ja gut, vielleicht

über Instagram oder so, aber

tatsächlich irgendwie, ja,

der Autor von Tornado ist halt irgendwie,

war halt CTO von Facebook lange Zeit.

Und hat da wahrscheinlich auch

seine Python-Vorlieben vielleicht so ein bisschen

ausgelebt.

Jeder bringt seine eigene

Technologie mit.

Ja.

Genau.

Das

Tornado

ist auch heute noch eine ganz

interessante Geschichte. Wird auch noch

nach wie vor aktiv entwickelt.

Ist auch bei der Jupiter-Geschichte liegt das

irgendwie drunter.

Ja.

und genau, aber das waren halt

alles Dinge, die unabhängig

voneinander halt existiert haben

und mit Python 2 war

das sowieso alles nicht so gut kombinierbar

und

dann

genau, ist halt

2012, glaube ich, gab es dann so erste

Ansätze dazu, das mal

dann tatsächlich in die Standardbibliothek

und in die Sprache irgendwie reinzubringen und ich glaube

mit 3.4, das muss dann irgendwann so

2013 irgendwann gewesen sein

ist dann halt auch

sozusagen das in der Sprache gelandet, beziehungsweise in der Standardbibliothek

mit diesen Dekoratoren

für Async-Funktionen

und dann in 3.5 kam die echte Sprachunterstützung mit

AsyncDev und Await dazu, also ab dann gibt es eigentlich tatsächlich

richtig Unterstützung in der Syntax

Ja, und es gab noch ein paar

weitere Geschichten, die dann auch später dazugekommen sind

Da hat sich auch noch einiges

getan, also es ist heute

viel angenehmer, das Ganze zu

benutzen, also es ist viel angenehmer, das zu benutzen als

früher

und es ist eigentlich inzwischen richtig

klasse, also

es ist aber was, es ist eine völlig andere

Geschichte

als jetzt, es gibt jetzt auch andere Sachen

also man kann zum Beispiel

Multisredding gab es in Python auch

schon immer, war in Python 2

ganz, ganz schrecklich, weil

Lochschreckliche?

Ja,

weil es tatsächlich

so ein Lock-Contention-Problem gab. Also einmal

ist es natürlich langsamer, als wenn es nur in einem Thread ist.

Also je mehr Threads man hat, desto langsamer wird es eigentlich.

Und Python 2 ganz besonders

schrecklich auf mehreren Prozessoren, weil

da haben die Threads sich dann tatsächlich um den

Gill gekloppt und ja,

das Ganze wurde noch viel schlimmer, langsamer.

Aber auch da, seit Python 3.2

gibt es einen neuen Jill, also

In Python 2 wurde das so gemacht,

beziehungsweise vor Python 3.2,

dass

der Interpreter

alle 100 Ticks, also

ein Tick ist halt irgendwie so eine

ja, ich weiß nicht

Das ist ein Upcode, oder?

Ja, genau.

Das ist sozusagen eine primitive

Operation, aber das kann auch so was sein, also wenn man sagt

so for i in range eine Million,

dann ist das auch nur ein Tick.

Das ist so ein bisschen schlecht,

weil es kann halt sein, dass ein Tick sehr, sehr lange dauert.

Aber

das Ding hat halt fix

nach 100 Ticks irgendwie geguckt,

okay, hat so eine Check-Funktion aufgerufen

und die hat dann einmal

Signal-Handling gemacht,

aber auch geguckt, okay, welcher

Thread läuft denn gerade?

Muss ich vielleicht einen anderen Thread

in die Warteschlange

der Threads, die jetzt

runnable sind, fürs Betriebssystem reintun oder nicht?

Das ist auch so, dass Python-Threads

sind echte Betriebssystem-Threads, also

was ich dann oft lese, irgendwie so was wie

ja, der Python-Interpreter, der Scheduleter, irgendwas

ne, macht er nicht, das betriebssystem

aber der

Python-Interpreter kann natürlich sagen, okay, also

dieser Stretch hier wäre jetzt theoretisch runnable

der dann vom Betriebssystem

tatsächlich

sozusagen, wo der Kontext dazwischen geht und welcher dann

weiter ausgeführt wird, das macht das Betriebssystem

dann

Wie nennt man das, Jochen?

Jetzt muss ich kurz das Schlüsselwort dazwischen sagen

Präemptives Multitasking

weil man zwischendurch abgebrochen werden kann

präemptives Multitasking, weil

man selber sozusagen, wenn man jetzt

in einem Thread ist, kann man nicht bestimmen

wann einem die Kontrolle

entzogen wird oder wann man sie wieder bekommt

und das kann jederzeit passieren

auch in

ich habe mich da mal mit jemandem drüber gestritten

und musste dann leider

mir zeigen lassen, dass ich

da Unrecht hatte, das kann auch innerhalb

eines Python Befehls sein, also

Python Befehle selbst sind da nicht atomar, sondern

und es sind eben diese Bytecodes, die

darunter liegen, die atomar sind.

Aber so eine Zuweisung wie

i plus gleich 1

ist auch nicht atomar, sondern

das kann zwischendurch unterbrochen

werden.

Das ist da die große Gefahr daran,

dass man eben innerhalb eines

Befehls, den man selbst

als unteilbar sieht,

kann man irgendwie

die Kontrolle wegnommen kriegen, es passiert

irgendwas anderes, jemand anders ändert

irgendeinen Wert und man selber

fängt wieder an und plötzlich sind die Sachen

anders, als man erwartet hätte und es passieren schreckliche Dinge.

Also das ist

präventives Multitasking.

Präventives Multitasking, ja genau.

Hat natürlich gewisse Vorteile, aber

ist halt, also ja.

Genau, aber erstmal um das so zu, genau.

Das ist präventives und das, was man aber heute

hauptsächlich macht und was halt auch eine

gewisse Geschichte,

also auch schon immer eine Geschichte hatte,

sind halt diese sozusagen

Dinge, die man innerhalb

von dem Thread oder innerhalb von dem

Prozess ausführt.

Also wo das Betriebssystem gar nichts darüber weiß,

dass man das macht.

Wo man das halt selber sozusagen

entscheidet, dass man jetzt die Kontrolle

abgibt oder was anderes macht.

Und das ist dann halt kooperatives Multitasking.

Und das ist halt so das, was man

kennt aus, also in Java heißen die Dinger

dann Green Threads oder das ist halt auch

das, was in Stacklist-Fighting passiert ist.

Oder das, was G-Event gemacht hat.

Eventlets oder so.

Ja, genau, Eventlets.

LibEV liegt da, glaube ich,

zum Beispiel unter Umständen

drunter oder auch LibUV,

also die

Eventloop von Node.js.

LibEV hat

glaube ich

Armin Rigo geschrieben.

Was ja auch faszinierend war,

die gleichen Namen,

da tauchten viele Namen auf, die ich schon kannte.

Das sind erstaunlich wenige Leute.

Ich kannte die aus anderen Teilen,

und dachte so, ach, die haben auch diese ganzen Geschichten da,

da haben die auch alle irgendwie mitgemacht, das wusste ich gar nicht.

Also, genau,

Amin Rigo habe ich nur gehört im Zusammenhang mit PyPI,

aber nie mit,

äh, nicht PyPI,

äh, PyPi, aber nie mit

irgendwie so

Concurrency-Geschichten, aber, ja,

der hat, glaube ich, eine Bibliothek

geschrieben, GreenLed,

die auf LibEV basiert

und darauf basiert

wieder G-Event und G-Event

macht halt quasi sozusagen

User-Space-Threads

und

macht da aber auch

teilt das irgendwie so halbwegs zufällig

ein, wann die laufen und wann die nicht laufen

und damit das halt mit dem

Rest von der

synchronen und blockierenden

I.O.

Funktion und so im Rest von Python funktioniert,

monkeypatchen sie einfach alles.

Zum Beispiel das Rocketman-Rule, ganz böse.

Das ist ziemlich hart.

Sie weiß so, okay,

und Jochen unterhalten sich über die Programmiersprache Python

und kooperatives Multitasking im weitesten Sinne.

Wobei, weiß ich jetzt gar nicht, bei G-Event bin ich mir jetzt gar nicht so super sicher.

Klar, bei G-Event ist es auch kooperativ.

Ja, im Prinzip ist es kooperativ.

Im Wesentlichen jetzt ist ja AsyncIO oder so der...

Genau, das ist jetzt sozusagen der heißeste Scheiß, den man jetzt da macht.

Und ehrlich gesagt, ich habe ja jetzt da auch eine ganze Zeit lang Sachen an,

das sieht auch deutlich besser aus als alles, was man da so vorher gemacht hat.

Aber im Wesentlichen heißt es doch, jedes Mal, wenn du Yield sagst,

wird dir die Kontrolle erstmal weggenommen.

Yield? Ja, nicht, Await.

Ah, wenn du Await sagst, okay.

Ja, früher war es Yield. Ja, Yield

from, genau, das war noch die

Syntax davor. Aber das ist

so ein bisschen der zentrale Mechanismus, oder?

Dass du sagst, okay, ich mache jetzt was

und sobald ich Await sage,

kann jemand anderes was machen. Genau,

genau. Und das hat eine interessante

Auswirkung auf die

Art oder auf die Schwierigkeit, also wie schwer das

zu programmieren ist, weil wenn du primitives Multitasking

hast und an jeder Stelle kann im Grunde

die Kontrolle weggehen, dann

alle Dinge, die irgendwie atomar

sein müssen, musst du halt dann mit Logs

absichern. Ja, es gibt dann so kritische

Sektionen, die musst du sehr ab. Genau, und das Problem

ist halt, du darfst halt nichts vergessen und das kann

halt überall passieren und du musst halt

Ja, und selbst wenn du nichts

vergessen hast, kommst du immer noch in so

Deadlock-Situationen rein oder in so

Starving-Situationen. Selbst wenn du

alles richtig machst, kannst du immer noch

Das ist eine Starving-Situation, es

wartet irgendjemand darauf, dass irgendwie wer losrennen

kann, aber da kommt einfach nichts.

Ne, das ist ein

Deadlock heißt, zwei oder mehr Dinge warten auf sich gegenseitig.

Und ein Starving?

Dann kann keiner loslaufen.

Und Starving heißt, jemand, der etwas tun könnte, kommt nie dran.

Weil immer jemand anders schon was tut.

Das heißt, dass der nicht selber gelockt ist, sondern dass er einfach nicht...

Schnapp, wie man vor Aspekt ist.

...zu niedrig ist oder weil er immer sagt, macht ihr erstmal.

Dass der sozusagen für immer wartet, obwohl er etwas tun könnte, obwohl er nicht irgendwo...

Ach, wäre ja so schön, aber die können das ja alle schon so gut. Ich bleib da mal hier stehen.

Genau, und sowas passiert dann halt. Sowas passiert halt in so präemptiven Sachen, weil du keine Kontrolle drüber hast, wer läuft.

Beziehungsweise die Kontrolle, die jemand hat, ist eben das Betriebssystem.

Und das muss dafür sorgen, dass so ein Deadlock entweder aufgelöst wird und dass solche Starving-Situationen nicht passieren.

Ja, also es gibt da halt diverse Techniken, mit denen man das halt auch, also die Probleme minimieren kann, es gibt dann so ein paar Patterns und wahrscheinlich würde ich auch sagen, also für die meisten Fälle nimmt man halt so ein Pattern und dann kann eigentlich nicht mehr so wahnsinnig viel passieren, man nimmt halt eine Queue oder halt viele Queues und macht da halt Logs rein und da gibt es auch schon fertige Dinge, wo man die Logs nicht selber ersetzen muss und dann Ja, aber auch da ist es erstaunlich leicht in so Situationen reinzukommen, wo du dich deadlogst

Das ist erstaunlich leicht

Jaja, ich würde auch sagen, also es ist halt

sehr scharfkantige Geschichte

Ja, man muss da echt aufpassen

und genau, achso

richtig genau

das habe ich eben nicht mehr erzählt, genau

nach 100 Ticks immer diese Geschichten, aber das hat halt

diverse Nachteile, weil Tick kann halt sehr lange

sein und dann gab es halt auch diese

Battles über

wer kriegt den Gill

quasi auf unterschiedlichen Prozessoren und da so war

halt, das war, wie

David Beasley gibt es halt

Understanding the Jill, zum Beispiel

den Vortrag von 2014

oder Verhalten auf

mehreren... Urgeschichte.

Also er sagte irgendwie auf

einer, also mit einem Stride, also alles gut, mit mehreren

Strides, na, nicht so toll,

auf mehreren Prozessoren, Diabolical.

Das war wirklich irgendwie nicht schön.

Und

ja, das ist aber mit Python 3.2

besser geworden, da gab es einen neuen Jill

und der macht das nicht mehr nach

Ticks, sondern es gibt jetzt einen Zeitintervall

was halt eben

das führt das halt nicht

quasi Dinge für immer warten

müssen, weil halt

ein Tick halt super lang war

und zwar jetzt ist es halt so

jetzt ist es nicht alle 100 Texte, jetzt ist es alle 5 Millisekunden

man kann das aber auch einstellen, wie man möchte

also das konnte man vorher auch schon

so alle 5 Millisekunden guckt halt der Interpreter

nach

muss mal jemand anders dran

kann mal jemand anders dran

oder welches Schatz könnte laufen

wobei letztlich wer das entscheidet ist das Betriebssystem

ja und das

funktioniert jetzt deutlich besser, das funktioniert auf mehreren CPUs

auch gut, ja es ist nicht so, dass jetzt da

auf mehreren CPUs gleichzeitig was gemacht würde, aber

es ist nicht mehr so, dass die Performance viel schlechter ist

als wenn man nur eine CPU hätte

was ja schon mal auch nicht so schlecht ist

genau, daher

also Threading kann man auch verwenden

also es ist auch nicht so, also es funktioniert mittlerweile

ganz gut auf Linux, also auch 10.000

Threads aufmachen, gar kein Problem

funktioniert

Genau, neulich hast du ausprobiert, Jochen

bei 9500 war Schluss bei mir

Aber

also das geht alles und das ist auch

nicht, das findet man auch oft, ich war überrascht

ich habe da so ein bisschen recherchiert

wie oft da so Dinge auch in Büchern

drinstehen, ich habe zum Beispiel Fluent Python mir angeguckt

oder auch Effective Python von

Brad Slatkin, also eigentlich beides sehr renommierte

Quellen, weil ich dachte so, okay, so die

Standardwerke, da muss doch drinstehen wie es geht und die sagen

beide irgendwie, ah, Threads ganz schlecht

du kannst irgendwie keine

nicht so viele Threads aufmachen, weil

der Stackspace

Betriebssystem riesig, brauchst halt

8 MB, zum Beispiel sagt Effective

Python, weil Fluid Python sind halt auch

immer in Größenordnung von, jeder Thread braucht so

Größenordnung MB, aber das ist halt nur Virtual Memory

das ist gar nicht

Resident Memory, das heißt

das stimmt so nicht

das ist viel weniger und das

Context-Switchen, also es gibt da auch so einen schönen Artikel, wo jemand das

alles mal gemessen hat und das ist

eigentlich sollte das alles kein Problem sein

und vielleicht war

und Jochen unterhalten sich über die Programmiersprache Python

Das heißt, das passiert, selbst wenn man ein kreatives Multitasking hat, passiert das automatisch. Also muss man sich auch nicht selber darum kümmern, sondern da gibt der Thread, der halt irgendeinen blockierenden Netzwerkaufruf gemacht hat oder I.O. Aufruf, da ist der Jill sofort weg.

und

ja,

also ich würde sagen, mit Threads kann man

eigentlich auch alle Sachen so, also wenn es

darum geht, I.O. zu multiplexen, das kann man mit Threads

auch wunderbar machen. Es ist

schwerer zu programmieren, es ist halt ätzend,

dass man nicht weiß, wann man die Kontrolle

weggenommen wird und so.

Es ist im Debugging

ziemlich übel,

aber... Probleme, die wir vorhin

erzählt haben, da kommen dann halt irgendwelche Fehlermeldungen

von irgendwo her. Irgendein

Callback hat Markus gesagt, hallo,

Ich sterbe. Dann steht man halt da.

Aber es geht auch. Und ich würde jetzt

nicht sagen, das kann man gar nicht machen, sondern

ja, es geht auch.

Aber tatsächlich

Async.io würde ich auch sagen mittlerweile deutlich

besser, weil

das ist jetzt kooperativ.

Es dreht sozusagen die Geschichte um.

Bei Threads ist es so,

man kann überall die Kontrolle weggenommen

kriegen und Dinge sind bedroht, solange man

nicht gesagt hat, okay, ich locke das jetzt hier.

Ich benutze irgendeine Kernel-Datenstruktur

um zu sagen, da bitte nicht

so, dann ist das geschützt, aber alles andere ist halt irgendwie

wilde, wilder Westen, Drachen kommen

vorbei, verbrennen einen die Hütte, also ist halt, ja, weiß man nicht

und bei Async.io ist es quasi umgekehrt, da gibt's

halt, also die Stellen, an denen böse Dinge passieren

können, die sieht man, die sind markiert, da steht await vor

und alle anderen Sachen, der ganze andere

Code, das ist einfach ganz normaler Code, der so durchläuft

wo man sich sicher sein kann, dass einem die Kontrolle da nicht weggenommen

wird und da kann man auch

Operationen machen und wenn da nur,

wenn da kein Await kommt, dann ist das alles atomar, weil

kann sonst ja gar nichts passieren.

Und das ist natürlich schön,

weil die

Anzahl möglicher Fehlerquellen wird halt

deutlich geringer, aber

man bezahlt natürlich in gewisser Weise einen Preis dafür

und der ist halt, naja, also man muss

sich halt auch selber darum kümmern, dass das halt,

dass man die Kontrolle

abgibt, wenn es geht, weil man alle anderen

blockiert, wenn man das nicht tut. Also wenn man jetzt irgendwas...

Man muss einfach kooperativ sein.

muss kooperativ sein. Wenn man irgendwas macht, was lange

dauert, dann gehen halt

alle anderen kaputt, was halt auch unter Umständen

natürlich sehr böse Konsequenzen haben kann.

Ja.

Aber da sieht man dann wenigstens. Also ich meine, wenn

du da dann den Interpreter unterbrichst, weißt du,

siehst du, wo du bist.

Wer schuld ist. Genau. Es ist auch so, dass man

kann, ich glaube,

Python-X, wenn man Debug

anschaltet und

TraceMalloc anschaltet, das sollte man immer

machen, wenn man irgendwie so Async-IO-Sachen

zumindest auf der Entwicklungsseite macht, dann

ist, sollte man das mal anschalten.

Produktion natürlich unter Umständen

nicht, kostet auch Ressourcen, aber

dann sagt einem der Interpreter zum Beispiel

sowas wie, also hier hast du

irgendwie ein Task oder was, diese Funktion

hockt die CPU und zwar ganz übel,

weil er das intern halt aufruft mit

einem Timeout und das halt mitkriegt

und dann die Exception fängt,

wenn das halt zu lange dauert.

Also diese Funktion da, die macht irgendwas Böses.

Das sieht man dann tatsächlich in der Ausgabe

oder sagt einem auch, wenn man Sachen

nicht awaited hat und so.

Type Annotation ist auch total sinnvoll,

vielleicht bei so hakeligen Geschichten.

Da kann einem der Interpreter auch noch eine Menge

sagen, was da halt dann schief geht.

Weil er halt weiß, dass da jetzt eigentlich

eine Coroutine zurückkommen sollte und so. Und wenn das

halt nicht passiert und dann, ja.

Also da geht

einiges.

Und es ist halt, wie gesagt, also

die bösen Stellen sind die, wo await davorsteht

und alles andere ist halt sozusagen ganz

normaler Python-Code eigentlich.

Ja.

und das ist halt schon schön

und von den Ressourcengeschichten

würde ich jetzt zwar sagen, nachdem

ich mich so ein bisschen damit beschäftigt habe, es ist nicht so

also es ist, ich weiß

es geht hier hinten ins Fetz auch

aber natürlich ist es auch so, dass die sind schon

Ressourcen aufwendiger, also

das habe ich jetzt nicht nachvollzogen

aber also Coroutine ist halt eigentlich

nur ein Funktionsaufruf und

braucht halt einen Kilobyte Hauptspeicher oder so

und davon halt ganz ganz viel zu haben ist im Grunde

überhaupt kein Problem, du kannst

Zehn, Hunderttausende davon haben, kein Ding.

Du musst halt bloß

schnell genug bleiben, dass du halt tatsächlich,

dass diese Hunderttausende auch irgendwann alle mal wieder drankommen,

aber ansonsten geht das.

Und ja, da gibt es ja dann auch

sehr schnelle Event-Clubs drunter, also man kann

halt auch, es gibt die Referenz-Implementation,

der Event-Club in

Python, die ist nicht schnell,

aber die ist halt dafür da, damit man weiß,

wie es funktioniert.

Wenn man jetzt eine andere Implementation schreibt, die auch

dagegen testen kann und zu gucken, verhält die sich jetzt genauso,

wie sie sollte und so.

für Produktionen kann man dann halt sowas nehmen wie

diese UV-Loop,

also Leap UV

und das ist die Node.js Event-Loop und die ist halt

echt sackschnell.

Damit möchte man halt unter Python

quasi da auch dann die gleiche Geschwindigkeit

hin.

Haben wir erklärt, was

eine Event-Loop ist?

Nein. Ich hätte jetzt mal einen Vorschlag.

Ich würde jetzt auch so langsam mal die Kontrolle

abgeben.

Ja, ja.

Einmal Awave machen.

Yield.

Ich würde einmal Yield sagen

und dann direkt Sleep aufrufen.

Das ist doch ein sehr schönes Stichwort, oder?

Ja. Aber es hört sich für mich

an, als ob wir noch mindestens zwei, drei

Episoden daraus machen müssen. Vielleicht machen wir einfach

noch eine. Alle Worte

gesagt haben, die gesagt werden müssen. Also mir fallen noch viele

Worte ein. Dir fallen sicherlich auch noch ganz

viele Worte ein.

Es ist auch, wenn ich

mich so an diese Vorlesungen erinnere,

die wir da gemacht haben,

und es hat eine gewisse

intellektuelle

Schönheit, wenn man diese ganzen

Locking-Algorithmen dann hat,

wenn man die Dining-Philosophers einmal besiegt hat

oder wenn man einmal die

Lockless-Data-Structures alle

erfunden hat. Das hat auch was Schönes,

aber

es ist nicht was, was man

jeden Tag in seiner Arbeit machen möchte,

glaube ich.

Es ist wirklich schwer.

Es ist auch eine massive Fehlerquelle.

Ich finde es auch

wirklich

und

und ich sage, passiert mir nichts.

Und das nimmt ganz, ganz, ganz viele

von diesen Ecken und Kanten da raus,

die einem sonst eben ganz schlimm

da reinfahren, die einem sonst die kritischen

Sektionen kaputt machen.

Und das

ist eine sehr gute Entwicklung, ich begrüße das sehr.

Und das war ein sehr schönes Schlusswort,

lieber Johannes.

Alles klar, dann...

Ob ich es geplant hätte.

Ja, würde ich sagen, machen wir doch einfach...

Ja, an dieser Stelle, bleibt uns gewogen,

wenn immer ihr uns hört,

lieber gerne immer weiter.

Abends, morgens, mittags, nachts, an welchem

Erdballteil ihr euch gerade befindet.

Oder irgendwo out of space,

man weiß es immer nicht genau.

Ja,

schön, dass ihr wieder eingestaltet habt.

Alle Kritik, Feedback und so weiter,

bis zum nächsten Mal. Tschüss.

Bis dann. Tschüss.