Ja, hallo liebe Hörerinnen und Hörer, willkommen beim Paisen-Podcast, heute die 26. Episode, wir haben den 1. Dezember.
Jochen, wir sind heute genau zwei Jahre, vor genau zwei Jahren haben wir die erste rausgebracht.
Oh, ja richtig, das stimmt.
2018, am 1. Dezember kam unsere erste Episode raus.
Ja.
Ja, nicht schlecht, oder? Zweiter Geburtstag.
Zwei Jahre, meine Güte, ist das schon wieder lange her.
Nicht so schlecht, wir haben sogar durchschnittlich mehr als eine Folge dann pro Monat aufgenommen.
Und wenn wir die noch zählen, die wir weggeschmissen haben, sind wir sogar bei.
Ja, ich glaube, wir haben uns verzählt ab und zu. Ich weiß nicht, ob das wirklich genauso viele sind. Also 27 ist jetzt die Zahl, aber es kann sein, dass wir irgendwie Dinge unterschlagen haben.
Ja, ich glaube, 26 ist offiziell jetzt.
Kann auch sein. Ich weiß es nicht genau.
Ja, hallo, hallo. Schön, dass ihr wieder eingeschaltet habt. Heute machen wir Async Teil 2.
Ja.
Und wir haben dabei den Johannes.
Hallo.
Ja, wir wollten auch wieder ein bisschen News machen und euch ein bisschen entschädigen für die ganzen Folgen, wo wir das so ein bisschen…
Ja, wir haben uns ja immer so viel vorgenommen,
was wir eigentlich machen wollten.
Module aus der Standardbibliothek vorstellen,
Pics und so, das machen wir dann nie, weil
irgendwie immer zu wenig Zeit ist und wir
die ganze Zeit brauchen, um unser Audio-Setup hinzukriegen.
Ja, genau, und dann muss am Ende irgendwie
jemand wieder ins Bett und dann müssen wir leider immer aufhören.
Ja, genau.
Genau, machen wir das diesmal.
Ja, also
zum Beispiel eine Geschichte, die ich
eigentlich dann erwähnen wollte,
wir hatten ja vorletztes Mal, glaube ich,
was zu Python 3.9 erzählt
und eine ganz wichtige Geschichte habe ich vergessen.
Und zwar ist in
Python 3.9 Topological
Sort schon mit in der
Standardbibliothek. Topological Sort.
Jetzt bin ich natürlich wieder der Blöde,
der keine Ahnung hat, was das ist. Also
was ist bitte Topological Sort?
Jochen weiß es auch nicht.
Das ist nur cool.
Nee, das ist
wenn man jetzt
einen Graphen, also wenn man zum Beispiel
Abhängigkeiten hat und die sortieren möchte, also wenn man sich zum Beispiel
anzieht und dann irgendwie
dran denken möchte, dass man irgendwie
bevor man, weiß ich nicht,
die Schuhe anzieht, die Socken angezogen haben
muss, dann ist das Problem
sozusagen, das allgemeine Problem dazu ist
topological sort oder
topologische Sortierung, keine Ahnung.
Gibt es auch beim Projektmanagement, glaube ich.
Gibt es überall, wo es grafen.
Ja.
Zum Beispiel auch ganz wichtiger Angelegenheit,
da habe ich selber zum, da wusste ich noch nicht, dass es
das ist und habe selber
überlegt, was das für ein Problem sein könnte. Nach ganz,
ganz lange Überlegen bin ich dann drauf gekommen, es könnte
irgendwas mit Graphen zu tun haben und dann sortieren.
Und irgendwann hat mir jemand gesagt,
ja, das ist doch Topological Sort. Dann habe ich mich
ziemlich blöd gefühlt, aber
zwar wenn man die
Abhängigkeiten von Programmen
oder Paketen, die man installieren
möchte, sortieren möchte, da braucht man das dann auch.
Ja.
Genau.
Das ist jetzt mit drin, einfach so?
Das ist jetzt in der Standardbibliothek mit drin.
Batteries included, sage ich ja nur.
Ja, Graflip heißt das Modul, oder?
Ja, ja, genau.
Heute ist übrigens auch Advent of Code,
der Teil 1, rausgekommen.
Macht ihr das noch?
Worum geht es denn dieses Mal beim Advent of Code, Dominik?
Das habe ich noch nicht so ganz rausgefunden.
Ich glaube, irgendjemand möchte in Urlaub fahren auf eine Insel,
weil er schon fünf Jahre lang versucht hat, da hinzubekommen.
Und dann muss er irgendwie seine Abrechnung richtig machen,
dass er da hinkommt.
Ich finde, die letzten Jahre fand ich auch sehr interessant.
dann ging es ja irgendwie um Weihnachtswichtel
und die Reise durchs Weltall mit dem Santa
und so. Ja, genau.
Okay, mit dem Raumschiff, was
ein Interpreter braucht, den man dann selber programmieren musste.
Ja, genau, dann haben wir Opcodes und so, ne?
Ja, also Entschuldigung, das ist eine coole Sache.
Da kann man dann allen möglichen
Programmiersprachen machen natürlich und
hallo.
Das ist auch hauptsächlich so für einen selbst, oder?
Also es ist ja nicht irgendwie gewertet oder so,
sondern es ist ja nur...
Ja, ich kenne es gar nicht.
Ja, es sind einfach 24 Programmieraufgaben,
üblicherweise zweigeteilt in zwei Teile.
Und die sind immer von der Sorte, hier ist ein kleines Beispiel
und hier ist eine große Eingabemenge.
Und wenn du die Antwort weißt, dann tippst du hier in dieses Feld ein.
Und dann kannst du quasi überprüfen,
ob du die richtige Lösung gefunden hast.
Ah, okay, ja.
Und das ist eigentlich immer ganz nett.
Das ist sehr nett gemacht, das ist sehr aufwendig
gestaltet und wir haben immer schöne Story.
Genau, man muss ja immer einen Stern sammeln pro Tag,
pro Aufgabe, also zwei Sterne am Tag.
Zwei Sterne, genau.
Für 48, 50 sogar, oder?
24, kriegt man 25 auch noch ein?
Nö. Also, ja,
zweimal 24.
Ich glaube, 48 dann.
Ach so, und das geht auch zurück, also man kann auch bis
2015 zurückgucken
und sich die ganzen alten Aufgaben
ansehen.
Das ist sehr nett, also
selber ausprobieren und dann halt gucken, ob man
die Aufgaben lösen kann. Die werden am Anfang
sind die noch etwas einfach.
Die gehen aber schnell wirklich in die Zeit.
Ich habe sogar einen Post gelesen von Peter Norweg,
der sagt, das ist ja eigentlich schon sehr geil, aber
so viel Zeit hat er dann auch nicht.
Aber ja.
Das ist auch bei mir immer so das Problem. Ich mache da gerne
mit und dann irgendwann fühlt
es sich an wie Arbeit und dann höre ich es dann wieder auf.
Ja, aber es ist auf jeden Fall
sehr zu empfehlen. Für alle
Stufen ist was dabei. Die ersten Aufgaben
sind einfacher, die kriegt man schnell durch und die
so ab dann fünf oder so
oder sechs oder zehn oder zwölf wird es dann
schon richtig happig. Ja, man muss sich dann wirklich überlegen, wie man
da rangeht und nicht einfach so so hands-on drauflos.
Dann läuft man meistens gegen eine kleine
oder größere Wand. Und
letztes Jahr war es auch so, dass die aufeinander aufgebaut haben.
Das heißt, man hat dann an einem Tag seinen Interpreter
gebaut und zwei Tage später hat man wieder abgebaut,
weil dann noch ein Feature dazu
kam. Ja, oder man musste halt neue Opcodes handeln
oder sowas. Und wenn man am Anfang studrig
gearbeitet hat und das so hingeworst hat,
dass das einfach so ging, da hat man sich geärgert,
weil man die Implementierung sonst einfach hätte
erweitern können und so musste man sie ganz neu
bauen. Naja, ich bin gespannt, wie es dieses
Jahr draus wird.
Ich habe nicht immer so viel Zeit, aber ich glaube, so eine Stunde morgens
würde ich mir schon dafür nehmen. Ich mag das nämlich.
Ja, es lohnt sich auf jeden Fall auch. Sehr gute
Übung.
Ja, ich habe da auch immer sehr viel gelernt. Also wirklich
auch über Konzepte von anderen Lösungen angucken, verschiedene
Sprachen. Ein Kollege von mir macht das in Go.
Da kann man das immer schön vergleichen.
Hatte heute direkt eine rekursive Lösung
implementiert. Ich war direkt ein bisschen neidisch.
Ich hatte nicht an Binary Research gedacht. Ich wusste auch gar nicht,
wie das in Python richtig geht.
Und habe einfach ItaTools genommen,
was auch funktionierte, aber
war halt BruteForce.
Aber ja, wir waren bei News,
was der Stene stehen geblieben ist.
Ja, sind ja News.
Ja, genau.
Eine ganz interessante Geschichte. Python läuft
jetzt auf .NET
auf der Runtime da.
Das hast du gerade so ein bisschen leise vor dich hin
genuschelt, als wäre es eine
Meinung. Das ist mir auch ein peinlich.
Das ist peinlich, dass du das jetzt sagt und nicht leid.
Was ist jetzt der Unterschied zu IronPython?
Weil IronPython gab es ja schon lange. Ja, aber ich glaube,
das war schon lange nicht mehr so richtig
aktiv. Das ist so wie Jython.
Da gibt es sicherlich einen 2.7-Port für.
Ja, es ist irgendwie, es gibt einen Pep,
der beschreibt, wie man
sich quasi einklinken kann, wenn man jetzt
ein JIT-Compiler ist
und diese Variante
jetzt benutzt es auch. Das ist irgendwie
von Anthony Shaw oder so
hat das gebaut.
Was genau meinst du mit einklinken, wenn man ein
Just-in-Time-Compiler, das heißt
sowas wie Python, die halt
zur Laufzeit dann irgendwie evaluiert werden, oder
wie ist das?
Dass es halt dann zu Maschinencode runterkompiliert
wird, quasi.
Ja, und genau.
Aber während das Programm läuft. Also die Teile,
die gerade notwendig sind, werden dann
während das Programm läuft zu
Maschinencode kompiliert oder zu dem Code, der
VM, die da drunter liegt
und sind dann natürlich schneller.
Macht PyPy
zum Beispiel auch. PyPy hat auch so einen
JIT-Modus, der dann halt
die
Sachen, die jetzt gerade
in der Schleife sind und
100.000 Mal durchgeführt werden, die
kompiliert er dann halt so vor, dass diese Varianten
schneller sind. Das ist einer der
großen Vorteile von PyPy, dass
die das machen können. Das macht CPython nicht.
CPython hat keinen JIT drin.
Der hat einfach seine Stack-Maschinen und die arbeitet
das alles ab und fertig.
Aber wie ist denn dann die
Runtime? Das ist ja dann nicht CPython, sondern das ist
dann irgendeine andere Runtime, die auf .NET läuft, oder wie?
Ja,
nee, das ist schon hauptsächlich
CPython. Es ist nur so, dass man
das irgendwie,
also,
keine Ahnung.
Es ist schon CPython.
Aber es
funktioniert jetzt
halbwegs noch nicht schneller, aber
Leute könnten jetzt
Optimierungen machen, indem sie halt das
irgendwie auf die .NET Runtime
optimieren.
Ja, war auf jeden Fall
irgendwie so, kann man sich mal angucken.
Ich werde mal den Artikel dazu in den Shownotes packen.
Ja, was
hatten wir noch? Genau, noch so Dinge
wie
PEP 621,
irgendwie mehr dazu gekommen, was man jetzt alles so in
PyProject-Tommel irgendwie reinschreiben kann
an Metadaten. Oh, cool. Was denn?
Ja,
ich glaube, so ziemlich alles, was
halt vorher sonst ein Setup-UI so genannt hätte.
Flake 8 auch?
Ich glaube, Flake 8 wehrt sich noch so ein bisschen.
Ähm,
ja.
PyTest geht fast, also
PyTest ist im Moment noch so mit PyTest
Ini-Options, so ein Workaround.
Das wäre cool, wenn das normal wäre und
ich glaube, Flake 8 hat es noch nicht so wirklich geschafft.
Und habe ich noch was vergessen, was fehlt?
Ähm,
ja,
ich glaube, das sind eher so Dinge wie,
was ist der Autor von dem Ding und was
sind die Abhängigkeiten und diese ganzen
Geschichten. Ja, aber so Black-Konfiguration geht zum Beispiel
schon rein und... Ja, ja, gut, aber das ist ja
ein Third-Party.
Ja, ein Third-Party, aber das ist ja nett,
wenn man das alles da in die Pipeline drumherum packen kann,
weil ich bin ein Freund von monolithischen
Konflikts und nicht so ganz vielen kleinen,
die irgendwo rumfliegen.
Ansonsten, was auch noch
ganz,
was ich ganz witzig fand,
da sind ja irgendwie neue Chips aus Apple rausgefallen.
Ja. Hat man gehört.
Ja.
Waren.
Hat man schon so Geräte gesehen?
Ja.
Also du hast schon so ein...
Ich habe jetzt keinen, aber ich habe schon
irgendwie Ergebnisse von
den Geräten gesehen für
Dinge, die ich interessant fand.
Und insofern, wenn ich jetzt schwer überlege,
ob ich da nicht vielleicht auch mal zuschlagen
soll, weil es ist schon
sendet, so auf dem Papier jedenfalls und so was man
hört.
Wenn man in diesem
Ökosystem drin ist, dann ist das glaube ich
eine Sache. Das ist ja so eine Sache, die ich gar nicht
verstehen kann. Also sonst finde ich ja alles, was
Mochen macht, total bewundernswert und super.
Aber dieses
Mekophilie, wie sagt man? Ich weiß nicht.
Mekaholika.
Fanboytum.
Naja, also
das Schicke daran ist halt, dass
da sind jetzt gar keine
Also zum Beispiel bei dem MacBook Air
sind halt keine Lüfter mehr drin.
Ja, juhu, im Sommer, yay.
Ja, aber also die Leute haben das ja schon benutzt
und das schaltet halt.
Ja, iPhone sind ja auch keine Lüfter drin.
Da sind auch keine Lüfter drin.
Das ist auch wahrscheinlich, dass das funktioniert.
Der schönste Hack, den ich gesehen habe übrigens.
Bitte was?
Der schönste Hack, den ich gesehen habe,
da hat einer die Tesla-App auf seinem Mac installiert
und der hat auch Bluetooth
und hat damit seinen Mac als Schlüssel
für seinen Tesla verwenden können.
Hm.
Was natürlich sehr praktisch ist,
wenn man immer seinen Mac dabei haben muss.
Ja, voll gut.
Und an, also der muss dann auch an sein.
Zum Einkaufen, einmal kurz im Supermarkt.
Ja, er hat mal kurz unter den Arm geklemmt.
Der Akku hält ja jetzt auch länger,
da kann man das dann vielleicht irgendwie aufgeklappen machen.
Aber handlicher ist das Gerät trotzdem.
Naja, nicht so richtig.
Wahrscheinlich sieht der Akku den Tester
innerhalb von zehn Minuten leer oder so.
Was es da jetzt halt auch gab,
ist schon so eine irgendwie Preview-Variante
von einer TensorFlow-Version,
die halt gegen die entsprechenden Bibliotheken gelinkt ist
und dann halt schnell ist halt auch auf Metal
und halt auf der Apple-Hardware.
Und das war tatsächlich auch ganz nett.
Also ich habe das dann auch mal,
ich meine, das ist ja immer so ein Problem,
man hat halt keine Nvidia-Karten auf Apple
und
es gibt da einmal so eine Geschichte
über PlateML, das ist so eine
Intel-Geschichte,
die man sich installieren kann, damit wird es dann halt schon mal
ein bisschen schneller, also da geht dann schon so ein bisschen was
GPU-mäßiges, halt auch mit den
AMD-Karten, die da halt drin sind.
Aber ist halt nicht so schnell wie Nvidia
und ist halt auch nicht so schnell,
also die CUDA und
diese ganzen Geschichten, das ist damit nicht so richtig vergleichbar,
aber so ein bisschen was kriegt man da schon hin,
Also zumindest so weit, dass halt so Maschinen in den Geschichten
halt auf der GPU in so einem MacBook sind halt genauso schnell
wie halt mit den acht CPUs sonst.
Ja, weil dann hat Nvidia 3090 oder sowas, da ist ja ...
Ja, genau, die ist halt schneller.
Die passt in den Mac nicht rein, habe ich gehört.
Ja, nee, das geht halt irgendwie nicht.
In diese Mac Pros gehen die nicht da rein?
Nicht?
Dachtest du, die hätten sogar Nvidia-Karten drin?
Das kann sein, dass das da geht, ja, das weiß ich nicht genau.
ja. Kostet ja wahrscheinlich 5000 Euro
für eine Karte oder so.
Ja, ist ja egal, komm.
Wenn der Standfuß von dem
Monitor schon 1000 Euro kostet, dann ist das
nicht mehr so wichtig.
Aber der ist aus einem massiven Block
Aluminium ist der rausgefräst.
Ja.
Ja, es ist auch, also aus
dem Bereich hätte ich auch News.
Jochen, was sagst du denn zu dem Durchbruch, was das
Proteinfalten angeht? Ja, das klingt
auch sehr gut tatsächlich.
Das wurde so beschrieben
als der erste richtige Anwendungsfall
für AI, der erste richtige
Durchbruch von AI-Anwendungen.
Wie mit den Protein-Fallen.
Wo eine
amerikanische Firma DeepMind
die haben
einen Algorithmus vorgestellt, also Algorithmus kann man
ja fast nicht sagen, aber die haben eine Technologie
vorgestellt, die aus
einer Sequenzbeschreibung
also
die Aminosäuren
quasi, die aneinander
gereiht werden, genau, die zum Beispiel durch
Gene kodiert werden können,
das fertig gefaltete
Protein berechnet. Und das Problem ist
halt, dass die,
ja, dass diese Proteine zwar
linear hergestellt werden,
aber sich dann eben zu einer dreidimensionalen
Struktur zusammenfalten. Und weil die eben
sehr viele Proteine drin haben, die sich
in sehr viele Richtungen falten können, ist die Anzahl
der Freiheitsgrade sehr hoch.
Und die haben jetzt eben eine Technik vorgestellt,
wie man innerhalb von wenigen Tagen
so eine Faltung berechnen
kann. Also quasi auf einem Strang
aus einer
RNA. Genau, also was du reinkriegst
ist, oder was du gegeben kriegst, ist eine
Abfolge von Aminosäuren. Das ist ja fast wie eine
RNA, oder? Genau, das ist
RNA. Das ist so ein Problem aus der Biologie,
was
1973 auf irgendeiner Konferenz
vorgestellt wurde.
Also seit 50 Jahren arbeitet man da
dran im Wesentlichen. Und
die Frage ist halt, wie dieses Protein
dann dreidimensional ausschaut, weil das bestimmt
ganz viele der Eigenschaften dieses Proteins
und das kannst du nicht blutfaust rechnen,
weil der Lösungsraum halt irgendwie 10 hoch
1000 ist
und die haben
jetzt eben so eine Technologie
vorgestellt, wo man in, ich glaube, vier Tagen
haben sie, vier Tage Rechenzeit haben sie reingesteckt
und dann haben sie im Schnitt
bei so einem, da gibt es dann so einen Benchmark
und so einen Wettbewerb, wo sie
im Schnitt 92%
Übereinstimmung hatten,
wobei 92% Übereinstimmung, das hört sich
niedrig an, aber ist wohl extrem hoch,
weil die Messwerte, die man so rauskriegt,
sind auch immer nur im Bereich zwischen
90 und 100 Prozent Übereinstimmung. Also es ist im Wesentlichen
wie ein Messwert, den man
da rauskriegt. Und das ist eben tatsächlich eine Sache,
die man vorher nicht konnte und die es einfach nicht
gab. Und
die auch in der Medizin sehr, sehr, sehr,
sehr, sehr nützlich ist, weil du dann
eben nicht die Moleküle
synthetisieren und untersuchen musst, was
sehr aufwendig und sehr teuer und sehr schwierig
ist, sondern du kannst halt sagen, hier, wir haben
so eine Gensequenz gefunden, wie sieht
denn das Ding aus?
Und das ist so, also es wurde wie gesagt
beschrieben als so einer der ersten richtigen
Durchbrüche von AI-Technologie,
von Machine Learning-Technologie,
wo jetzt was möglich ist, was vorher
einfach nicht möglich war.
Das heißt, man kann tatsächlich irgendwann einen ganzen
Körper brechen irgendwann mal vielleicht so.
Ja, aber also
das wurde halt dann sozusagen
so vorgestellt als, oder das habe ich gesehen,
ich habe dann halt so den, man hat
den Fortschritt gesehen als so ein Graph
Und dann, die letzten beiden Geschichten waren halt deutlich besser und jetzt halt das letzte so gut wie fast ein Experiment oder quasi genauso gut. Und jemand hat beschrieben, das ist dann halt so, dass der ImageNet-Moment für Proteinfaltung, also wo man halt sieht, okay, jetzt ist es so gut, dass man tatsächlich was damit machen kann.
und bei ImageNet war es ja auch so, also
bevor Deep Learning
da irgendwie, man da mit rangegangen ist,
waren die Ergebnisse einfach, man
konnte es nicht verwenden. Und das war halt bei
diesen Proteinfaltungsgeschichten auch immer so, da war die
Genauigkeit 40%, 50% oder so,
ja schon, es geht so ein bisschen was, aber es hat halt nicht,
war halt, man konnte es nicht verwenden und jetzt ist
es halt so weit, dass man es tatsächlich verwenden kann.
Und ja, das ist natürlich
schon beeindruckend. Ja, DeepMind, auch interessant,
ist von Google gekauft worden,
die haben wir schon,
die hatten doch auch schon AlphaGo gemacht.
haben die gemacht, genau, Alpha-Code-Zero,
ja.
Ja, spannende Sache,
aber hat nichts mit Paisen zu tun, also zurück zum Thema.
Hunde wollt ihr ewig leben, ja.
Tja.
Ja, das ist doch gar nicht so schlecht, also so ein Protein-Fighting,
da kann man auch bestimmt einige Sachen machen,
die den Körper verjüngen oder sowas, das ist bestimmt ein gutes
Geschäftsmodell, wenn man da relativ weit vorne ist.
Ja, jetzt gerade ist es vor allem
spannend, weil man da halt auch
mRNA-Sequenzen mitbrechen kann und
hat welche, die richtige ist.
Gut, gut, ja.
ja, da geht einiges
genau, ansonsten
eine Geschichte und da, das ist ja schon fast
eine Überleitung zu
dem Thema
es ist eine neue Release rausgekommen von
Phoenix Live View
vor kurzem
ich gucke da ab und zu auch mal so ein bisschen
rein, weil ich mir dieses ganze Elixier
Erlang-Ding halt auch so ein bisschen angucke
und
das hat jetzt zum Beispiel
auch File Uploads drin
Oh, das hört sich
voll interessant, das hört sich total nach
Yagni an, ah, Pfeil Uploads
das machen wir in Release 12, das braucht
kein Mensch. Ja, ja, ja
das hat mich jetzt auch gewundert, ehrlich gesagt, dass das
noch nicht drin war, oh Gott
ja, jetzt ist es drin und das ist auch tatsächlich sehr schick
also, ja, aber
genau, genau, da
hat sich auch noch ein bisschen was getan
Ja, vielleicht musst du nochmal kurz sagen, was Phoenix überhaupt ist
Ja, das ist halt sozusagen das Standard
oder ich weiß es nicht genau, jetzt
bloß nichts Falsches sagen.
Ich kenne mich ja jetzt mit Elixier nicht so aus, aber es ist halt
so das Web-Framework, was man halt, also
Elixier ist halt ein
Dialekt oder, sagen wir mal,
so eine etwas anders aufgemachte
Sprache, die aber auch
auf dieser Erlangen vor allem läuft und
oder auf der, ja, genau, und
zu Erlangen runterkompiliert
und Phoenix
ist halt sozusagen das Standard-Web-Framework
dafür. Und was ist Erlangen? Kann man
das essen? Ja, Erlangen ist halt auch so
eine Sprache. Die Ericsson-Language.
Genau. Wer oder was ist Ericsson?
Ericsson ist der
große Telefonhersteller.
Der große Telefonhersteller aus
Norwegen, glaube ich.
Woher kommt Ericsson?
Und ich weiß nicht genau, wann das entwickelt wird.
Er ist natürlich ein Sony-Ericsson.
Ach.
Ja, und
ich glaube, das ist
schon ziemlich lange her.
Anfang der 80er, weiß nicht, oder irgendwann dann so
Schweden.
Da gibt es ein ganz, ganz, ganz geniales Video aus den 80ern,
wo sie das demonstrieren, das ist R-Lang-System.
Mit der Ästhetik
der 80er, aber mit der Technologie, die
heute, also wenn ich das
programmieren müsste, was die damals zeigen,
wüsste ich nicht genau, wie ich es machen würde.
Ja, ist schon mal ein
R-Lang-Nehmen.
Ja.
Und das ist halt auch heute noch,
immer noch, es ist gerade sehr hip im
ganzen Lab-Umfeld, so für Backend-Geschichten,
deswegen war das halt,
weil man quasi, naja, so sehr, sehr
robuste Concurrency-Geschichten
halt geschenkt kriegt und
so, ich meine zum Beispiel
WhatsApp ist da drauf halt gebaut
und so, ne, und
Das wurde doch für, also das hat Erlang,
das hat Ericsson doch für seine Telefonsystem-
Backends gemacht. Für die Telefon-Switches ist das
eigentlich gebaut worden, ja. Genau, und da, die dürfen halt nicht
abstützen. Also ich meine, wenn die abstützen, dann ist halt
echt blöd.
Deshalb ist das so robust.
Da gibt's auch einige, es gibt auch einige
Multiplayer-Gaming-Systeme,
wo die Backends in Erlang geschrieben sind.
Einfach, weil die nicht abstürzen dürfen und skalierbar
sein müssen. Ja, man sieht
die ja nicht. Das sagen immer nur Firmen wieder
hier, wir benutzen Erlang, um unsere Backends zu
programmieren, aber die siehst du ja nie.
Na gut.
Ja, also ich habe gerade mal bei Wikipedia geschaut und da steht
auf der Übersichtsmap, die
ziemlich hässlich ist, Environment
CCC. Auch
interessant. Crackers Competitors
Costumers wollten die wohl sagen, aber naja.
Das nur so am Rande, kleiner
Joke. Okay. Aber Jochen
kompiliert das wirklich zu Erlang
runter oder kompiliert das direkt zu Beam?
Weil die VM heißt ja Beam VM.
Ja, ich meine,
ich meine,
es kompiliert erst nochmal zu Erlang runter.
Und dann, aber
ja, genau.
Ich gucke dann immer nur so drauf.
Zu Beam. Beam me up, Scotty.
Was ist denn jetzt wieder Beam?
Ja, das ist die VM, die Erlang ausführt.
Das ist so wie C-Python.
C-Python, niemand interagiert je mit
C-Python, obwohl wir alle immer mit C-Python
interagieren, aber das ist das
eigentliche Programm, was das ausführt.
Bei Erlang und Beam ist es genauso. Bei Erlang heißt es halt
nicht C-Erlang, sondern es heißt
halt Beam. Und dann laufen
Dinge wie Elixir auf Erlang.
Genau.
Und Elixir ist das Django für Erlang.
Nee, Phoenix. Das ist das Django
sozusagen für Elixir.
Das Django für Elixir.
Elixir wird auf Erlang und das läuft dann auf Beam.
Genau. Und Beam läuft auf?
Ich glaube, da gibt es auch irgendwo OTP oder sowas
Ja, ich glaube, dass das die Bibliothek ist.
OTP ist die, wenn ich das recht weiß.
Aber ich lasse mich gerne in den Kommentaren.
Genau, das müssen wir uns alle dafür schlagen.
Das ist wieder so ein neuer Namespace.
Also ich habe überhaupt keine Ahnung, wofür ihr gerade redet.
Ich fühle mich etwas abgehängt.
Ja, das macht nichts, dann fühlen wir uns besser.
Ja, also genau.
Eigentlich ist es auch nur, es ist halt deswegen interessant,
weil es halt sozusagen für Async und
diese Geschichten halt so das,
wo man immer sagt, das ist ein Goldstandard,
da funktioniert das richtig gut und alle, die das da machen,
sind immer so begeistert und schauen auf die anderen herab.
Dann muss man auch vielleicht mal gucken, was das eigentlich so kann.
Und
ja, deswegen gucke ich mir das auch gerade so ein bisschen an,
um das halt ein bisschen miteinander vergleichen zu können, alles.
Und genau,
dazu vielleicht auch gerade noch eine Überleitung
zu so einem Podcast
Software-Thema,
weil es gab schon mal einen Versuch,
also
noch mal eine Ecke
ausholen. So eine
der populäreren Geschichten, wie man Podcasts
hostet, ist ja irgendwie
der
Podlove Publisher oder es gibt ja
natürlich unterschiedliche Teile, was dieses Hosting betrifft,
aber so das Ding, was sozusagen
die Feeds generiert und
ja
irgendwie auch den ganzen Website-Teil
so zum Großteil macht.
Das ist halt so ein
WordPress-Plugin.
Vielleicht habe ich schon mal gehört, dass von Tim Püttler
auf der Cars-Radio-Expo...
Ja gut, der hat das Projekt mal initiiert.
Da haben natürlich eine Menge Leute
dran irgendwie geschrieben.
Und genau,
naja,
also man kriegt halt so Probleme, wenn man jetzt
irgendwie WordPress und dann Plugin hat.
Also dazu gibt es
jetzt auch einen ganz interessanten
Podcast.
Padlovers Podcast heißt der irgendwie.
Und da wurde über die Geschichte auch schon so
einiges erzählt. Und ich habe mir
das halt mal angehört, weil ich dachte, für mich ganz interessant,
weil ich diesen ganzen Hosting-Teil,
den Publisher-Teil ja sozusagen in Django
irgendwie
gebaut habe. Natürlich
nicht das, was das Ding macht, aber halt so rudimentär,
dass man damit halt irgendwie
für die Anforderungen, die wir haben, das halt so halbwegs hinbekommt.
Und
ja,
dachte, vielleicht kann ich da so ein paar interessante
Anregungen mitnehmen, was man da eigentlich alles noch so tun kann
und worauf man aufpassen muss und so.
Und ich fand das sehr unterhaltsam
und ich fand es auch interessant, in welche Probleme
sie dabei reingelaufen sind.
Zum Beispiel
einfach mal so ein bisschen so, ich meine,
oder könnt ihr euch das schon vorstellen, was man so für Probleme
kriegt, wenn man WordPress als Hosting-Plattform
nimmt und dann ein Plugin hat?
Nö,
ich glaube, da gibt es keinerlei
Sicherheitsprobleme mehr und auch keine
Interabhängigkeiten
und auch keine Dependency-Hell,
gar nichts. Ich glaube nicht, dass das, nö, ist nicht.
Dass er klick, klick und funktioniert?
Ja, also das ist halt
so eine, es ist natürlich super
zugänglich und es funktioniert überall
und insofern
kann ich das natürlich in gewisser Weise verstehen, dass man das macht,
weil man halt sozusagen, wenn man
nicht benutzt wird, dann hilft einem
das ja natürlich auch alles nicht.
Aber wenn es dann benutzt wird
und es ist halt ein WordPress-Plugin, dann hat man
halt auch einen Haufen Probleme, die man sonst nicht hätte.
Unter anderem also der arme
Mensch, der das dann erzählt hat, ich hätte jetzt leider den Namen
auch gerade nicht parat, der da schon
ganz lange dran rumentwickelt,
Und erzählte dann so, ja, also wir haben das, also irgendwann wollten Leute dann so Statistik haben auch und dann liefen aber die Statistik-Jobs irgendwie so ein bisschen länger und naja, normalerweise so WordPress, das läuft dann halt auf Hostern irgendwo und die beenden die Prozesse halt immer so nach einer Minute ungefähr.
Und normalerweise ist das kein gutes Zeichen, wenn dein Web-Request länger als eine Minute läuft und dann schießt man den lieber weg, weil wahrscheinlich ist der eh kaputt. Und naja, du blockierst ja auch einen Worker komplett sozusagen und das sind ja Shared-Hoster und da gibt es ja ganz viele Leute und dann blockierst du ja die anderen Ressourcen.
Das heißt, ja, nicht so gut und jetzt musst du halt aber irgendwie um diese Beschränkungen drumherum programmieren, weil sowas wie Background-Tasks oder irgendwie Task-Queue-System oder so hast du halt nicht.
Du hast halt auch nicht irgendwelche Maschinen mit Workern, die dann halt Sachen abarbeiten oder so, das gibt es halt einfach alles nicht und du musst halt alles in Requests abhandeln.
Das heißt, du musst darauf warten, dass ein Request vorbeikommt und dann guckst du halt in eine Kontakt-Tabelle und guckst halt, ob jetzt gerade irgendwas laufen muss und wenn ja, dann läuft das halt in deinem Request.
und derjenige, der
die Webseite aufgerufen hat, der hat halt ein bisschen Pech gehabt
und der muss halt länger warten
und, aber du musst halt aufpassen, wenn das
länger dauert als eine Minute oder wenn du dich diesem Bereich
näherst, dann wird es halt knifflig
und dann hat er dann irgendwie so ein Katz-und-Maus-Spiel
gebaut, wo man
dann so einen Prozess wegforkt
nach kurz vor
60 Sekunden und dann wieder
berechnet, berechnet, berechnet, alles wieder serialisiert
wieder wegforkt und dann sozusagen
dem Kill immer wegläuft
und das ist natürlich schon
Also ich meine, ja.
Ja, ist eine lustige Übung, würde ich mal sagen.
Ja, kann man natürlich machen.
Oder halt eben auch so Dinge wie,
ja, sie wollten irgendwann die Podcast-Logos anzeigen
und da gibt es ja die von iTunes geforderten Größen,
das sind so 3000 mal 3000 Pixel, das ist ein bisschen groß.
Dann siehst du, okay, das rechnen wir einfach ein bisschen runter
und dann, ah, oh Mist, so einfach kann man das aber nicht machen.
Man muss ja irgendwie berücksichtigen, dass
auf unterschiedlichen Monitorgrößen
die Dinge unterschiedliche viele Pixel haben müssen
und so. Und wie macht man denn das? Und was ist denn
die Standardlösung von WordPress? Und dann haben sie gesehen,
oh, es gibt keine. Und
das Problem hat mich ja auch schon,
das ist auch etwas, wo ich bei Django etwas überrascht war,
dass es da einfach nichts gab.
Und ja,
dann mussten sie das halt auch irgendwie selber
bauen. Wo man sich denkt, oh ja, das Problem hatte ich
halt auch schon, das habe ich dann auch selber bauen.
Aber was
das Ganze halt deutlich schwerer macht, ist halt, wenn du
nicht selber das alles installiert hast und deine
Abhängigkeiten definiert hast, dann hast du halt
machst du das vielleicht mit Image Magic
oder so auf
in zehn unterschiedlichen Variationen
über alle möglichen Hoster, die halt alle möglichen
unterschiedlichen Versionen
davon installiert haben
und dann musst du
halt Code schreiben, der mit zehn
unterschiedlichen Versionen von irgendeiner
Bildbearbeitungsgeschichte klarkommt, was natürlich totaler
das ist natürlich
gruselig alles.
Ja, depende sehr.
Ja, und genau, all diese Dinge und ja, ich meine, kann man sich ja auch mal selber anhören, wenn das, also es war schon interessant und ich fand das auch total cool, was sie da alles irgendwie mit hingekriegt haben und da rausgeholt haben.
Auf der anderen Seite würde ich jetzt sagen, wenn man jetzt nochmal anfängt mit sowas, dann nimmt man doch vielleicht lieber irgendwie ein richtiges Framework zum Entwickeln von Webseiten und nicht irgendwie ein Wordpress.
Plug-In, ne? Also...
Naja, das Problem ist, was du jetzt gerade gesagt hast,
nimmt man vielleicht lieber, ist natürlich nett, wenn man
dann weiß, wie es geht. Ich glaube, das ist so die größte...
Nee, ich glaube, das war tatsächlich Absicht,
dass das so... Weil
die Frage war, wie kommt
man halt zu einer User-Basis?
Und das geht
halt nur, wenn man dahin geht, wo die Leute sind
und die sind halt bei WordPress. Oder waren sie auf jeden Fall
zumindest damals
zu mehr oder weniger 100 Prozent.
Ja, ich weiß nicht, ob sich das groß geändert hat.
Ja doch, es gibt mittlerweile Hoster.
Es gibt zum Beispiel Podigy
als Podcast-Hoster,
der inzwischen auch relativ groß ist
und
einer der Gründer davon
war halt auch bei einem von diesen
Podcast-Episoden zu Gast
und der erzählt dann so, ja,
wir haben das dann auch gemacht,
irgendwie so Podcast-Hosting irgendwie mal gebaut,
aber wir haben dann Ruby on Rails genommen und da dachte ich mir so, ja,
okay, das ist schon mal
eine deutlich bessere Wahl. Also ich würde
auch, also wenn ich so spontan sagen müsste,
so Ruby on Rails ist wahrscheinlich eine gute Wahl
oder eben Django wahrscheinlich auch,
um sowas zu bauen, weil da hat man halt einen Großteil
von dem ganzen Kram, den man braucht, der ist da halt
schon einfach drin.
Oder nachladbar zumindest.
Ja, und man hat halt
Wege, damit umzugehen
und das macht es halt dann
natürlich schon mal deutlich einfacher.
Auf der anderen Seite ist es dann halt so, wenn du
jetzt aber eigentlich
die ganzen
Podcasts,
Blogs, die es da draußen gibt, unterstützen möchtest,
in dem, was sie tun. Ja, ist halt schwierig.
Da musst du halt dann irgendwas für WordPress entwickeln.
Das ist natürlich nicht so einfach. Also ich weiß es nicht.
Ich habe keine Antwort darauf.
Ja. Aber ich fand es halt
interessant, dass das halt, wie sich das
da so entwickelt hat. Und
deswegen kam ich eigentlich drauf.
Die haben dann nochmal versucht, das alles komplett
neu zu bauen. Und zwar in Elixir.
Aha. Ja.
Die Katze beißt sich in den
Schwanz. Genau. Und
eigentlich eine ganz gute Idee.
Aber das ist dann irgendwie auch
nicht so richtig
dann fertig geworden.
Aber im Prinzip würde ich auch sagen,
ja, so Elixir klingt schon mal deutlich besser.
Das hast du dann nicht gemacht, weil man das mit Asynch
so toll machen kann, bei Elixir?
Ja, weil du damit halt auch
die harten Probleme lösen kannst.
Du quärst dich mehr krass mit dem Maus-Unterherspiel.
Ja, nee, das ist gut, aber
das ist nochmal eher solche Sachen
wie, du willst ja auch zum Beispiel die Files
irgendwie
distributieren, zum Beispiel.
Und du kannst
natürlich ein CDN nehmen, aber ich merke das jetzt auch
irgendwie, so CDN ist halt
einmal teuer und
ja, also weiß nicht,
wäre eigentlich schon cooler, das selber
machen zu können, aber dann ist halt wieder blöd.
Also das kannst du dann nicht irgendwie mit einem WordPress-Plugin
machen, da kannst du keine Files haben.
Oh, kann man schon, aber
das...
Was ist mit einem selbst gecodeten Minio oder sowas?
Ja,
ja, ja, gut, aber
es ist halt auch kein CDN, hast du auch
keine, wenn du globale
Infrastruktur haben willst.
Also du meinst, die Verteilung über mehrere Länder hinweg ist sonst
kompliziert?
Ja, auch generell die schnelle Anbindung,
wenn du halt sehr viele große Dateien
hosten willst, ist nicht
ganz simpel, das performant
hinzukriegen. Der Vorteil bei Elixir wäre halt,
du kannst halt alles damit machen.
Du kannst halt da dein
File-Verwaltungs-Dings mitmachen,
genauso wie dein Backend für
irgendwie dein Frontend
du musst eigentlich nie
diese Umgebung verlassen
und kannst darin halt alles bauen.
Ja, aber warum ist das denn so? Warum ist das denn für alles geeignet?
Das hört sich so an, als würdest du den Podcast umbenennen wollen.
Noch nicht, nein.
Lernst du denn Elixier
oder ist es nur Neid, der aus dir spricht?
Ja, es ist schon Neid
auch, ja.
Kann ich verstehen.
Ich habe tatsächlich auch
hier so Elixier in Action oder sowas, Buch rumliegen.
Ich habe auch schon mal reingeguckt, aber ich habe es noch nicht.
Das diffundiert jetzt dein Kopfkissen durch in deinen Kopf.
Genau, das hoffe ich mir davon.
Mal schauen, was ist die beste Methode.
Ich habe auch noch so ein, zwei Bücher
unter dem Kopfkissen.
Bei Alexi habe ich auch immer das Gefühl,
ich hätte gerne die Zeit schon reingesteckt,
das mal gelernt zu haben, aber jetzt
habe ich doch auch keine Lust, das gerade jetzt zu machen.
Ja.
Ja, aber Jochen, erklär mal, warum ist das so?
Ja, Kekse
sind ein großes Thema.
Also was halt auch
eben, weshalb ich das jetzt auch so betont habe,
Man kann damit halt alles machen. Du kannst damit halt auch
Files surfen und kriegst halt, also zum Beispiel
irgendwie nehmen wir dieses Problem von Hand mit dem
Django-Channel ja auch schon ein paar Mal
irgendwie private Files surfen
oder sowas.
Wenn du das jetzt irgendwie,
nehmen wir an, du nimmst jetzt mal Django als
deine Podcast-Hosting-Plattform
und jetzt willst du aber sowas
auch haben, vielleicht wie private Podcasts
oder keine Ahnung, wenn es sowas gibt, keine Ahnung, ich weiß es
nicht, aber du willst irgendwie den Zugriff beschränken.
Oder Bilder oder so von der Familie.
Deine geheimen Vertragsdaten.
irgendwie sowas, dann
ist das halt nicht mehr so ganz einfach,
weil die Files kannst du ja
auch nicht mit Django direkt ausliefern, wenn du das
jetzt mal so die Folgen erst abgreifst. Kannst du schon.
Ist halt aber dann
nicht so gut, wenn da tausend Leute gleichzeitig drauf
zugreifen. Wenn da viele Leute gleichzeitig
drauf zugreifen, geht das nicht so gut.
Auf der anderen Seite kann eigentlich nur
Django bzw. der Applikationsserver entscheiden,
ob jetzt irgendwie... Privat, viele Leute gleichzeitig,
hatte ich auch irgendwie gerade so ein bisschen, ja.
Ob ein Request autorisiert ist oder nicht.
Der Dominik bezweifelt unseren Erfolg.
Wie, warte, wieso?
Naja, also das ist...
Privat und viele Leute gleichzeitig.
Natürlich, in unserer coolen Gang laden viele Leute...
Das passiert relativ schnell.
Das passiert möglicherweise schon mit einem Browser,
kriegst du das halt schon hin.
Also wenn du halt irgendwie da, weiß ich nicht...
Wenn du mittlere Maustaste hast, dann mach dir einen neuen Tab auf.
Ja, wenn du einen neuen Tab aufmachst.
Ja, auch wenn du jetzt zehn Bilder auf einer Seite hast,
dann ist es schon vorbei.
Das heißt, du kriegst das schon mit einem Browser hin.
Also wenn du jetzt, ich weiß nicht, wie viel Worker du normalerweise hast,
wenn du jetzt eine billige VM hast
auf Hetzner oder weiß ich nicht,
dann ist es halt, wenn du da nur
ein paar Prozesse laufen hast, dann sind die halt schon mit einem
Request ausgelastet.
Was ist jetzt mit Xcent-Pfeil
noch? Genau, das wäre dann halt
sozusagen eine Möglichkeit, das Problem zu
lösen, dass man halt, dass der
Request an den Applikationsverfahrer geht, der
überprüft, ob der autorisiert
ist oder nicht und schickt dann halt einen
Header zurück in der Response, ja,
also dieser Request
sah gut aus und dann geht jetzt irgendwas
was in der Proxy-Pipeline in Nginx
oder so hin, sieht diesen
Header in der Response und sagt,
ah, das war eigentlich eine File-Response,
aber der Applikations-Server kann ja jetzt keine
Files zurückschicken, das wäre ja blöd.
Dann bleibt da ja die ganze Zeit die Verbindung offen
und es gibt nicht so viele Applikations-Server.
Daher nehme ich jetzt mal diesen Request,
diese Response und tausche die aus durch
eine File-Response
mit dem echten File, auf das ich Zugriff habe
und schicke das zurück.
Ja, so ist die Konfiguration dann doch wieder
eigentlich relativ blibberle, weil in den X
einen Eintrag macht, der dann dieses
X-File-Response-Send-Dings
macht. Ja, aber auf jeden Fall Nginx benutzen.
Genau. Geht das nicht mit Kendi?
Aber Jochen, warum ist denn das jetzt besser?
Warum ist denn das besser, wenn der
Nginx das macht, anstatt dass unser
Django, unser Glydekorn oder sowas...
Bei dem Nginx ist das halt egal, wenn da
tausend Requests reinkommen. Aber warum?
Warum ist es dem egal und warum ist es uns nicht egal?
Ja, deswegen, weil halt
sozusagen eine Verbindung den Nginx
nicht blockiert. Also selbst wenn
er da Daten zurücksendet, dann kann
er das auf tausend Verbindungen gleichzeitig
tun. Das geht aber jetzt bei einem
normalen Django-Applikationsserver
so nicht, sondern da ist der Prozess
komplett geblockt, weil der halt synchron
Sachen rausschreibt. Das heißt, das müsste man
einen ASCII-Django nehmen.
Der ist quasi
besser parallel als...
Ja, also
der macht halt parallel I.O.
Und das geht
mit Django erstmal so
nicht. Das geht jetzt inzwischen auch so ein bisschen, aber
erstmal nicht so einfach.
Und das Problem,
was ich damit habe, sozusagen aus der Systemperspektive,
ist halt, du musst
halt einfach nur, um diese Konfiguration
dann testen zu können, dass, wenn du das
jetzt lokal überprüfen willst, funktioniert das denn alles
so, wie ich das gedacht habe, dann musst du dann
Nginx hochfahren und eine Datenbank
und dann deinen Applikationsserver
und ein Caching. Ja, du brauchst es wesentlich
nur in einer Staging-Umgebung testen, oder? Also
in einer Develop-Umgebung
hast du die ganzen Bauteile ja normalerweise
nicht. Ja, und das kannst
schon, dann fährst du halt einen Haufen Docker-Container hoch, geht schon.
Ja, gut, aber das machst du ja nicht zum
entwickeln, sondern das machst du ja wirklich nur zum überprüfen.
Ja, naja,
also, aber
kann man nicht alles machen. Also gut, ich mach das nicht.
So, ich stelle Docker-Compost ab und dann ist
die ganze Liste, die in der YAML drin ist, die wird dann einfach mal
hochgefahren. Ja,
der Punkt ist nur, es ist halt... Ja, das mach ich schon auch, aber
es ist halt ein Haufen... Wenn 3 oder 4 so Dinge laufen
hat, dann ist schon der Speicher voll.
Jaja, also es ist halt aufwendig und
es ist halt auch irgendwie eine komplizierte
Konfiguration und es ist halt fehleranfällig.
und wenn du jetzt
Elixir verwendest,
dann ist das halt alles,
dann kannst du das lokal testen, du kannst
lokal das entwickeln und du kannst
deployst es so produktiv,
natürlich vielleicht mit einer etwas anderen Konfiguration, aber
mehr oder weniger genauso, wie du es lokal getestet hast
und wenn das dann lokal funktioniert, dann funktioniert das
dann auch und du brauchst keine komplizierte Architektur mit
irgendwie noch drei anderen
Teilen, die halt zusammen
funktionieren müssen, damit es klappt insgesamt
und das hat natürlich schon einen gewissen Reiz.
Also ich meine, ich
entwickle auch viel mit Docker, weil das
halt, ja, ich meine, bei ganz
vielen Leuten wahrscheinlich so das Mittel der Wahl ist, um halt
Entwicklungsumgebung zu vereinheitlichen. Und bei mir ist
das so, also das lüftet,
also mein Laptop lüftet einfach die
ganze Zeit. Ich dachte, er hat keinen Lüfter mehr. Ach so,
stimmt, das war noch mal. Und wenn ich das vom Strom
abstecke, dann dauert das eine Stunde und dann ist der Akku leer.
Und das ist halt irgendwie eigentlich
kein schöner Zustand. Aber so ist
es halt. Also das ist bei mir nicht so,
Jochen. Da ist
eine andere Konfiguration.
Ich sage mal, es ist eine andere Konfiguration.
Ich versuche auch gerade so ein bisschen wieder von dem Docker-Zeugs runterzukommen,
weil das ist halt echt das...
Ach ja, und jetzt bei den neuen
Macs geht das ja auch gar nicht mehr.
Die haben keine Virtualisierungsunterstützung.
Okay, cool.
Wie war der Fortschritt?
Es gibt keine Virtualisierungsunterstützung, also kein Parallels
oder was?
What? Wegen ARM? Warum?
Ja, ich weiß
nicht, ob das noch kommt oder so, aber
einen Tag gibt es das auf jeden Fall nicht.
Ach cool, dann muss man sich endlich einen anschaffen.
Wirklich nicht. Keine Methodisierung.
Brauchst dann zwei Macs, einen für
Windows und einen für
Microsoft.
Ja gut, aber das sind ja jetzt alles nur, also ich meine,
wie man seine Entwicklungsumgebung betreibt
und warum man das wie macht,
das ist ja so ein bisschen freigestellt. Aber
der eigentliche
Hintergrund ist doch halt wirklich der,
dass man in Python einfach daran
gebunden ist,
dass jeder Worker einen Request
bearbeiten kann, weil die halt nicht parallel
arbeiten können. Und in Elixir
ist es halt nicht so, weil die
VM, auf der das läuft, halt super
parallel ist, weil die alles gleichzeitig machen können.
Auch hier wieder mit dem Hintergrund halt,
dass das aus einem Telekommunikations
Background kommt und wenn
die Hardware nur ein Telefonat
gleichzeitig machen kann, dann ist das
halt ziemlich blöd und
es ist besser, wenn man tausend Telefonate gleichzeitig
macht. Das erinnert mich an die 90er, wo mein Dad
mich die ganze Zeit angeschrien hat, geh aus dem
Internet, ich will telefonieren.
Und wenn ihr da halt so einen Knotenpunkt gehabt
hättet, dann hättet ihr vielleicht mehrere
Sachen. Aber so Telefonate
haben ja auch üblicherweise sehr strenge
Real-Time-Anforderungen. Das heißt,
es reicht ja nicht, tausend Sachen gleichzeitig
zu machen, sondern du musst ja tausend Real-Time-Sachen
gleichzeitig machen.
Und dann ist dieses
sowieso schon schwierige Problem nochmal direkt
ein kleines bisschen noch viel schwieriger
geworden.
Und
das ist so ein bisschen für mich das Coole an dieser
ganzen Erlangen-und-Elixir-Sache,
weil die halt einfach eine Basis haben,
eine VM haben, die
knallhart darauf ausgerichtet ist,
tausend Sachen gleichzeitig in Realtime zu
machen. Und wenn man das
braucht, dann ist das eine absolut geniale
Sache. Und das ist, glaube ich, eben in so einem Web-Umfeld
kann das wirklich was sein, wo man das einfach ausnutzen
kann, wo du halt wirklich sagen kannst, okay,
da kommen Dateien rüber, da kommen
Authentifizierung rüber, da kommt alles
drüber.
Und
ja, das ist auch so ein bisschen die Faszination,
das ist der Grund, warum ich das gerne mal
gelernt gehabt hätte.
Ja, oder noch ein Beispiel, wo das vielleicht ein bisschen deutlicher wird. Ich habe jetzt gerade nochmal kurz drüber nachgedacht. Also wenn man jetzt zum Beispiel etwas, was man häufig nicht hinkriegt, es gibt so eigentlich, was man gerne hätte eigentlich, ist dieses HLS, also HTTP Livestreaming.
sozusagen, das ist so ein Standard,
im Grunde, das zackt halt
große Dateien in viele kleine und
aber du brauchst halt Server-Unterstützung
dafür. Wenn du das jetzt gerne
anbieten würdest, sodass Podcast-Clients
das sozusagen nutzen können, um halt
auch auf schlechten Verbindungen
und halt auch irgendwie online Sachen zu streamen,
dann hast du halt, wenn du jetzt ein normales
System baust, sag ich jetzt mal, so eben mit Ruby und Rails
und keine Ahnung, Nginx und so und weißer Teufel,
das hinzukriegen
wird ein echter
Stunt, während
wenn du das halt alles in Elixir machst, dann ist das
halt bloß Code, den du schreibst.
Du musst auch den Standort unterstützen und du musst
es halt irgendwie hinkriegen, aber das ist halt auch
nur dein Applikationscode und nicht irgendwie
ein großes System, was du da irgendwie drumherum
konfigurieren musst.
Und du kannst alle diese Anforderungen damit
in den Griff kriegen. Das ist halt
schon ein gewisser Charme.
Ja,
es ist einfach tief
in einem Web-Server drin.
Du hast einfach
die Fähigkeiten, die du in einem
Nginx hättest. Ich meine, im Prinzip kannst du das ja
alles mit Nginx-Modulen machen. Kannst du ja
Module schreiben.
Nur, dass
die Zuhörer haben gerade eben abgeschaltet.
Die sind schon lange weg. Dann muss man das halt
auch tun und das will eigentlich keiner.
Ja, also okay. Das kann man mit
Caddy und Traffic oder sowas nicht einfach machen.
Was kann man bei alter Alternativen noch?
Nein, leider alles nicht.
Also kannst du auch
in Traffic reinbauen. Musst du dann halt
in Go programmieren.
Caddy ist auch Go, oder? Ja, genau.
Kannst halt auch in Go schreiben.
Können die beide Module, die nachladbare
Module?
Ja, so middleware.
Oder musst du das dann halt direkt selber kompilieren?
Egal. Ja, also ist auf jeden Fall
dann nicht mehr so richtig einfach. Und es ist
halt ganz was anderes als die Applikation, die du dann
normalerweise so schreibst.
Aber genau, also wie kriegt
Erlang das denn jetzt eigentlich hin?
Es verwendet halt das
sogenannte
Actor-Model.
Oh, jetzt.
Du musst auch gleich noch,
wenn du noch besser klingen willst, musst du sagen,
Shared Nothing Concurred Programming via Message
Parsing. Okay.
Ja. Schön, haben wir
jetzt, wissen alle Bescheid, oder?
Fertig für heute.
Nee, ich bin gerade abgestürzt.
Das ist auch so, also das ist was, was man
sehr schnell, ich habe ja mal versucht, Erlang
zu lernen.
Habe es dann
wieder aufgegeben.
Aber das ist so was, das ist so was, so was
Konzeptuelles, was man sehr schnell lernt,
wo man sich aber ungeheuer schwer nur
dran gewöhnen kann. Also in dem
Modell, in dem ich üblicherweise
so lebe und programmiere, in Python,
da schreibt man halt Programm und es wird von
oben nach unten abgearbeitet. Und wenn ich eine Funktion
aufrufe, dann ist es so, wie wenn ich die Funktion
da eben an die Stelle hin kopiert hätte.
Wesentlichen
so, bis auf so ein paar Ausnahmen mit
Rekursionen und Scopes und so, ist das
das Modell, was ich im Kopf habe.
Wenn ich eine Funktion aufrufe, dann ist es so, wie wenn die
da jetzt steht.
Und in Erlangen ist das aber nicht so. In Erlangen ist das Modell so ein bisschen anders. Da schreibt man ein Programm und es besteht aus ganz vielen Prozessen. Und auch was ein Prozess ist, ist da auch erstmal, das wird so ein bisschen, ja ein Prozess ist, stell dir einfach einen Prozess vor.
Und die können sich dann Nachrichten schicken und zwar an ihre Mailboxes. Also jeder Prozess hat eine Mailbox und da kann man sich Nachrichten hinschicken. Und das Einzige, was diese Prozesse machen, ist im Wesentlichen Nachrichten aus ihren Mailboxes abrufen und die bearbeiten und anderen Prozessen Nachrichten in ihre Mailbox reinschicken. Und das ist von der Vorstellung her was total Verrücktes, was total Absurdes, weil wie kann man denn daraus ein funktionierendes Programm machen?
Das könnte man ja in Django auch machen,
indem man irgendwie so einen Cache für eine Datenbank nutzt,
als diesen Mailbox-Layer oder sowas.
Nee, kannst du da nicht machen,
weil das tatsächlich da eine Entsprechung in der Maschine hat,
weil diese Sachen alle gleichzeitig laufen.
Und das ist so ein bisschen die Macht davon,
das Coole davon.
Und Mailboxes und Processes müssen nicht eins zu eins sein.
Das heißt, du kannst an einem Mailbox viele Prozesse ranmachen
oder ein Prozess kann mehrere Mailboxes bearbeiten,
Je nachdem, wie dein System halt gerade an der Anforderung ist.
Okay, aber warum ist das jetzt so cool?
Das Coole ist, diese Prozesse heißen Actor.
Dieses System aus Prozess und Mailbox heißt Actor.
Und das hat eine bestimmte, oder so wie ich es mir vorstelle,
hat das eine bestimmte Zuständigkeit.
Das System ist zuständig für Dateien ausliefern.
Und wenn ich eine Datei ausliefern möchte,
dann sage ich, muss ich es nicht selber machen,
sondern ich schicke nur eine Nachricht an die Dateien
ausliefern Mailbox. Und da ist irgendjemand und der
bearbeitet die dran. Das heißt, wenn
ich entschieden habe, ich als
Anwendungslogik habe entschieden, da muss jetzt diese
Datei ausgeliefert werden, dann
ist meine Arbeit beendet, indem ich eine
korrekt formatierte Nachricht an die Mailbox
Dateien ausliefern schicke.
Dann bin ich fertig.
Und auf der anderen Seite dieser Mailbox
ist halt irgendein weiterer Prozess,
der macht nichts anderes als
da kommt eine Nachricht, ich soll
eine Datei ausliefern an folgende
Verbindung oder an folgende IP oder sonst was.
Also mache ich das. Und dieser Prozess
macht nichts anderes. Das heißt, es gibt
einen Prozess, der ist zuständig für, oder
eine Mailbox, ja, einen Actor,
der ist zuständig für Dateien ausliefern. Es gibt
einen Actor, der ist zuständig für Authentifizierung.
Es gibt einen Actor, der ist zuständig für die Datenbank.
Es gibt einen Actor, der ist zuständig für
was weiß ich, SSL Termination,
was auch immer man haben möchte, ja.
Bühne frei.
Jeder Actor macht eine Sache
und ist für eine Sache zuständig.
Und wenn jemand anders was machen soll,
dann ist es einfach nur eine Nachricht.
So, jetzt könnte man sagen,
okay, das ist ja in einem objektorientierten System
nicht anders.
Ja, da schickt man Nachrichten von Klassen zu Klassen.
Der Unterschied ist,
dass diese Actors selbst laufende Prozesse sind.
Das heißt, wenn ich eine Nachricht schicke,
dann wird die halt gleichzeitig,
die wird jetzt sofort bearbeitet.
Ich muss nicht warten,
bis die Nachricht abgearbeitet ist von der Klasse.
Und das kann ja sehr lange dauern.
Wenn meine View-Klasse aufgerufen wird
und ich eine Datei ausliefern muss,
dann dauert es halt so lange, wie es dauert,
die Datei auszuliefern und dann ist die Nachricht bearbeitet.
Sondern das sind wirklich einfach nur
kurze Nachrichten. Mach das. Mach das. Tu das.
Hier ist was passiert.
Also Events.
Das sind einfach nur
Dinge, die passieren sollen oder Nachrichten,
die in dem System relevant sind und die werden
dann sofort weiter bearbeitet. Und derjenige,
der für die Authentifizierung zuständig ist,
der kann sofort den nächsten Request authentifizieren.
So, das ist die eine Sache. Die andere Sache ist, in Klassen ist es, wenn man eine objektorientierte Architektur hat, dann ist es sehr leicht, Daten zu verteilen. Da gibt es diese, wir haben ja schon drüber gesprochen, es gibt diese Sachen, wie man Klassen aufbauen sollte und dass die abgeschlossen sein sollten und dass die ihre privaten Daten privat halten sollen und das Null-Interface und so weiter.
Aber im Endeffekt ist es ja doch irgendwie so, dass man schon ungefähr weiß, was diese Klasse wie macht. Und auch, was die für Daten enthält. Und dann manchmal ist es halt auch so, dass man auf Daten zugreifen muss, die halt da drin sind und die draußen sind. Das geht in diesem Ektormodell überhaupt nicht. In dem Ektormodell gibt es nur eine Möglichkeit, mit einem anderen Ektor zu kommunizieren und das ist über eine Nachricht. Das heißt, alles, was in diesem Ektormodell passiert ist, du schickst Nachrichten.
Aber die E-Mail-Box kann man dann klonen oder was?
Oder dass die doch gleichzeitig irgendwas machen können?
An der einen Mail-Box, wie du gesagt hast?
Die Mail-Box ist
der Endpoint.
Du schreibst eine Nachricht und du tust die in den Briefkasten
rein und dann bist du nicht mehr dafür verantwortlich.
Also die Worker holen sich ihre Sachen alle raus.
Dass da zehn Leute gleichzeitig
diese Mail-Box bearbeiten, das kann dir völlig egal sein.
Dann hast du so ein
NIFO oder FIFO oder sowas,
eine Methode und kannst dann einfach Dinge da rausnehmen
aus der Mail-Box.
Ja, also davon gibt es
dann sehr, sehr viele. Also das ist halt so, dass
ich weiß nicht,
also Tausende gar kein
Problem, auch Millionen kein Problem.
Und
das ist
also ja,
das kannst du quasi beliebig
hochskalieren, sagen wir mal so.
Man kann die auch dynamisch neu starten.
Die werden auch dynamisch neu gestartet.
Und wenn so einer abbricht, wenn einer kaputt geht,
weil er irgendeine Nachricht nicht verstanden hat,
dann wird der halt gelöscht und einfach ein neuer gestartet.
da, zack, der ist jetzt weg.
Ja, was ja kein Problem ist,
wenn sozusagen,
also was man dazu noch sagen muss,
genau, eine schöne
Eigenschaft sozusagen für dieses Modell,
die halt Erlang da auch direkt mitbringt,
ist, dass da das ja so eine
funktionale Vorbeimersprache ist, ist halt
sowas wie Daten verändern,
das geht halt einfach nicht.
Das ist
prinzipiell nicht möglich.
Du kannst halt bloß Daten kopieren, aber
das heißt, du kannst Sachen auch mal perfekt cachen
und so, weil
und es ist auch egal, wer da was
macht, weil es ist ja sowieso immer nur
das Gleiche, ja, es ist halt nie,
du kannst, es ist nicht möglich, dass jemand hinterher
irgendwie Daten verändert hat und das in einem
anderen State ist oder so,
sondern, ja,
wenn der State irgendwie
kopiert wird und dann macht das halt ein anderer Actor,
ist das halt völlig egal, wer das jetzt war.
Ja, oder auch wenn der abstürzt und
ein anderer übernimmt das, ist egal.
Wir sind alle gleich. Du hast eine Armee
von identisch ausschauenden Schauspielern.
Ja, und
man kann das halt auch nicht umgehen,
weil, ja, das
verbietet einem die Sprache. Es gibt ja auch
sozusagen eine Actor-Implementierung in anderen Sprachen.
Es gibt auch diverse in C++ zum Beispiel, aber
du kannst... Pie-Acker, ja.
Super Sache
übrigens, sollte jeder verwenden.
Okay, ich habe nur gehört, dass es das gibt.
Ich weiß aber nicht, ich wundere, dass es sich an der
Skala-Acker-Geschichte orientiert.
Ja, genau, das kommt von Skala, ja. Wann, wie, wo
benutzt man das dann? Wobei Skala
ist ja quasi Erlangen für
Ja, für die
Wie benutzt man das dann?
Pi-AK?
Ja, wenn du halt
synchrone Sachen haben willst
Das Problem an Pi-AK ist halt
dass das immer noch den Gil beachten muss
Das heißt, du gewinnst nicht so ungeheuer viel
Weil du immer noch in dieser
mehr oder weniger Single-Threaded-Python-Welt
festhängst, aber das macht
die Struktur einfacher
Ja, es löst dich davon ab, alles in einem Ablauf machen zu müssen, sondern du kannst sagen, so, dieses Ding ist jetzt verantwortlich für und das hat folgende Ressourcen fest in der Hand und zack.
Aber was du halt nicht hinkriegen kannst und was das halt so ein bisschen, also ich meine, klar, du kannst natürlich dann sagen, okay, ich weiß, ich darf hier nur immutable Datenstrukturen verwenden und so, aber du kannst natürlich Sachen schon ändern, wenn du böse bist und das geht halt lange nicht.
Ich habe gerade auch eine andere Bibliothek gefunden, die heißt
Tespian. Habe ich aber nicht
reingeguckt, keine Ahnung. Ja, das ist ein Aktor.
Das sind die Theaterschauspieler.
Ja,
genau. Also ich meine, man zahlt da natürlich
einen Preis für. Also man zahlt den Preis
vor allen Dingen in Hauptspeicher.
Man muss halt alles kopieren, wenn man irgendwas verändern
will.
Das ist halt auch das, was
einen im Wesentlichen begrenzt, was die Anzahl
der Aktor-Dinger
halt angeht.
dass man, wenn der Hauptspeicher voll ist, dann ist halt
Schluss
und es ist halt auch ein bisschen langsamer
also wenn man jetzt sagen würde, okay man macht
das Ganze handoptimiert
irgendwie mit Threads oder so, dann ist das
wahrscheinlich schneller, aber
sagen wir mal so, es ist halt ein sehr sehr guter Kompromiss
eigentlich, wenn es um
ja
Dinge parallel
concurrent und in zuverlässig
machen geht
und so diese letztes
das Sequential Performance brauchen die meisten Leute ja dann
eh nicht.
Und dafür ist es halt super.
Selbst dann bist du ja oft in so einer Situation,
wo Stabilität einfach
wichtiger ist.
Und die kriegst du da halt für umsonst
mit dazu, weil das sehr schwierig ist,
diese VM zu crashen.
Und selbst wenn du irgendwas machst,
was crasht, dann hast du halt
diesen einen Request gecrashed.
Aber der Rest läuft weiter.
Es ist quasi nicht möglich,
diese Maschine abzuschießen.
Und das ist schon was, wo man auch mit Neid draufschauen kann, weil das ja in anderen Systemen relativ leicht ist.
Das ist eher so schwer, das Ding irgendwie am Laufen zu halten. Da muss man immer die ganze Zeit fünf Teller jonglieren, während man auf einem Einrad herum, auf einem Seil herumfährt oder so. Ja, das ist da ganz angenehm.
Aber es ist natürlich auch ganz klar ausgerichtet auf so Workloads, die parallel sind. Also eben genau aus dem Telefonieumfeld her. Jedes Telefonat selber braucht halt nicht ungefähr euer viel. Also du musst halt dann irgendwie deine, was weiß ich, 16 Kilobit musst du durchkriegen oder deine, wie viele auch immer sie gerade runter haben. Aber das ist ja nicht viel. Aber du hast halt 1000 Stück davon gleichzeitig in der Hand.
Und in anderen Workloads hast du ja andere Anforderungen, jetzt zum Beispiel Machine Learning, da brauchst du halt eine Sache, die du hunderttausendmal ausführen musst und da ist es besser, Prozessoren zu haben, die das schnell machen können, deshalb hat sich das ja auch so ein bisschen anders entwickelt und ich glaube auch, dass da der Hintergrund so ein bisschen anders ist.
Python kommt ja wirklich aus dieser, ja, ein Programm tut eine Sache Welt und da ist es dann halt einfacher zu sagen, okay, die Programme werden schneller, weil die Prozessoren schneller werden, weil die Single-Thread-Performance schneller wird. Aber jetzt sind wir nun mal genau in so einem Umbruch, wo es tatsächlich so ist, dass eben Single-Thread-Performance nicht mehr schneller wird. Aber dafür kannst du jetzt einen Computer kaufen, der 64 Cores hat. Oder gibt es nicht von AMD sogar schon die mit 128?
Kann gut sein, ja. Das ist, äh, genau, ja. Und das, das, jetzt wird's halt, also, sag mal so, also, äh, das hatten wir in der ersten Sendung schon und ich, äh, würde da tatsächlich, äh, ehrlich gesagt, äh, bei bleiben, also, dass man das selten hat, dass man beides braucht. Also, du kannst ja problemlos 128 Python-Interpreter starten. Also, wenn du 128 Cores hast, dann hast du wahrscheinlich auch genug Hauptspeicher, um, äh, 128 Prozesse zu haben.
Aber da hast du halt nur 128. Kannst du 128 gleichzeitig beantworten? Nicht 12.800.
Aber wenn CPU dein Problem ist und dann brauchst du, ja, also wenn I.O. dein Problem ist, gut, aber dann brauchst du die ganzen Prozessoren eigentlich nicht, dann kannst du das auch auf einer CPU, also naja, ich weiß es nicht so genau, es ist, ja, also ich meine, man hat es selten, dass man beides braucht und für beide Extremfälle gibt es halt sehr gute Lösungen.
Also den Data Science CPU verbrennen Use Case, da gibt es super Lösungen für. Den kann man jetzt nicht zum Websurfen verwenden, aber das funktioniert super.
Sehr schöne Computer von Nvidia für mehrere hunderttausend Dollar. Würde ich nicht als Webserver einsetzen.
Ne, genau, das macht doch nicht so viel Sinn. Und auf der anderen Seite ist halt irgendwie, weiß ich nicht, eben Lib, sozusagen, kriegen wir den Übergang zu Python wieder hin oder halt auch eben Node.js. LibUV ist halt auch auf einem Prozessor, macht das schon irgendwie ordentlich I.O.
Das ist sozusagen die Event-Loop,
die unter Node.js und halt auch
bei Python, also normalerweise
in Produktivgeschichten nimmt man halt immer LibUV
statt der Async.io
Standard-Event-Loop.
Aha, kein Async.io?
Das ist Async.io.
Würdest du Ubicorn verwenden statt
Also kann man auf jeden Fall,
ja.
Also
und
ja, man kann halt, bei Async.io
ist es so, du kannst die Implementierung deiner Event-Loop
kannst du halt austauschen und du
kannst halt entweder die Standard-Implementierung
nehmen oder du nimmst
halt LibUV zum Beispiel und
LibUV ist dann halt deutlich schneller.
Und
ja, also zu der
Historie, ich weiß es jetzt ehrlich gesagt nicht so ganz genau, ich glaube,
es gab einmal LibEV,
das Ding ist auch schon ziemlich alt
und... Aber das ist doch
eine CE-Bibliothek, oder? Ja, ja,
LibUV auch.
Wenn du einfach nur Event-Event-Element
anfängt. Genau,
das ist, die implementieren das sogenannte
Reactor-Pattern irgendwie
und benutzen unten drunter
Syscrolls. Wenn es da mal einen Podcast dazu gäbe,
so Pattern. Ja, ich glaube,
da müssen wir auch noch ein paar Teile irgendwie machen.
Ja, aber vielleicht tatsächlich noch mal genau
was erklären.
was halt das Reaktor-Pattern vielleicht ist.
Und dann vielleicht auch nochmal, was halt Event-Loops
überhaupt sind. Das haben wir nämlich. Genau, das haben wir das letzte Mal,
da haben wir da aufgehört.
Ja, also Reaktor-Pattern.
Das setzt ihr für raus.
Jetzt seid ihr im geneigten Leser-Zug.
Du hast halt so
Syscalls
in Unix.
Da gibt es auch unterschiedliche, je nachdem, welche Unix-Art man
verwendet. Epoch, unter Linux.
Vielleicht nochmal einmal ganz kurz,
Wir müssen doch ein bisschen nur damit anfangen. Was ist ein Syscall?
Oh nein, oh mein Gott.
Jetzt muss man tief reinsteigen.
Also sozusagen, das ist die Art,
wie User...
Ja, mit dem Betriebssystem
kommunizieren. Also
das, was jeder kennt vielleicht, ist sowas wie
du machst einen Pfeil auf.
Du musst jetzt irgendwie an die Bits auf der Platte
tatsächlich rankommen und der
tatsächlich bei Unix ist so der
der Syscall für alles ist halt
open. Also das ist ja auch eigentlich der Trick
bei Unix, dass man sagt so, okay...
einen Syscall. Es gibt nur einen
Syscall. Alles ein Pfeil.
Eigentlich ist alles ein Pfeil, genau.
Es ist völlig egal, was es wirklich ist.
Pfeil ist unsere Abstraktion
für einfach
alles.
Also wenn man das annimmt, dann kommt man
bei Unix ziemlich gut raus.
ja, genau.
Das ist halt die Art, wie man dem Kernel sagt, ich hätte jetzt gerne
da zum Beispiel irgendwie Zugriff drauf.
Dann sagt man halt Open.
Und das kann man eben
dann eben nicht nur mit Files machen, sondern auch mit Netzwerkverbindungen,
die ja dann in Unix auch nur Files sind
oder Hauptsprecher ist auch nur Files oder halt
irgendwie Pipes, Kommunikation
zu anderen ist auch alles immer nur ein File und
also man kommt ja sehr weit.
Der Bildschirm ist auch ein File, oder?
Ja. Und
die Terminals sind auch Files.
Ja. Und
jetzt müssen wir nur noch wissen, was Files sind.
Ja. Das ist
abstrakt. Das können wir in dieser
Vorlesung nicht machen. Es ist ein sehr
sehr, sehr, sehr, sehr simples Interface.
Es ist einfach unstrukturierte Daten und
du kannst darauf zugreifen, indem du
halt Sachen daraus liest und
reinschreibst. Aber sortiert. Sortiert.
Das ist das Wichtige, oder? Du kannst an eine bestimmte Stelle springen.
Eine Abfolge von Bytes. Ich kann hin und her springen, ja.
Ich habe so einen Zeiger, der irgendwie Interface.
Ah, nicht jedes Pfeil kann hin und her springen.
Pfeils können sagen, sie dürfen hin und her springen
oder auch nicht.
Okay, dann habe ich jetzt
ein Cisco, das macht ein Open, okay.
Genau.
Also insofern auch alles schick.
Problem ist jetzt natürlich... Und das ist auch gar kein
Problem, oder, Jochen? Also ich meine, da brauchst du noch
keine Lib dafür, sondern du brauchst halt nur wissen,
wie du das aufrufst. Und das
ist super und nett und easy.
Und wenn du jetzt gegen deine, was weiß ich, Bibliothek,
gegen deine
Kernel-Bibliothek kompiliert hast,
gegen deinen Kernel-Header, dann kannst du die Sachen aufrufen.
Genau.
Warum brauchen wir jetzt LibEV? Warum brauchen wir LibEvent
oder Lib? Ja, das ist
sozusagen eine Abstraktionsschicht über
den Syscalls,
weil das Problem ist, du hast jetzt unterschiedliche Syscalls,
je nachdem, welches Betriebssystem du hast,
die eben so etwas machen wie,
naja, du machst jetzt nicht einfach nur
einen Pfeil auf und schickst da irgendwas, das kannst du auch,
dann ist es aber blockierend und synchron.
Du willst jetzt aber nicht blockierend
irgendwie lesen und schreiben, weil
du möchtest ja gleichzeitig parallel
irgendwie Datenströme in der Gegend
herumschicken, weil wenn du blockierst,
dann kannst du immer nur eins nach dem anderen machen
und das ist ja, wenn du jetzt tausend Leuten
gleichzeitig einen Pfeil schicken möchtest, geht das halt nicht so gut.
Und dafür gibt es dann halt
andere Interfaces,
die das möglich machen.
Und da gibt es dann halt so
die uralten
Geschichten in Unix sind halt so Select,
der Select-Syscall und Poll.
Und im Wesentlichen gibt man
den, oh Gott. Jetzt musst du trotzdem kurz
sagen, was Select ist und was Poll ist.
Also ich fange mal mit Poll an.
Du gibst Poll einfach eine Liste von
Pfeildeskriptoren sozusagen, also
offenen Pfeils eigentlich, mehr oder weniger.
Und dann wirst du irgendwie benachrichtigt,
wenn da irgendwas passiert ist,
vom Kernel.
Und das Problem dabei ist halt, dass, also
bei Paul kannst du halt irgendwie, ach Gott,
das muss ich tief in Erinnerung kramen,
also der Vorteil ist, du kannst halt beliebig viele
Files da reintun, also beliebig viele Netzwerkverbindungen
haben, der Nachteil ist irgendwie, ist es halt
O von N oder sowas, also deine
Zeit,
die das im Kernel verbringt,
wird halt immer mehr, je mehr du da reinsteckst.
Und bei Select war es so,
dass
das schnell ist, das ist halt irgendwie O von 1,
aber du kannst irgendwie nur 1024
Pfeildeskriptoren oder so irgendwie da reinstecken.
Was ist denn ein Select jetzt, also im Unterschied?
Also im Wesentlichen geht es doch darum, dass du
auf Daten wartest.
Das heißt, der Syscall heißt,
du kannst sagen,
ich möchte jetzt die Datei
lesen und dann gibt es einen Syscall,
der heißt ReadData oder wie auch immer der heißen mag
und
der blockiert dann halt, da musst du
so lange warten, bis die Daten da sind.
Und das ist bei einer Netzwerkverbindung echt blöd.
Das willst du nicht, genau.
Dann kannst du sagen, okay,
wir modifizieren den und
sagen, wir machen Read-Data, aber
nicht blockierend. Das heißt, wenn was da ist, dann
kriegen wir das und wenn nichts da ist, dann kriegen wir halt
zurück, es gibt gerade nichts.
Und damit kannst du das ja
umsetzen. Damit kannst du Polling machen, damit kannst du sagen,
hier, alle meine Netzwerkverbindungen,
was gibt's denn jetzt hier?
Aber Polling ist halt schlecht,
weil dann, das ist
aktives Warten.
Busy Waiting, genau, das verbraucht halt CPU.
Ja, und vor allem, während du auf
eins wartest, kann ja bei einem anderen was passieren
und das bemerkst du dann halt erst, wenn du so weit bist,
dass du da bist.
Da steht die ganze Zeit, du sagst, bist du schon da, bist du schon da,
bist du schon da, bist du schon da, bist du schon da, bist du schon da.
Genau, aber wenn du jetzt bei zehn Türen immer anklopfst
und sagst, bist du schon da, bist du schon da,
dann kann es ja sein, dass du bei der zehnten Tür bist
und bei der, oder du bist bei der ersten Tür
und bei der zehnten Tür passiert jetzt gerade was
und du merkst es aber erst,
wenn du die anderen neun alle durchgefragt hast.
Das heißt, du hast nicht nur viel CPU verbraucht,
für was, was eigentlich nichts bringt,
sondern du hast auch noch hohe Latenz drin.
Du kriegst die Nachrichten,
sofort mit, dass irgendwas passiert, sondern du kriegst
erst mit, wenn du dazukommst, danach zu fragen.
Und das ist natürlich schlecht, ja, weil
ähm
weil du dann eben
eine unnötige Latenz hast. Du hast unnötige Wartezeiten,
die du nicht abbrauchst. Und jetzt
wird es noch schlimmer, wenn du das nämlich naiv machst, dann
kannst du so ein Problem haben, das Starvation heißt.
Ja, wenn du sagst, wenn irgendwas passiert,
dann fange ich wieder bei Tür 1 an, nachzufragen.
Und dann passiert das nicht.
Und doch, doch, dann hast du nämlich
Starvation, weil wenn bei Tür 10 irgendwas ist,
da kommst du ja nie hin, weil
die ganze Zeit irgendwas passiert, dann
kommst du nie dazu, Tür 10 nachzufragen. Das heißt, du musst
dann auch noch aufpassen, dass du die
in einer gewissen Reihenfolge
abfragst, die nicht dazu führt, dass
einer hier liegen gelassen
wird. Also Polling ist was ganz Schlechtes,
wenn du auf Daten wartest
in einer Aktivverbindung.
Und deshalb gibt es
diesen Select-Syscall,
wo du eben sagst, benachrichtige mich,
wenn irgendwas von diesen
1024 oder eben
jetzt, wie Jochen sagt,
beliebig vielen, irgendwo was passiert.
Wenn irgendwo
was passiert, dann gib mir Bescheid. Dann kriegst du
quasi einen Interrupt.
Ah. Genau.
Ah, das gab es doch früher immer.
Das war noch so relativ nativ
oder schneller ansprechbar. Das musste man doch früher immer
selber konfigurieren, die Interrupt.
Die Soundfarbe gab es, weil die müssen
halt ihre Daten holen und die sagen so,
jetzt, ich brauche Daten und dann musst du
dich drum kümmern. Da kannst du nicht sagen, ja, ich bin jetzt gerade
beschäftigt mit.
Sonst knackt es der Ton.
Genau, und
also der Syscall, den man auf der Linie
dafür jetzt verwendet, der nennt sich E-Poll, der
halt irgendwie, ja, ist halt
irgendwie Anfang der Nuller Jahre, ich weiß nicht, seit wann
das drin ist im Kernel, müsste ja
irgendwie, aber ist schon sehr lang
und das Ding macht das quasi für beliebig
viele Falldeskriptoren und halt schnell
also das Ding ist richtig, macht
macht Laune, funktioniert
dann alles super und
FreeBSD, BSD-basierte
Unix, die nehmen dann eher sowas wie KQ
also FreeBSD, macOS
macOS und so
macht praktisch das gleiche
Wie was? Entschuldigung, ich wollte das nicht nochmal aussprechen. Der Syscall
heißt einfach anders und der heißt KQ
KQ heißt der, oder? Oder KQ
Ja, genau
Ja, KQ
Die Leute mitschreiben, kleiner Schmutzigeritz
Und
genau, aber es gibt ja subtile
Unterschiede, bei Solaris hast du dann noch sowas wie
DevPol und so, also
unterschiedliche Unix-Geschmacksrichtungen
machen das halt irgendwie so leicht anders alles
und das willst du ja jetzt nicht, wenn du
ein Anwendungsprogramm schreibst, alles nochmal
machen müssen, damit du halt irgendwie alle
Unix-Varianten unterstützen kannst
und dann brauchst du halt eine Abstraktionsschicht darüber,
die halt dann unten drunter mit
den
betriebssystemspezifischen
Syscalls oder Interfaces
redet, aber mit der du
dann reden kannst, ohne das alles wissen zu müssen.
Und genau, das ist halt LibEV.
Und, genau, das war LibUV, also das, was dann, das Ding ist, glaube ich, gestartet irgendwann 2011 oder so, das Projekt, und hat für Unix, für Unix hat es halt LibUV benutzt einfach, das hat es einfach nur gerappt.
Hat aber auch noch eine Windows-Geschichte mit dazu genommen, weil Windows macht das alles irgendwie anders.
Das implementiert
halt nicht dieses
Reaktor-Pattern sozusagen,
wo du halt benachrichtigt wirst, wenn halt irgendwas passiert,
sondern es ist ein
Pro-Reaktor.
Also der Select ist ein Reaktor-Pattern?
Ja, genau. Das sind die alle.
Bei Unix ist das immer so.
Was heißt nochmal ein Reaktor-Trimmer?
Du kriegst halt
benachrichtigt, wenn irgendwas passiert und dann kannst du
irgendwas machen. Warum heißt das Reaktor-Pattern?
Weil du darauf reagierst, wenn irgendwas
passiert. Also du bist in dem Moment
Nicht der Aktor, der aktiv
wartet, sondern du bist der Reaktor. Du sagst,
weck mich auf, wenn irgendwas ist.
Ich hatte irgendwie gerade einen in die Grille
entdeckt, der Reaktor, wir abgeben.
Und Windows macht es halt
anders. Da gibt es diese
IOCompletion
Ports. Da ist auch alles nicht eine Datei,
sondern ein Handle.
Tja.
Und
da ist es halt so, man
kriegt halt, da passieren dann Dinge
und der Kernel macht dann schon zum Beispiel, der liest dann schon, also beim
während bei dem
Reactor-Pattern ist es halt so, da musst du dann schon noch selber lesen,
du kriegst halt bloß Benachrichtigungen, also du könntest
jetzt, wenn du wolltest, dann könntest du erst was lesen und
kannst das halt machen oder nicht.
Und
bei Windows ist es halt so, der Kernel macht das dann
halt und dann
sagt er dir halt, wenn irgendwas completed
ist, was damit passiert ist und wo
es liegt oder so. Ich weiß nicht so genau, keine Ahnung
von Windows. Wenn du das Handle weißt. Ja.
Aber es ist halt eine grundsätzlich
andere Art, damit umzugehen
und da gab es, glaube ich, tatsächlich
auch, hat Microsoft selber, hat da irgendwie
Code beigesteuert zu
LibUV, meine ich, und hat
den Teil halt geschrieben und dann
haben sie das halt unter einem
Interface sozusagen
verfügbar
gemacht und halt LibUV verwendet
für Unix und dann
den Microsoft-Teil für Windows
und sieht dann aber von der
Anwendung gleich
aus. Und später
haben sie dann aber Libby wieder rausgeschmissen, glaube ich,
und das dann selber nochmal alles geschrieben.
Naja, also, wie auch immer.
Also es funktioniert. Inzwischen ist es gut
getestet. Es gibt ja genug
Node.js da draußen und so.
Und es funktioniert gut.
Und es ist halt auch
richtig schnell.
Und was diese Event-Loop tatsächlich
eigentlich macht, ist
eben diese
ganzen
dieses I.O.-Zeugs
verwalten.
aber halt auch Callbacks
aufrufen. Also du kannst zum Beispiel
bei deinem Event-Loop jetzt Callbacks registrieren
für halt... Also ein Event-Loop ist
ein eigener Prozess, der läuft und der die ganze Zeit guckt,
was für Events da registriert sind und die dann
aufrufen, wenn irgendwas passiert, oder?
Das Ding läuft immer,
läuft in,
es kann nur eine Event-Loop pro
Thread geben. Du kannst mehrere
haben, aber nur in unterschiedlichen Threads.
Und
ja, das Ding läuft halt.
Das ist halt sozusagen die innerste Loop
in deinem Programm, wenn du es was benutzt.
Das ist das, was mit LibUV
hintergeht, oder? Das ist die Event-Loop.
Ja, also
LibUV ist eine Implementation, ja.
Also so eine Wild-Schuh-Schleife oder sowas.
Ja, letztlich genau. Das Ding,
ja, wobei das nicht busy-weighted,
sondern das schläft dann halt auch,
wenn nichts zu tun ist, aber
sobald irgendwas zu tun ist, dann wird es sehr
wach und agil und macht irgendwie Dinge.
diese
Einführung
in ASIC.io von Lukas Langer gibt es
halt auch, da zeigt er die Implementation
der Python-Event-Loop
glaube ich aus 3.4 oder
3.5, ich weiß es nicht genau, und das
waren irgendwie so 20
Zeilen, 30 Zeilen Python, und es war
tatsächlich eine While-True-Schleife, und
die hat im Wesentlichen nur gemacht, so geguckt,
oh, welche Callbacks sollen jetzt gerade laufen,
dann hat sie aufgerufen,
dann noch irgendwie Signal-Handling gemacht und
irgendwie, das war es im Wesentlichen.
Und dann noch geguckt, welche sind jetzt beim
nächsten auf, beim nächsten, bei der nächsten
Iteration dran und das war es eigentlich
fast. Und das war die ganze Event-Loop.
Also Event-Loop ist tatsächlich dieser Loop und da muss man
Signale registrieren oder was?
Callbacks sind vor allen Dingen das, was
man da rein
tut, was dann da drin läuft.
Die stehen dann in irgendeiner Liste, die immer wieder
ein gemeinsamer Speicher quasi
der...
Wenn in Datei X irgendwas
was passiert, dann ruf damit diese
Funktion auf. Ja, aber also, wie sag ich das?
Da gibt es halt ein Interface.
Du kannst Call soon
zum Beispiel für, jetzt soll dem nix
laufen oder
ja, mit einem bestimmten,
zu einem bestimmten Zeitpunkt, also die Timer,
du kannst dann auch Timer setzen und die werden halt ausgeführt
und dann wird halt überprüft, ist das jetzt
dran mit dem Laufen oder noch nicht.
Also je nachdem, was halt so eine Event-Loop
anbietet, ja. Also es gibt ja da viele
verschiedene Sorten Events.
Und genau so ein Timer, ja, im Wesentlichen
sagst du halt, wenn du auf so einen
Timer wartest, dein
Python-Programm sagt, ruft
eine Funktion auf, die sagt, ich möchte
um 0 Uhr
möchte ich, dass diese Funktion gestartet wird.
Und dann muss
diese Event-Loop ja im Wesentlichen nichts anderes machen,
als zu sagen, ist es schon 0 Uhr? Nein, ist es schon
0 Uhr? Und wenn es 0 Uhr ist, dann sagt sie
ja, und dann startet eben dieses
registrierten Callback. Diese Funktion und genau.
Und so ein Callback ist einfach
eine Funktion, ja, du sagst, ich möchte
dass eine Funktion aufgerufen wird und die muss
auch normalerweise schon fertig
parametrisiert sein, ja, also du kannst dann nicht
sagen, mit folgenden Parametern, sondern
du musst dann halt die so, ja, oder gibst die halt
irgendwie mit, ja, aber im Wesentlichen sagst du
nur, da soll dann ein Funktionsaufruf
passieren. Also im Prinzip iteriert quasi dieser
ganze Loop immer durch diese gleiche Liste und
guckt, was da drin steht und versucht das dann halt auszuführen, was da
irgendwie... Ja, nur halt schlau, ja, er iteriert
da nicht die ganze Zeit durch, sondern er sagt
zum Beispiel, wann ist denn
der nächste Timer fällig?
Das kann ja,
das ist um 0 Uhr, das sind jetzt noch
1 Stunde 55,
also kann ich 1 Stunde 55,
ich schlafe mal 1 Stunde 54, ja, und
dann kannst du
dich da so rantasten, ja, aber für die 1 Stunde
54 musst du ja nicht immer gucken, ah, ist schon soweit,
ist schon soweit, sondern
die machen das halt schlauer und das
ist eben genau der Trick da dran,
dass du dich nicht drum kümmern musst, wie der das macht,
sondern dass
diese Eventloop schlau genug ist,
das für dich auf eine schlaue Art und Weise zu machen.
Ja.
Genau, richtig, da war noch ein Spezialdings dabei, der LibUV hat auch noch ein Threadpool irgendwie für, glaube ich, Kommunikation mit Files und so, aber also im Grunde abstrahiert alles weg, was man halt so, was Low-Level unten drunter passieren muss, damit es halt funktioniert und man hat dann halt ein sehr schönes Interface nach außen.
Und wenn man jetzt AsyncIO zum Beispiel verwendet, dann kann man einfach das AsyncIO-Interface verwenden und AsyncIO sagen, verwende doch LibUV als Event-Loop und dann benutzt es das Ding unten drunter.
Ja, und ein weiterer Trick, den es dann halt noch gibt, sind sogenannte Trampoline, also Callbacks.
Wenn man es will, jetzt aber.
Kein Tamponier.
Genau, wenn man das genau wissen will,
wie das
alles funktioniert,
dieses Videoserie von Lukas Lange
angucken, der erklärt das alles sehr ausführlich, ich kann
das jetzt nur so anreißen, aber
im Grunde ist es so, Callbacks, die sich halt
selbst wieder registrieren, sozusagen, weil man
ja, also ich meine, wenn jetzt eine Funktion
aufgerufen worden ist und gelaufen ist,
dann ist ja dann eigentlich ja Schluss.
Aber du hast ja oft so Tasks, die
irgendwie die ganze Zeit irgendetwas machen.
und ab und zu mal und dann wieder schlafen.
Wie kann das zum Beispiel sein, dass die sich dann
schlafen legen und wieder aufwachen und dann nochmal was anderes machen?
Das ginge ja eigentlich nicht.
Oder auch die Reaktivität anpassen.
Wenn du gemerkt hast, da ist jetzt nichts zu tun, dann
schlafen die länger oder kürzer.
Ja, und der Mechanismus,
über den das geht, ist, die schedulen sich selbst
wieder auf die Event-Loop.
Hat jeder von uns schon mal gemacht.
Ohne das Wort Trampolin
zu kennen. Ja, wahrscheinlich.
Genau. Und
noch, wenn man jetzt
guckt, wie ist der Mechanismus
eigentlich dafür, der
das macht, dann sind das halt
tatsächlich einfach nur Generatoren eigentlich
unten drunter.
Das ist doch der generelle Trick
von Ace und Gaio, oder? Das sind alles einfach immer nur
Generatoren.
Ja, also
man nennt es halt anders und
es hat einen anderen Typ, aber es ist
tatsächlich fast
das Gleiche.
Also
also die Step-Funktion
in dem Generator ist halt eigentlich das, was
du dann halt immer wieder in die Event-Loop
reintust. Und Await
ist halt nur ein anderes Wort für
Yield-From und Yield-From ist halt genau das
Ding, was halt die
Generator-Geschichte da macht, an der
Stelle. So hat doch
Async.io auch angefangen, oder? Dass man einfach
gesagt hat, wenn ich eine Menge von Generatoren
habe, dann könnte ich die alle nacheinander mal
ausführen lassen und die geben mir die Kontrolle
zurück. Die haben genau diese Eigenschaft schon.
Generatoren haben genau das, was man
braucht, was man sagen kann.
Sogenannte Co-Routinen.
Im Generator kann man ja sagen,
okay, alles klar, jetzt gib mir doch mal das nächste,
gib mir das nächste. Und dann so, ah, und jetzt stopp mal.
Bleib mal kurz stehen.
Du machst jetzt erstmal nichts mehr.
Und dann später kann man ihm sagen, okay, und jetzt gibt noch mal
wieder was. Das heißt, das sind schon Funktionen, die man
irgendwie so anhalten und weiterlaufen lassen kann.
Und wenn man
das jetzt nicht nur aus der
ich kann ja jetzt Sachen rausnehmen Perspektive sieht,
sondern auch man kann da Sachen reintun,
Dann hat man eigentlich schon alles zusammen, was man braucht, um das zu implementieren. Und tatsächlich, die werden alle fair gescheduled. Das heißt, also wenn man sich jetzt, da wäre jetzt ein Schaubild ganz nett, so als Klassenmodell, wie ist die Vererbungs-Hierarchie an der Stelle?
also wenn man
jetzt zum Beispiel async-dev schreibt,
also async-dev-Funktion ist
was sehr ähnliches wie eine normale Funktion, die
jetzt irgendwie yield statt return sagt.
Die wird nämlich intern in Python
auch anders behandelt als normale Funktion.
Und auch dieser
Was auch sehr überraschend
ist für Anfänger, oder wenn man das erklärt.
Vielleicht müsste man statt dev irgendwie
gen-Name machen oder sowas. Nein, nein.
Da schreibst du es schon so hin,
aber wenn du sagst yield im Body der
Funktion, dann wird das Ding anders behandelt
und nicht mehr als normale Funktion.
Ja, das ist die gleiche Art. Wenn man die Deklaration dann anders machen würde,
vielleicht mit einem Gen, statt einem Define,
dann könnte man dann...
Ja, aber...
Du siehst dann halt an einer anderen Stelle und dann musst du
aufpassen, dass das zusammenpasst.
Das ist schon okay, so wie es ist.
Es ist nur einmal am Anfang, wenn man das erklärt,
zum ersten Mal, dann ist es echt weird.
Ja, also im Grunde
sind halt nur andere
Schlüsselwörter, aber was man
tatsächlich macht, ist halt einen Generator
oder eine Funktion zu definieren,
die halt irgendwelche Dinger, also einen Generator
erzeugt. Und wenn man
jetzt die Worte ändert, dann hat man fast
das schon, was Async.io macht, nämlich wenn man sagt,
Async.dev ist, damit definiert
man halt eine Funktion, die jetzt, die man
anhalten kann und die man weiterlaufen lassen kann.
Und wenn man
die aufruft, kriegt man nicht das Ergebnis der Funktion
zurück, sondern eine Kuroutine oder
ein Generator.
Eine Routine, die man dann halt starten kann.
Genau.
auf genau diese Runde, bis er wieder Yield-Zahl
gesagt hat, oder? Genau, und
das Ganze ist verpackt, also
wenn man jetzt, man hat diese Ansend-Funktion
und dann hat man
diese
Kurroutinen und diese Kurroutinen
verpackt in ein Future,
sozusagen das Interface von
dem Future,
sind ein Task.
Und dann sind wir eigentlich
komplett, weil das, was tatsächlich, was man
haben will, sind eigentlich Tasks. Das ist halt so das,
was eigentlich die
Low-Level-Async-IO-Geschichte
ist. Also ein Future hat
ein erwartbares Ergebnis, oder?
Ja, ein Future ist
sozusagen auch nur ein Interface
für, also
in einem Future kann man halt
das kann man halt fragen, so bist du fertig?
Und dann sagt das halt ja oder nein, also dann.
Oder man kann ein Result
für ein Future setzen, dann kann man sagen so
future.setResult
irgendwas und dann, wenn man sagt future.done
dann sagt das, ja, ich bin fertig, ich habe ja ein Result
und dann kann man das Result auch holen.
Und man kann eben auch sagen...
Kann man die nicht sogar verketten?
Man kann die verketten, beliebig, genau.
Man kann auch solche Sachen sagen wie,
wenn du fertig bist, dann ruf folgende Funktionen auf.
Folgendes Future.
Ja, und das kann man beliebig vielen wieder machen.
Und die gehen auch alle wieder auf die Event-Loop.
Das ist auch ein interessanter Unterschied.
Als ich da so ein bisschen was drüber gelesen habe,
habe ich das dann gesehen, es gab ein Node.js macht das anders
und es gab da auch einen Vortrag von dem Ryan Dahl,
der Node.js mal irgendwann entwickelt hat.
Das ist jetzt auch schon wieder was her,
2018 hat er den gehalten und meinte so,
ah, Designfehler in Node.js früher.
Also einer der Fehler ist halt,
dass es eben nicht so,
dass auch diese Promise-Geschichte in JavaScript
nicht, dass Node.js
da nicht so wirklich drauf basiert, sondern dass sie
halt auch viele Callbacks haben, die dann direkt ausgeführt
werden und dann haben sie das Problem,
dass Netzwerk dann doch nicht so gut funktioniert,
weil sie teilweise nicht kontrollieren
können, wann welche Callbacks ausgeführt werden
und sie dann irgendwie, keine Ahnung,
kompliziert, Backpressure kriegen, Probleme
kriegen an diversen Stellen und das dann alles
irgendwie wie ein Kartenhaus in sich zusammenfällt.
An der Stelle bräuchten wir vielleicht mal
ein bisschen mehr mit jemandem reden.
Genau, und
in Python
ist es halt so, da wird das alles wieder,
die ganzen Callbacks der
Features, die gehen auch alle wieder zurück in die Event-Loop
und werden ganz normal gescheduled und das ist alles
fair, sozusagen. Also kein Callback,
das ist ein Callback, das ist ein Backcall.
Im Wesentlichen ist dann jeder Funktionsaufruf
eben so ein Yield-Punkt, oder?
Ja, beziehungsweise, genau, an der Stelle findet dieser Übergang statt, an der Stelle geht es zurück in die Event-Loop und dann halt in den nächsten Callback.
Ja genau, aber das ist ja eben genau wichtig sonst, also damit dieses kooperative Multitasking hier funktioniert, dass die Prozesse einfach regelmäßig oder in möglichst kurzen Abständen yielden, damit eben die Event-Loop andere Sachen machen kann.
Genau, wenn man das nicht macht, hat man ein Problem, ja.
Ja gut, dann hältst du halt im Wesentlichen die Event-Loop an.
Also wenn einer von denen hängen bleibt, sage ich mal,
dann hat auch die Event-Loop wenig Möglichkeiten,
da was zu tun dagegen, weil die halt nie wieder dran ist.
Ja.
Und das ist zum Beispiel in der Erlang-Welt anders.
Wenn da ein Actor, die haben auch natürlich Monitoring eingebaut,
automatisch, das heißt, man kann da Time-Outs setzen
und wenn der Time-Out erreicht ist, dann wird halt der Actor abgeschossen.
Ja.
Ja, ja, also
das ist halt da noch mal
anders, ja.
Ja, und dann habe ich auch noch so ein bisschen
Benchmarks gemacht,
wollte einfach mal gucken, wie schnell ist das denn alles
so ungefähr. Und das
war auch teilweise ganz interessant.
Also
bei Node.js kommt man ungefähr so bei,
also
es bietet einem dann,
ich habe NUX, glaube ich,
irgendwo mal deployed und dann, also
wenn man das startet, man kriegt nicht mal
die Option, das auf mehreren Prozessen laufen zu lassen
oder so, sondern man kriegt halt irgendwie einen Prozess
mit der Event-Loop und das war's. Aber der
macht halt dann auch schon so 7.000 Requests pro Sekunde
oder so, wenn man jetzt einfach nur
ein Stückchen
Hello World JSON zurückgibt.
Und das ist schon
sehr schnell. Und wenn man
das konfigurieren könnte, was ich nicht konnte,
aber dann kann man das bestimmt auf mehreren Prozessen
auch laufen lassen. Und das
wird dann wahrscheinlich in einer ähnlichen
Richtung, weil es die gleiche Event-Loop ist,
liegen wie, wenn man jetzt irgendwie
einfach nur Starlet nimmt oder
so, halt Async
Webserver und dann LibUV
drunter und auch wieder so Hello World JSON
zurückgibt, dann kommt man so
auf 35.000 Requests pro Sekunde
bei einer 8-Core-Maschine.
Also bei meinem...
Das ist etwas weniger als 7.000.
Nee, mehr, aber es ist ja auch...
Es ist etwas weniger als 7.000 pro Core.
Ja, das kann sein, genau.
Es ist ein bisschen weniger
genau, braucht auch ein bisschen,
aber es ist, es ist, es ist, auf
einem Prozess ist es aber ähnlich, auf einem Prozess
ist es fast gleich, also es macht ja echt
kaum einen Unterschied. Ja, okay.
Ja gut, die werden halt auch im Wesentlichen
nicht viel anderes machen, das sind ja kurze
Funktionen, die ausgeführt werden, wenn so ein
WV-Core
kommt. Ja, und die Latenz war auch
fast gleich, tatsächlich bei
Node.js ein bisschen konstanter als bei
bei Python,
aber
auch so, also tatsächlich
die Netzwerk-Latenz zwischen den beiden Rechnern, auf denen
ich das probiert habe, war so 2-3 Millisekunden.
Und die
gemessene
Latenz war dann so 12-13
Millisekunden immer. Sowohl bei Node.js wie
auch bei Python. Auch wahrscheinlich
eben die Latenz von Yubi halt.
Aber das ist auch schon ziemlich gut.
Also kann man nicht mehr kann.
Wenn man jetzt Django nimmt
und nicht irgendwie so einen rohen
Async-Server,
also Yubicorn habe ich
verwendet halt als Applikationshäufer.
Wenn man
jetzt Ubicon nimmt und
Django, dann sieht das halt
ein bisschen anders aus. Dann ist
halt leider, also
da gehen insgesamt nur so 3000
Requests pro Sekunde durch ungefähr.
Wahrscheinlich liegt das irgendwie
an diesem ganzen Middleware-Stack oder ich weiß nicht genau, woran es
liegt, aber das ist halt... Ja, der macht halt sehr viel.
Macht halt sehr viel pro View.
Also das ist deutlich weniger
und es ist halt auch, die Latenz ist
halt deutlich höher. Die ist irgendwie direkt bei
also 30 Millisekunden oder sowas. Ich meine, das ist immer noch nicht viel,
aber es ist halt dann schon mal
so, puh, oi, das war schon
ja, ich meine, es ist alles
völlig irrelevant, ja, also nicht, dass ich jemals
irgendwie... Ja, klar, aber die Zahlen sind halt schon
deutlich unterschiedlich. Ja, und
was ich dann krass fand, ist,
wenn man
Django nimmt
mit Junicorn und
zum Beispiel G-Event-Workern,
dann ist das auf einer CPU
auch so bei 8000 Requests pro Sekunde, also sogar noch ein bisschen
schneller als CPU-Wi.
Und auch mit relativ
wenig Latenz. Also das hat
mich auch gewundert. Wow, krass. Wusste ich, hätte ich
jetzt nicht gedacht. Also
das war,
das fand ich ganz beachtlich.
Und auch Latenz besser.
Aber du kannst es nicht als
ASGI laufen lassen, sondern dann
über Whiskey
Interface. Und da kannst du natürlich viele
Dinge so nicht mehr machen.
Aber da ist
das dann gar nicht mehr so langsam. Ich glaube
irgendwie momentan ist es halt noch so, dass
die ASCII-Geschichten nehmen irgendwie einen Sonderweg
in Django und dieser Sonderweg ist irgendwie ein Stückchen langsamer.
Ja, aber
keine Ahnung. Aber da würdest du jetzt
dann natürlich auch nicht deinen File-Server
bauen. Würdest du dich trauen,
einen File-Server mit Django
ASCII-Uvicorn zu machen?
Ich glaube, das ginge wahrscheinlich sogar tatsächlich.
Also wahrscheinlich wäre das schnell genug.
Oder würdest du den raustun und in den Starlight rein tun?
Ja, das wäre eben auch so eine
Sache.
Wahrscheinlich würde ich es eher mit sowas wie
Starlet probieren oder FastAPI oder so.
Genau, einfach
deswegen, weil das da
so seamless ist quasi. Das ist halt
irgendwie
dafür schon gebaut und das funktioniert einfach so.
Und was ja auch toll ist,
du kannst ja auch über
ASCII halt mehrere
Applikationen haben.
Du nimmst halt einen Applikationsserver und
sagst dem halt unter der URL, es ist halt
irgendwie, deine ASCII-Applikation ist halt
jetzt irgendwie FastAPI oder sonst irgendwas.
Ja, klar. Und unter der URL ist es
halt Django. Gar kein Problem.
Und gibst denen halt unterschiedliche Funktionen mit und dann
ist das halt so.
Sodass du halt auch sowas machen, wenn du
es jetzt schaffst, irgendwie zum Beispiel Sachen zu authentifizieren,
du kriegst ja das gleiche
Cookie, Session-Cookie zum Beispiel, und dann kannst du
natürlich auch die Autorisierung in
irgendwas anderem machen und nicht unbedingt in Django.
Wenn das geht, und das geht bestimmt irgendwie,
dann kannst du auch das Ding dazu verwenden,
die Files auszuliefern.
Oder könntest du es über einen geteilten Cache oder irgendwelche
anderen Messages machen, dass du quasi...
Dass man das andere
Dinge und dann halt irgendwie fragt, ja, das könnte man wahrscheinlich auch machen.
Sogar über dieses ASCII-Interface könnte man das machen.
Ja, also wie auch immer.
das kriegt man auf jeden Fall hin, denke ich. Und
dann bräuchte man vielleicht diese
ganze Nginx-Geschichte schon nicht mehr
und kann es einfach auch alles direkt in
Python machen. Ja, gut, irgendwas brauchst du
davor, um es zu terminieren. Also SSL-Termination
genau, das willst du nicht.
Ja, also da ist meine
aktuelle
Geschichte ja Traffic
und ich fand es hakelig zu
konfigurieren. Wir schreiben übrigens Traffic
für die Leute, die mitgoogeln wollen.
Und
Ja, das ist so ein
Loadbalancer, TCP,
HTTP und mit eingebautem
SSL. Ja, es ist hauptsächlich ein
Loadbalancer, oder? Habe ich so verstanden.
Ja, die machen gar kein Web-Server-Kram.
Also da gibt es auch diverse...
SSL-Termination und Loadbalancer.
Ja, genau. Und das Ding ist
in Go geschrieben
und performt auch. Es ist auch so,
wenn man SSL anschaltet, habe ich dann natürlich auch getestet,
wie ist das eigentlich, wenn man jetzt SSL anmacht,
wie wirkt sich das auf?
Ja, es verbrennt gut CPU
und es wird dann alles, ist dann alles
nur noch halb so schnell. Aber okay,
das ist ja gut. Klar, dass das was kostet.
Das ist ja irgendwie logisch. Ja, gut, aber
das sind ja Kosten, die man, also da
kommst du halt nicht drum rum.
Die hast du halt irgendwo.
Genau, und
ja, also das war
eigentlich, also insofern würde ich sagen, also
Django ist halt momentan noch im Vergleich zu
Node.js und reinem Ubicorn
irgendwie ein Stück langsamer.
Woran es genau liegt, weiß ich nicht. Aber es ist
auch schnell genug wahrscheinlich für alles, was man irgendwie so
damit machen möchte. Insofern eigentlich kein großes Problem.
Und dann habe ich auch nochmal Erlang
getestet. Und Erlang war
Erlang war quasi
genauso schnell wie Ubicorn
auf allen CPUs. Hat auch
irgendwie alle CPUs komplett ausgelastet
und
hat halt auch so 35.000 Requests
pro Sekunde ungefähr gemacht. Aber was ich total
überraschend fand, und das hat mich
auch beeindruckt, ehrlich gesagt, war,
dass die Latenz, also du hast ja
dann immer so, also die meisten Requests
liegen halt alle in so einem engen Korridor
von Zeit, Latenz
und dann hast du halt so ein paar Ausreißer
irgendwie so und eigentlich schon eher
viele, manchmal dauern Dinge dann länger und das
wollen wir ja eigentlich auch nicht. Und bei R lang
hat man das praktisch gar nicht. Die brauchen alle
genau gleich lang und alle nur so 3
Millisekunden. Die Latenz zwischen
den beiden Rechnern, wenn man Ping macht, sind halt irgendwie
2,47 Millisekunden oder sowas
und die Latenz bei den R langen Dingern
ist halt 3 Millisekunden. Also wow, krass.
Okay, das ist, ja.
Ja, das ist eben diese Telefonie, ja.
Das ist einfach ein Realtime-System
und das merkt man eben an so einer Stelle ziemlich deutlich.
Also da waren halt eben, also ja,
das fand ich durchaus auch beeindruckend, ja.
Aber wie kann man jetzt diese beiden Welten verheiraten, Jochen?
Wie würdest du jetzt?
Kann man ja auch machen, ne?
Man könnte ja auch sagen, okay,
man lässt das über den gleichen Loadbalancer gehen
Ja, okay, wenn man so einen Load-Balancer hat, ja.
Ja, okay, man braucht irgendwas in der Richtung
und dann könnte ja auch zum Beispiel Erlang
die Session-Cookies von Django kriegen,
weil es ja die gleiche Domain.
Ja, wobei Session-Cookies reichen ja alleine nicht aus.
Du hast ja oft bei Authentifizierung,
hast du dann irgendwelche Datenbank-Aufrufe,
ob du welche Dateien du sehen darfst
oder welche Bilder oder was weiß ich.
Ja, ja, klar, okay.
Aber du kannst ja auf die gleiche Datenbank gehen.
Das könntest du ja machen.
Ja, nee, aber klar.
Eine Lösung, die ich mal gesehen habe, ist, dass du das
über S3-Buckets machst und dann solche Tickets
mitschickst, weil da kannst du so Authentifizierungstickets
machen. Moment, du machst
welche Tickets auf welche Buckets?
Ist ja gar nichts. Das
Wichtige ist, du hast zwei Systeme und das eine
System sagt dem anderen, ja, du darfst die Datei
ausliefern oder nein, du darfst sie nicht ausliefern.
Und das eine ist ein Erlang und das andere ist Django zum Beispiel.
Und sowas könnte man da ja prinzipiell auch machen,
dass du sagst, du hast irgendwie so eine interne
Schnittstelle, die dir
aufruft und sagt, darf dieser Session-Cookie
diese Datei abrufen?
Ja, das geht.
Sowas könnte man machen, dass du quasi da
eine internische Stelle hast, weil das brauchst
du auf jeden Fall. Wenn du das alles in ASCII
hast, hast du auch eine internische Stelle.
Auch wenn du eben Starlet
und Django
zusammenfindest, brauchst du auch eine schöne Stelle.
Das ist dann halt eine Python-Funktion.
Wenn du zwei VMs
quasi in einem Loadbalancer zusammentust,
hättest du auch eine schöne Stelle, die dann halt aber eine
HTTP-Stelle ist.
Was ja okay ist.
ja, was ja prinzipiell
möglich ist.
Und dann hast du ja wieder so eine Situation,
ich meine, Extent-File ist ja auch nichts anderes als
so eine Schildstelle, ja, die sagt, liefere
diese Datei aus.
Wäre halt
hier ein kleines bisschen anders. Aber ich wüsste jetzt nicht, dass
es da was gibt, was vorbereitet ist.
Nee, da muss man dann selber, also ich habe tatsächlich auch
jemanden schon irgendwo im Blog, ich habe dann nur
ganz kurz danach gegoogelt und dann habe ich jemanden gefunden,
der einen Blogpost dazu geschrieben hat, wie man
Django-Sessions
von Erlang aus authentifizieren kann.
und der Fazit von dem Blogpost
war irgendwie so, ja, ja, das geht.
Aber... Ich meine, das ist ja im Wesentlichen
eine Datenbank-Tabelle, da steht
der Session-Cookie drin und ein serialisiertes
Base64-serialisiertes
JSON.
War das, ja, ja, das geht, aber lass es lieber
oder war das, ja, ja, geht, aber...
Der brauchte das für irgendwas.
Also gebaut und das war jetzt
natürlich schon fummelig und das ist nicht so, dass das
irgendwie, dass man das
irgendwo... Es gibt keine Konfigurationsoptionen
oder so, dass man jetzt sagt, Django, ja,
aber man muss das dann halt
erlangen. Aber es geht schon.
Also insofern, ja.
Ja, und das ist auch nicht
super kompliziert
schlimm. Also es ist nicht, du musst jetzt hier
den internen Code von Django
lesen und verstehen und
erinnert sich alle meine Release, sondern es ist halt schon,
du musst auf die Datenbank-Tabelle zugreifen
und Base64 dekodieren und JSON
lesen und fertig. Pipx install, oder?
Ja,
genau.
Oder halt, keine Ahnung, wie es bei Erlang
heißt. Beam-Install
Python Django.
Ja, aber ja, fand ich
fand ich
überhaupt, FastAPI habe ich mich jetzt ein bisschen
mit beschäftigt mal.
Zuerst, ich habe das immer mal schon verfolgt,
so dass es, das ist eigentlich ganz interessant.
Und jetzt habe ich es ein bisschen intensiver mir angeguckt
und das ist wirklich eigentlich ziemlich cool, muss man sagen.
Auf der anderen Seite, also auf der einen Seite, sehr cool.
Auf der anderen Seite,
ich vermisse Django, bei Django
eben schon solche Sachen, dass halt da ist halt
Registrierung, Authentifizierung, also wobei
ehrlich gesagt, ich finde es fast noch ein bisschen zu wenig, also
Registrierung muss man ja auch immer dann schon überlegen bei Django,
aber dass halt zumindest Authentifizierung
und so halbwegs eigentlich alles schon
drin hat und bei FastAPI
das macht man schon mehr oder weniger
so roh selber und das
ist halt so, okay,
ich muss ja wirklich
die Hash-Funktion auswählen und
ja. Hat ja auch einen gewissen Security-Impact.
Jaja.
Genau. Die Verantwortung will ich gar nicht
haben. Don't do it yourself, ja.
Try. Ja.
Und also insofern, dass da muss man halt
eine ganze Menge Dinge tun,
die man vielleicht gar nicht machen will, aber
auf der anderen Seite ist es halt so, man sitzt halt auch
wirklich mit dem
Hintern roh auf dem
auf der
Performance und kann halt auch, wenn man jetzt
müsste. Man muss zwar nie, aber man könnte.
Aber
das ist doch deine Hypothese, Johann. Man muss doch eigentlich
gar nie.
Wir lösen das durch mehr Prozessoren.
Ja, auf jeden Fall, genau.
FastAPI, eigentlich auch eine sehr, sehr schöne Geschichte
und macht diverse Dinge richtig.
Also zum Beispiel, dass das API-Interface,
dass das Web-Interface halt so komplett integriert ist
und alles ist halt, das macht Dinge schon deutlich einfacher.
Und ja, also ich bin mal gespannt,
wie sich das noch entwickelt, aber das sieht schon,
also Flask habe ich mir auch so ein bisschen angeguckt,
Flask ist schon so ein bisschen schwieriger mit Async.
Also da gibt es dann auch so Geschichten,
ich weiß nicht, wie hieß denn das? Quart?
Oder ich weiß es nicht mehr genau.
Wo man das irgendwie so miteinander
verheiraten kann. Aber ehrlich gesagt,
ich glaube nicht, dass ich
Flasks noch wirklich verwenden.
Also jetzt so, weil
eben Starlet oder Fast API macht eigentlich genau
das Gleiche. Oder ist halt, du hast
und es ist halt irgendwie deutlich moderner.
Ja, den Eindruck hatte ich auch.
Es gibt Leute, die verwenden
das noch. Ich meine, wir kennen ja beide Leute, die noch
Pyramid verwenden oder BFG.
Oder ein Webverwender. Ich meine, das ist natürlich auch so eine Sache.
Wenn man sich da einmal dran gewöhnt hat
und da viel drin gemacht hat, dann
ja, das ist, bevor man
seinen eigenen Vendor locken.
Ja, hat man sich dann selber
ja,
eingeschlossen.
Genau.
Letztens habe ich auch noch so einen
Podcast gehört mit einem, jetzt habe ich leider
den Namen nicht mehr parat,
auch einen Python-Urgestein,
der arbeitet bei Instagram.
Und er plauderte so ein bisschen aus dem Nähkästchen, was sie da so alles machen. Und da waren auch so ein paar Aspekte noch dabei, die ich noch nicht so kannte. Wie zum Beispiel, das war mir nicht klar, dass Instagram schon seit Jahren auf ASGI, nicht ASGI, den Standard gab es nicht, aber auf irgendeinem Async-Interface zwischen Applikationsserver und Anwendung umgestiegen ist, obwohl sie ja eigentlich Django verwenden.
Aber den Teil haben sie halt tatsächlich umgebaut.
Und
das war, weil
das für sie dann wohl doch schon sehr
wichtig war, dass das halt geht. Ja gut.
Wenn du viel Rechenlast hast und wenn du viele
Dateien auslieferst. Ja.
Und
also das,
auf der anderen Seite, sie waren lange auf Django 1.3.
Sind dann
jetzt umgestiegen. Und das war
auch irgendwie wohl der Treiber hinter dem Umstieg auf
Python 3, weil dann Async alles
sehr viel fluffiger wird.
und sind jetzt auf Django 1.8
und das hieß halt so, das wird sich
wohl auch nicht mehr ändern, das ist jetzt die letzte
Django-Version, die sie halt irgendwie nehmen.
Die letzte Version, die es gibt.
Ja, das war's
dann da irgendwie, sie haben halt einige
Teile komplett, die
quasi identisch geblieben sind, also irgendwie das ganze
Request-Response-Handling ist irgendwie,
auch die Mittelwehr-Geschichten, das ist alles gleich geblieben,
auch der View-Layer ist mehr oder weniger komplett
intakt, aber
also bis auf, dass sie halt da eine Asing-Schnittstelle
dazwischen haben, aber was sie
komplett ausgetauscht haben, ist irgendwie, also
alles, was man irgendwie pluggable austauschen
kann, ist ausgetauscht und den ORM
haben sie auch ausgetauscht,
weil sie irgendwann
schaden mussten.
Da brauchst du mehr der Kontrolle dann irgendwann.
Ja, und Schaden zu der Zeit
ging das, also es geht ja inzwischen in Django auch so halbwegs,
aber damals ging das halt nicht.
Also ich meine, nochmal, Schaden ist aufteilen
von, hat man gefragt, aber verstehe ich nicht.
Ja, also der
Königsweg bei Datenbanken,
die zu skalieren, ist ja einfach immer mehr Hauptsprecher reinstecken
oder mehr Prozessoren, solange wie halt geht.
Und wenn man denkt, ja, jetzt geht nicht mehr,
dann halt einfach nochmal ...
Eine zweite Datenbank.
Und dann musst du halt aufpassen, wo deine Daten hinspannen.
Wisst ihr, wo das Wort herkommt?
Das ist ein sehr schönes ...
Ultima Online.
Sehr schönes Wort.
Genau.
Das Wort Shard heißt ja eigentlich so ein Bruchstück.
Und es kommt tatsächlich aus der Ultima Online-Welt.
Die Geschichte von Ultima Online ist,
dass der Weltstein in viele kleine Steine zerbrochen ist.
Und jeder von diesen Shards ist jetzt eine Welt für sich.
Und das heißt, wenn du eben in Ultima Online
dich mit einem Server verbindest,
dann heißt der nicht Server, sondern Shard.
Und das war deren Trick,
wie sie so eine große Benutzerschar handeln konnten,
indem die dir einfach auch verschiedene Bruchstücke
von diesem Weltstein verteilt haben.
Und da kommt dieses Wort Sharding her.
Das ist ja schon ein sehr spezifisches Wort,
dass du eben einfach sagst, das ist
eine eigene abgeschlossene Welt und du kannst nicht aus
dieser Welt raus.
Ja, genau. Und das musste
Instagram mit denen, musste halt auch die User dann
irgendwann aufteilen auf unterschiedliche Datenbanken.
Und dann hatten sie das zuerst so gemacht, dass
quasi alle deine
Daten, wenn du jetzt als User auf irgendeiner Datenbank lagst,
dann alles, was du, also dein kompletter Feed
und der ganze Content von denen, denen du
folgst, der lag dann halt auf deiner Datenbank.
Was ja
auch irgendwie Sinn macht, weil dann die ganzen Queries
gehen dann halt nur zu einer Datenbank und dann ist es eigentlich schön.
Und dann
war irgendwie
Wer war das?
Justin Bieber
oder sowas? Ich weiß es nicht genau.
Irgendwie hieß es
also, jeder kannte die User-ID von dem und
wenn die irgendwo aufgetaucht ist, dann war immer
irgendwie all hands on
deck Zeit und man musste halt,
weil immer wenn der gepostet hat, hast du natürlich das Problem,
da hat er halt irgendwie
Zillionen
Follower und
der Content, der musste
dann halt auf alle Datenbanken repliziert werden.
Das hat dann einen riesen Update-Sturm ausgelöst,
weil, also sobald der irgendwas abgedatet hat,
wurde das dann halt
irgendwie quasi jede Datenbank rein repliziert.
Und das ist natürlich dann nicht so gut.
Das ist doch eine generelle Eigenschaft
von so einem Netzwerk, von so
Social Graphs, dass wir so eine exponentielle
Verteilung haben.
Dass es ein paar Knoten gibt, die mit allen
verbunden sind und alle anderen haben nur ein paar
Verbindungen. So ein zentrales
Webding.
Wie gesagt. Ja. Und die Spinne.
Ja, nee, dass du eben
so eine Verteilung hast, wo es
beide Extreme gibt. Du hast
ganz, du hast viele, oder
einige Knoten, die ganz viele Verbindungen
haben. Und du hast aber auf der anderen Seite
auch ganz, ganz viele Knoten, die
ganz wenige Verbindungen haben. Also die, das ist
irgendwie. Ja, irgendwo im Zentrum.
Irgendwo so eine große Gaswolke, wo ganz viele
Sterne sitzen. Die Menge der Endes ist irgendwie gleich verteilt.
Ist das nicht sogar so, wenn du so einen Random Graph
baust, wenn du in so einen Graph
Random Edges reintust, dass du dann immer so einen kriegst?
Das kann sein.
Meine Grafen-Theorie-Vorlesungen sind lange her.
Ja, also jedenfalls fand ich das
auch witzig, fand ich,
dann wurde irgendwann gefragt, wie lange dauert das
eigentlich, wenn man die testet, oder wie viel Code
ist das eigentlich?
Keine Ahnung, viele Millionen Zeilen irgendwie.
Und wie lange dauert das eigentlich,
die Tests durchlaufen zu lassen?
Ja, also auf einer Maschine
hat das schon ganz lange keiner mehr probiert.
Sie haben sich halt auch so ein eigenes Ding gebaut,
was dann halt die Tests irgendwie an
diverse Maschinen...
Auf dem Teststart
lief es auf dem anderen nicht.
Ja, aber das dauert wohl tatsächlich nur 15 Minuten.
Und das machen sie auch nur, also normalerweise
reicht es irgendwie, die Lokaltests
um dich herum laufen zu lassen, um zu sehen,
ob das irgendwie alles noch funktioniert oder nicht.
Und sobald es dann halt in Produktion geht,
muss es halt einmal komplett durchlaufen und das
dauert dann halt auf x Rechnern
15 Minuten ungefähr. Ja gut, aber
das ist doch trotzdem noch cool. Das ist eigentlich noch alles
in 15 Minuten
durchzutesten, das ist ja der Hammer,
da könnten sich ja viele Firmen, das dauert
ja bei vielen anderen Projekten
Monate. Ja genau und
eben die ganzen Teile
fand ich auch, das ist aber auch
respektabel und was ich auch gut fand,
das hieß so, ja wie macht ihr das eigentlich
als Entwicklungsmodell mit Branches
oder wie auch immer und dann hieß es so, ja
Branchen, das können wir schon ganz lange nicht mehr machen,
weil es sind einfach zu viele Entwickler. Die haben halt tausende
Entwickler, die da drin rumschreiben
und sobald du einen Branch
irgendwie weggehst, dann die kriegst du nie
wieder zurück, weil
du gehst einfach in den Konflikten unter.
Das ist einfach zu schnell. Das heißt, alle entwickeln
immer auf dem gleichen Branch, aber verstecken
alles.
Und packen halt alles hinter Feature-Flex.
Und das geht dann wohl.
Ja, aber das ist generell so eine Technik,
wenn du größere
Deployments auch hast, dass du Feature-Flags machst.
Was ist ein Feature-Flag?
Rolling Releases haben kannst und
trotzdem sicher bist, dass du
ein Rollback machen kannst. Dass du halt sozusagen
ein Feature, an dem du jetzt
irgendwie schreibst, das ist,
das machst du halt ein- und ausschaltbar
sozusagen.
Also quasi die Commits kann man dann abschalten?
Nein, nein, nicht die Commits, nur die
Funktionalität.
Code kommt immer mit, aber
der wird halt nicht immer angesprochen.
Du hast eine große Tabelle, wo drinsteht,
was jetzt gerade für Features aktiv sind.
Okay, dann muss ich halt quasi jede Zeile flecken.
Nö, nur die ...
Nicht jede Zeile, jedes Feature.
Ja.
Nur die Einstiegspunkte.
Genau.
Und du würdest auch nie ein neues Feature
auf allen gleichzeitig anschalten oder so,
sondern du schaltest das immer erst mal auf so
einem Promille an und guckst, was passiert.
Und dann nimmst du ein bisschen mehr
und dann guckst du halt und dann kannst du messen
und dann guckst du deine Graphen an und denkst,
okay, sieht gut aus, dann ja.
Das kennt ihr,
könnt ihr euch noch damals, ganz, ganz
früher, als das Internet noch jung war,
könnt ihr euch an Audio
Galaxy erinnern? Ja.
Das war, es war das bessere
Napster. Ja, das war super.
Und der, einer von den Autoren, die das
geschrieben haben, also die hatten auch, die sind dann geschlossen
worden, ja, von der Musikindustrie relativ schnell.
Die, da, die haben sehr viele,
der hat sehr viele interessante Artikel veröffentlicht
und er hat halt gesagt, die sind irgendwann von Java
auf C umgestiegen aus Geschwindigkeitsproblem.
Und natürlich waren diese Server
erstmal nicht kompatibel.
Und die haben das einfach so gemacht.
Die haben diesen C-Server halt geschrieben
und der war dann halb fertig. Und dann haben sie ihn einfach laufen lassen.
In den Pool reingetan.
Der ist nach einer halben Sekunde gecrashed.
Und dann haben sie
diesen Crash behoben.
Und dann haben sie das so lange gemacht,
bis der halt stabil genug lief,
dass sie quasi die Hälfte ihres Pools
ersetzen konnten.
Das ist so eine Technik.
Wenn du viel Traffic hast,
dann kannst du so statistische Sachen machen.
Kannst du sagen, okay, wir samplen jetzt einfach mal
einen Teil des Traffics raus
und tun den auf einen anderen Server
und schauen mal, ob der kompatibel ist.
Oder du samplst eben die, wie du sagst, Feature Flags raus
und sagst, wir aktivieren jetzt dieses Feature mal
für 10.000 Benutzer.
Und dann denkst du dir so, 10.000 Benutzer, so viele.
Aber es sind halt nur 0,001 Promille der aktiven Benutzer.
Und wenn irgendwas schief geht, dann ist es schade für die,
aber dann müssen die halt die Seite neu laden
und du hast aber
statistisch valide Daten.
Also auch das ist ja was,
was du nur kannst, wenn du viel
Paralleles,
viele parallele Anfragen hast.
Naja,
das fand ich eigentlich alles
sehr fluffig und dann hat er noch was gesagt
und da dachte ich so, oh shit,
das ist auch, hatte ich ja vorher schon so ein bisschen
gehört bei auch einem Podcast
mit Andrew, wo
weil Andrew Godwin zu Gast war,
der irgendwie bei Eventbrite, glaube ich, arbeitet.
Weil er auch meinte so,
also die Eventbrite-Jungle-Applikation
hat ja so um eine Million Zeilen irgendwie Code.
Und es dauert halt schon relativ lang, die zu starten.
Und der Grund, warum es so lange dauert,
sind halt die Imports,
weil die Imports laufen halt 20 Sekunden.
Und da kann man nicht viel optimieren.
Und er meinte so,
wir haben halt tatsächlich das Problem,
dass wenn wir jetzt irgendwo schnell hochskalieren müssen,
dann sind halt diese 20 Sekunden, die fehlen.
einfach. Und es gibt tatsächlich Überlegungen,
ob sie das Ganze nicht in einer anderen Sprache neu schreiben, weil
es halt unoptimierbar ist.
Kann man die Imports cachen oder so?
Nee, leider kann man da nicht viel machen.
Und das
kannst du einen Graphen aufbauen,
der die dann in einer anderen Reihenfolge macht. Das habe ich schon mal
wo gelesen, aber das hilft halt auch nur.
Ja, das Problem,
das grundsätzliche Problem ist halt wohl irgendwie,
dass auch, sobald ein neues Modul dazu
kommt, kann es halt die Reihenfolge ändern.
Und das heißt, du kannst nicht,
du müsstest irgendwie das
Ich habe das mal gesehen, ich habe mal so einen Artikel gelesen, wo sie gesagt haben, sie mussten, also war auch irgend so ein Internetanbieter aus den 2010ern oder was weiß ich, die halt das Importsystem so anpassen mussten, dass sie die Importreihenfolge selber optimieren können, um genau das zu umgehen.
Ja, und genau das sagte der dann halt auch.
Der meinte so, naja, also sehr große,
also sie haben das schon so ein bisschen zerlegt irgendwie
oder versucht, aber trotzdem ist es so,
wenn du an Instagram entwickelst,
hast du da auch deinen Entwicklungs-Server,
deinen Django-Entwicklungs-Server so quasi,
ganz normal, wie man das so kennt.
Und jetzt änderst du da halt irgendeine triviale Geschichte
und dann lädt er automatisch neu.
Und dann willst du ja gucken auf deiner Seite,
okay, hat das jetzt so funktioniert,
wie ich mir das gesagt habe.
Und das dauert dann halt eine Minute.
Du kannst nicht viel daran machen.
So ist das dann halt.
Und das ist natürlich extrem frustrierend.
Also das macht dann nicht mehr so richtig viel Spaß,
damit zu entwickeln.
Und was man sich eventuell vorstellen könnte,
was man da macht, ist halt eben über Type Hinting oder so
vielleicht irgendwie auch in dem Modulsystem zu sagen,
es gibt Module, die nicht mehr alles dürfen.
Und dann kannst du irgendwie einschränken,
dass sie zum Beispiel nicht mehr die Reihenfolge der Module,
die importiert werden, ändern dürfen. Und dann könntest
du sowas machen, wie du kannst es eben cachen. Du kannst halt sagen,
okay, ich mache einen Reload,
aber nur von dem Modul und sonst nichts.
Und das geht aber momentan noch
nicht so richtig und da sind sie halt
auch irgendwie dran.
Aber da kann man doch bestimmt den Python-Interpreter
irgendwelche Memory-Snapshots machen, wo du
alles importiert hast,
was du einfach einmal komplett in den Hauptspeicher
rein streamst.
Ja, ich weiß es nicht, aber es scheint
nicht so ein einfaches Problem zu sein.
Das sind irgendwie wohl...
Also mal ein Guido fragen, der weiß das.
Ja, aber das klingt natürlich,
wenn schon mal mehrere Leute sagen,
dass sie damit Probleme haben,
das klingt dann natürlich nicht so richtig gut.
Aber ja.
Ja.
Ja, tatsächlich ist mir das auch schon
in eigenen Projekten aufgefallen.
Wenn die größer werden,
dann ist halt die Startup-Time langsamer.
Und das ist nervig beim Entwickeln,
weil du halt deine Sekunden warten musst,
bis du deine Änderungen testen kannst.
Das ist schon so.
Ja.
Ja, aber du hast irgendwas Interessantes gesagt, und zwar Type-Ins.
Ich glaube, das bringt uns jetzt quasi
zum Ende dieser Folge.
Und zwar hatte ich da
einen Pick der Woche in der Standard, äh, nicht Standard
Library, wir wollten zwar ein bisschen Standard Library machen, aber
ich hätte heute gepickt
Typer. Und Typer macht
nämlich genau das, das macht nämlich aus Type-Ins
Kommandos, die man sehr schön
benutzen kann. Man kann jetzt seine eigene
Klee zusammenklicken oder
seine eigenen Kommandos, die man aufrufen kann.
Ah, das ist für eine Kommandozeile?
Ist das da, also tatsächlich so, dass
du dann Command-Line
Dinger hast. Ja, es gibt sogar
Autocompletion, die mitgeliefert wird und so. Das hast du eigentlich
ganz cool gemacht.
Da gibt es ja ganz viele Bibliotheken, die das machen.
Früher gab es ja immer nur eine, die ganz schlecht
war und inzwischen gibt es ganz viele.
Ja, also Klick-Klick drunter und man kann halt tatsächlich
mit so Type Annotations sagen, was
für gültige
Argumente man irgendwie mitparsen kann.
Irgendwie, dann kannst du einfach ein Boolean flaggen
und dann kannst du halt einfach die Option setzen, dann kommt
halt ein True oder False rein und kannst halt dann gucken,
was du machen willst und das ist irgendwie sehr
convenient irgendwie für Projekte und
kleine Abstraktionen.
Ja, das ist spannend.
Das ist tatsächlich ein Problem, an dem ich
auch schon vor langer Zeit mal
gearbeitet habe.
Weil es mich nämlich auch genervt hat. 2012
habe ich meine eigene Bibliothek veröffentlicht.
Kommandier heißt die,
die im Wesentlichen genau das Gleiche macht.
Die nimmt Funktionen mit ihren Types
und Typehints und
baut ja daraus eine Kommandozeile.
Gibt es inzwischen tatsächlich
einige Google Fire
heißt die, glaube ich.
Die ist nicht
quasi auf Google nicht zu finden. Ah, hier,
Python Fire heißt.
Macht auch so was ähnliches.
Simple way to create command line
interface in Python.
Ich bin ja sehr froh, dass
ich lange vor Google auf die Idee gekommen bin.
Also ich kann mir selber,
ich schreibe mir selber zu, dass ich
die bessere Idee hatte.
Ja, sehr gut.
Du hast auch irgendwie noch eben was gesagt
unserem vorgepinkelt, dass du Commander
interessant fandest?
Ne, also wie gesagt, meine Bibliothek heißt
Kommandier. Kommandier.
Das ist ein englisches Wort, das heißt so viel
wie übernehmen.
Und deshalb habe ich das gemacht. Aber es gibt
in der Standardbibliothek noch
was anderes, das heißt CMD, also
CMD. Das macht
ein bisschen was anderes, das macht nicht ein Command Line
Interface, sondern ein Shell Interface.
Das heißt sowas wie
das, was man in Python hat. Der Python
Interpreter ist ja, wenn man den startet, ist der
ein Shell-Interface, das heißt, ich habe eine Eingabezeile
und wenn ich da was eingebe, dann passiert irgendwas.
Und mit
dieser Bibliothek
CMD aus der Standardbibliothek
kann man solche Shells
sich selber bauen.
Das heißt, es ist quasi nicht auf der Kommandozeile
die Befehle eingegeben, sondern in dem
Programm dann drin. Auch mit toller
Autocompletion und mit bestimmten
Optionen, die direkt angezeigt werden und sowas alles.
Genau, also im Wesentlichen schreibt man eine Klasse,
die von dieser Command-Klasse
ableitet, also von der CMD-Klasse ableitet und
tut dann da Funktionen rein.
Und der Rest, also der nimmt die Dokumentation
daraus, der nimmt die Parameter daraus.
Wenn man nicht
die Standard-Library braucht, gibt es auch CMD2.
Das kann dann auch Farben und sowas alles.
Aha, Farben. Spielerei.
Ja, nein, nein, nein, das kann, glaube ich, noch ein, zwei
andere nette Sachen. Ich muss da mal ausprobieren.
Das Beispiel, was bei CMD
in der Standard-Library
drin ist, ist direkt Turtle, also wie man sich eine
Turtle, interaktive Turtle baut.
Ich weiß nicht, ob ihr
ob ihr damals schon alt
oder schrägstrich jung genug wart, um
die Turtle zu benutzen im
Ja, erinnere mich ein bisschen an, wie hieß das Logo?
Informatik-Unterricht. Ja, ja, Turtle Graphics.
Das war
sehr schön damals.
In Pascal hatten wir das.
Wisst ihr, was LEED ist?
Guck dir mal in den Spiegel.
Der, der, oh, ich weiß nicht
mehr, was das heißt. Loyal Informatik-Editor
oder irgendwie sowas. Das war so
ein System, was wir in der Schule hatten,
Als ich in der achten Klasse war,
hatten wir das entschuldigt.
Es war so eine Art Pascal
mit einem Turtle-Interface und das Beste ist,
es hatte einen Editor mit dabei und es hat auch
sehr schöne Grafiken gemacht.
Der konnte aber nicht scrollen, dieser Editor.
Das heißt, alle Programme waren maximal eine Seite lang.
Sehr schön.
Und das
musste halt ausreichen in der achten Klasse.
Aber mit Turtle
und allem war es auch sehr, sehr gut.
Wir hatten damals tatsächlich
Turbo Pascal 5.0, glaube ich.
nicht schlecht. Das war auch, das hat
tatsächlich Spaß gemacht.
Ist auch sowas, was man nicht mehr, also ich meine,
diese ganzen Dinge findet man nicht mehr im Internet.
Ich habe es gerade probiert und es geht nicht.
Ja, ist alles irgendwie weg.
Ja, gone, gone, gone again.
Ja, aber rechter Vergess ist ja auch nicht schlecht.
Ja. Kommt alles in die Shownotes.
Genau, ja gut.
Hast du noch was,
Pick, Jochen?
Ja, also ich würde jetzt einfach mal so,
auch was so Async-Geschichten angeht,
also man braucht ja nicht nur den Serverteil,
sondern halt auch einen,
der kleine ist ja manchmal auch nicht so schlecht,
wenn man den hat.
Ansonsten, ja, wie will man jetzt eigentlich gucken,
ob das funktioniert hat,
was man da auf der Serverseite gebaut hat.
Und ja, so üblicherweise wird man jetzt unter Python
zum Web-Requests machen,
ja, verwenden die meisten wahrscheinlich Requests.
Aber das Ding ist halt leider nicht Async, gar nicht.
Sondern halt komplett synchron.
Und kann man auch nicht viel machen.
Und sozusagen der asynchrone
Nachfolger
irgendwie von Request, oder vielleicht wird ja
Request auch nochmal irgendwann asynch.
Ist
HTTPX.
Auch von
einem der Namen,
die hinter ganz vielen Dingen stehen.
Von Tom Christie, der halt
Jungle Rest Framework
gebaut hat. Und dann Starlet
und viele andere Dinge.
Und genau, der hat
dann irgendwann quasi halt auch jetzt
einen async-fähigen
HTTP-Client geschrieben,
der sich am Request-Interface halt orientiert.
Aber halt
auch, mit dem man
dann async-Geschichten machen kann.
Und genau, den verwende ich jetzt auch eigentlich
meistens, wenn ich irgendwie HTTP-Geschichten mache
und funktioniert eigentlich ganz gut.
Und warum
nicht jetzt nicht mehr Request, was jetzt besser
als Request ist? Es kann mehr als Request.
Wie gesagt, Request ist Sync,
kann kein async. Ja, okay. Also es ist jetzt
quasi, ja, iSync-Request.
Ja, also ich erinnere mich noch,
früher habe ich immer sowas verwendet wie AEO,
HTTP-Client und so, aber das war immer ziemlich,
da muss man viel selber machen. Ja, da muss man selber frickeln.
Ja.
Ja, gut. Ich würde sagen,
Come to the Dark Side, wir haben Cookies, ne, und
du hast auch noch ein nettes Video gemacht zum Cookies.
Oh ja, das können wir ja auch mal verlinken. Ja, das kommt auch
in die Show Notes, perfekt. Ja.
Aus aktuellem Anlass.
Ja. Ja, vielen Dank, dass ihr uns
heute wieder zugehört hat, dass ihr eingeschaltet habt.
Feedback, Kritik, Anregungen, was auch immer.
Hallo at peisenpodcast.de
Schreibt uns, hört uns, wann auch
immer ihr wollt. Morgens, mittags, abends, nachts.
Zum Aufstehen, zum Schlafen gehen, zum Zähneputzen,
zum Autofahren, zum was auch
immer euch gerade einfällt, zum auf der Decke
im Park liegen. Bei den
Temperaturen bestimmt wundervoll.
Ja.
Auch beim Autofahren. Optionen sind eingeschränkt.
Wir sind immer noch Corona
behindert.
Irgendwie in allem, was wir tun.
Aber E-Mails schreiben geht.
Und Podcasts hören geht auch.
Bleibt uns gebogen und bis zum nächsten Mal.
Jo, bis dann. Tschüss.