3 Punkte von GN⁺ 2024-10-11 | 1 Kommentare | Auf WhatsApp teilen
  • Wasm ist kein CGI-Protokoll, lässt sich aber als nächstes Anwendungsmodell verstehen, das – ähnlich wie cgi-bin – die Ausführungseinheit und Bereitstellungsweise von Web-Apps verändert
  • CGI, FastCGI, Rack/WSGI und Serverless haben alle die Anfrageverarbeitung und Serververwaltung neu gestaltet; das gemeinsame Ziel war, performante Anwendungen einfacher zu entwickeln und zu betreiben
  • Wasm-Module laufen in einer Host-Runtime und können durch isolierten Speicher und Snapshots einen sauberen Ausführungszustand beibehalten, während Startkosten sinken
  • Fehlende native Threads, kein JIT, Kosten durch Datenkopien sowie die Unreife von Interface Types und Module Linking sind zentrale Einschränkungen Wasm-basierter Server-Ausführungsmodelle
  • Wenn Serverless Functions und Edge Functions mit Wasm-Ausführungsumgebungen kombiniert werden, können Cold Starts und Isolationskosten sinken, und Module aus mehreren Sprachen lassen sich leichtergewichtig kombinieren

Vom CGI bis Serverless: das fortlaufende Web-Anwendungsmodell

  • Der Kern von CGI lag weniger im Common Gateway Interface-Protokoll selbst, sondern im Anwendungsmodell, bei dem Skripte oder ausführbare Dateien im Ordner cgi-bin per URL aufgerufen wurden
  • Dieser Ansatz war ein frühes Web-Anwendungsmodell, das das Web von einem Dokumentenarchiv in ein Netzwerk interaktiver Anwendungen verwandelte
  • Da für jede Anfrage ein neuer Prozess gestartet wurde, sind nach heutigen Maßstäben die Kosten für Prozessstart und Skript-Parsing ein großer Engpass

FastCGI und der Wandel sprachspezifischer Webserver

  • FastCGI führte ein Modell ein, bei dem langlebige Prozesse CGI-Anfragen verarbeiten, um die Performance-Probleme von CGI zu reduzieren
    • Der Webserver startet nicht für jede Anfrage einen neuen Prozess, sondern kommuniziert mit einem oder mehreren langlebigen Prozessen
    • Bestehende CGI-Anwendungen wurden unter der Annahme gebaut, dass der Prozess nach der Anfrage endet, wodurch in langlebigen Umgebungen leicht Ressourcenlecks entstehen konnten
  • Später etablierten sich sprachbasierte Webserver als Konvention, und Anwendungen wurden rund um ein Request/Response-Modell gebaut
    • Üblich war, sie hinter funktionsreiche und bewährte Webserver wie Apache oder nginx zu setzen und die Anwendung so von langsamen Anfragen und HTTP-Details zu entkoppeln
    • Serverimplementierungen nutzten unterschiedliche Prozessverwaltungsstrategien, etwa Fork pro Anfrage, OS- oder Sprach-Threads, Event- oder Reactor-Modelle
  • Das Rack-Interface der Ruby-Community beeinflusste auch Pythons Flask Application Server und die WSGI-Spezifikation
    • Vereinfacht besteht eine Anfrage aus HTTP-Methode, Header-Hashmap sowie einem Eingabe-Byte-String oder -Stream
    • Eine Antwort besteht aus Statuscode, Header-Objekt sowie einem Antwort-Byte-String oder -Stream

Cloud-Autoscaling und der Kompromiss von Serverless

  • In Modellen auf Basis physischer oder virtueller Server musste man die Zahl der laufenden Server selbst verwalten
    • Bei hohem Traffic konnten Anwendungsserver langsam werden
    • Bei niedrigem Traffic konnten viele Rechner untätig bleiben
  • Autoscaling in der Cloud ermöglicht es, die Zahl der Anwendungsserver anhand von CPU, Speicherauslastung und Tageszeit anzupassen
    • Das Hochskalieren neuer Rechner kann je nach Anwendung und Konfiguration 2 bis 20 Minuten dauern
    • Skalierung hängt außerdem von den verfügbaren Ressourcen in der jeweiligen Cloud-Hosting-Region ab
  • Serverless Compute durch die Kombination von Amazon Lambda und API Gateway schuf ein Modell, in dem Funktionen statt Server verwaltet werden
    • Pro Anfrage werden ein einzelner Prozess, isolierte CPU und isolierter Speicher garantiert
    • Prozesse können bis zu einige Stunden wiederverwendet werden, werden aber bei Nichtnutzung pausiert oder entfernt
    • AWS kann je nach Anfragevolumen binnen Sekunden hoch- und herunterskalieren
  • Serverless bringt klare Trade-offs mit sich
    • Wegen der Kosten neuer Prozesse erleben einige Anfragen beim Skalieren gleichzeitiger Anfragen einen Cold Start
    • Nach einer Antwort kann der Prozess pausiert werden, wodurch persistente TCP-Verbindungen zwischen Anfragen schwierig zu verwalten sind
    • HTTP-basierte Datenbank-APIs sind im Serverless-Modell beliebt, weil sie viele Verbindungen verkraften und sich leicht gemeinsam mit Funktionen hoch- und herunterskalieren lassen
  • Die Eigenschaft, pro Anfrage dedizierte CPU und dedizierten Speicher bereitzustellen, kann je nach Workload Vor- oder Nachteil sein
    • Manche Workloads können Ressourcenmanagement reduzieren und Kosten- sowie Skalierungssorgen verringern
    • Andere Workloads sind effizienter, wenn ein einzelner Prozess viele Anfragen verarbeitet oder Shared Memory für Batching und Caching nutzt
    • Es werden sowohl ein Fall genannt, in dem der Umzug einer CMS-basierten Webanwendung auf Serverless die Kosten um 90 % senkte, als auch ein Fall, in dem der Umzug eines Event-Analytics-Dienstes auf ein serverbasiertes Modell die Kosten um 90 % senkte

Wasm-Ausführungsmodell auf dem Server

  • Wasm wurde ursprünglich entwickelt, um performanten Code im Browser auszuführen, und steht auch mit Ansätzen wie asm.js in Verbindung
  • WebAssembly ist ein binäres Instruktionsformat für eine stackbasierte virtuelle Maschine und wurde als portables Kompilierungsziel für mehrere Programmiersprachen entworfen
    • Es ermöglicht die Bereitstellung von Client- und Serveranwendungen im Web
    • Es ist darauf ausgelegt, in einem binären Format codiert zu werden, das bei Größe und Ladezeit effizient ist
    • Ziel ist eine Ausführung nahe an nativer Geschwindigkeit, indem gemeinsame Hardwarefunktionen verschiedener Plattformen genutzt werden
  • Heute lassen sich mehrere Sprachen in Wasm-Instruktionen kompilieren und sowohl im Browser als auch auf Servern ausführen
  • Das vom Browser geforderte Isolations- und Sicherheitsmodell ist auch für Serveranwendungen nützlich
    • Nicht vertrauenswürdiger Code kann in einer deutlich leichtergewichtigen Form als mit VMs oder Docker-Containern isoliert werden
  • V8-basierte Serverless-Umgebungen wie Node.js, Cloudflare Workers und Deno nutzen die im Browser aufgebaute Wasm-Ausführungskompetenz
  • Es gibt auch Wasm-native Umgebungen wie Fastly, Shopify und Suborbital

Module, Host, Speicher und Snapshots

  • Da Wasm-Module Instruktionen für eine virtuelle Maschine sind, benötigen sie zur Ausführung eine Runtime
    • Die Runtime kompiliert generisches Wasm für die lokale Architektur und stellt die Ausführungsumgebung bereit
    • Manche Umgebungen bieten Schnittstellen, die den POSIX-APIs von Linux-Systemen ähneln
    • Manche Umgebungen stellen nur bestimmte Funktionen des Host-Systems bereit und führen die Export-Funktionen des Moduls aus
  • WebAssembly-Programme sind in modules organisiert, und die VM, die ein Modul ausführt, wird host genannt
    • Ein Modul ist die Einheit für Bereitstellung, Laden und Kompilierung
    • Es bündelt Definitionen von Typen, Funktionen, Tabellen, Speicher und globalen Werten
    • Es kann Imports und Exports deklarieren und Initialisierung in Form von Datensegmenten, Elementsegmenten und einer Startfunktion bereitstellen
  • Die „memories“ von Wasm werden als lückenlos zusammenhängende Byte-Arrays dargestellt und vom Host zum Zeitpunkt der Instanziierung zugewiesen
    • Jedes Guest-Modul erhält Speicherisolation
    • Dieser Speicher verhält sich wie der RAM der virtuellen Maschine
    • Er kann leer bereitgestellt oder mit Datensegmenten vorbefüllt werden
  • Durch die Modul-Isolation kann ein Modul pausiert und sein Speicher als Datensegmente gespeichert werden
    • Das ist ein ähnliches Konzept wie Snapshots virtueller Maschinen
    • Von einem pausierten Modul lassen sich mehrere Kopien starten
  • Wizer instanziiert ein Wasm-Modul, führt eine Initialisierungsfunktion aus und schreibt anschließend den Instanzzustand in ein Wasm-Binary zurück
    • Es initialisiert den Zustand globaler Werte direkt
    • Es zeichnet Speicherbereiche auf, die nicht null sind
    • Es entfernt bestehende Datensegmente und ersetzt sie durch Datensegmente für die aufgezeichneten Speicherbereiche
  • Dieser Ansatz bietet eine saubere Ausführung wie ein neuer Prozess, vermeidet aber die Startkosten eines neuen Prozesses
    • Es ist nahe an CGI ohne die Nachteile von CGI
    • Moderner formuliert: nahe an Serverless ohne Cold Starts

Einschränkungen und Vorteile von Wasm

  • Wasm hat in seiner nativen Konfiguration keine Threads
    • Blockierende Aufgaben müssen in Host-Methoden verlagert werden
    • Der Host kann Wrapper zum Lesen und Schreiben von Datei- oder Netzwerkschnittstellen bereitstellen, Module pausieren oder Callback-Handler anbieten
    • Reactor-Modelle oder blockierende Modelle lassen sich bauen, doch bis zur Umsetzung des thread proposal spielt das Design der Ausführungsumgebung eine große Rolle
  • Aus Sicherheitsgründen ist dynamische Wasm-Codegenerierung nicht erlaubt, daher ist JIT-Kompilierung unmöglich
    • Code selbst kann zur Laufzeit nicht als Adresse behandelt werden
    • Laufzeitumgebungen wie V8 oder CRuby, deren Performance von JIT abhängt, können in einer Wasm-VM nicht ausgeführt werden oder müssen auf JIT verzichten
    • Ein „pre-jit“-Ansatz, bei dem eine optimierte Runtime für Skripting zur Build-Zeit ausgegeben wird, wurde vorgeschlagen, ist aber nicht weit verbreitet
  • Da die grundlegende Schnittstelle zwischen Wasm-Modul und Host Speicher ist, kann Datenbewegung Kopieren erfordern
    • Das Teilen von Speicher-Chunks ist möglich, aber ob es möglich oder empfehlenswert ist, hängt vom Speichermodell der Runtime ab
    • In den meisten Runtimes gilt Zero-Copy-Kommunikation zwischen Modul und I/O-Operationen als schwierig
    • Streaming-Daten in Wasm-Module hinein und aus ihnen heraus zu bewegen, kann langsamer sein als die Verarbeitung im Host
  • Wasm-VMs bieten eine hohe Kontrolle über Nutzungsbeschränkungen
    • Manche Runtimes können CPU-Limits erzwingen, indem sie CPU-Instruktionen zählen, ähnlich dem Wasmtime fuel concept
    • Die VM kann Speicher und Wall-Clock-Zeit begrenzen
  • Interface Types und Module Linking können Modulgrößen reduzieren sowie I/O-Geschwindigkeit und Nutzbarkeit verbessern
    • Interface Types sind nutzbar, aber noch kein ratifizierter Standard
    • Für Module Linking gibt es funktionierende Prototypen, aber noch keinen Standardansatz
    • Wizer kann derzeit mit Module Linking kollidieren; es gibt zwar Custom-Ansätze zur Lösung, aber keinen klaren Gewinner
    • Interface Types zielen darauf ab, sprachneutrale Objekte ohne teures Encoding und Decoding über Wasm-Speichergrenzen hinweg bewegen zu können
    • Der derzeit übliche Weg besteht darin, JSON in den Speicher hinein- und wieder herauszukopieren
  • Wasm-Module können grundsätzlich nur auf das zugreifen, was ihnen gegeben wird, wodurch das Sicherheitsmodell klein und klar ist
    • Nicht vertrauenswürdigen Wasm-Code auszuführen, gilt allgemein als relativ sicher
    • Die Angriffsfläche der VM ist kleiner als bei Docker oder anderen Isolationsmodellen
    • Da übersetzte Instruktionen auf der Host-Hardware ausgeführt werden, sind Timing-Angriffe möglich, es gibt jedoch Gegenmaßnahmen
    • Wasm kann auch in native Binaries kompiliert werden, doch dadurch wächst die Angriffsfläche

Edge Functions und Wasm-basierte Funktionsausführung

  • Wenn Wasm-Ausführungsumgebungen und Entwicklungstools breite Verbreitung finden, können auch Skriptsprachen unter Druck geraten, Wasm-Runtimes und Preboot-Ansätze wie Wizer bereitzustellen
  • Theoretisch könnte eine Anwendung bei jeder Anfrage aus einer per Snapshot gespeicherten Kopie fortgesetzt werden und schneller laufen als in aktuellen anderen Modellen
  • Auch lokale CLIs könnten in Ruby geschrieben, dann als gesnapshotetes Wasm-Modul ausgeliefert und mit einer Wasm-Ruby-Runtime verbunden werden; so ließen sich Startzeiten nahe an C++-Utilities erreichen und die Ausführung auf das Projektverzeichnis beschränken
  • Die erste große Veränderung besteht darin, Funktionen näher an den Nutzer an den Edge zu verlagern
    • Compute läuft nahe beim Nutzer statt nahe bei der Datenbank
    • Vercel Edge Functions werden als V8-basiertes Beispiel genannt, das aber viele Prinzipien teilt
    • next-auth kann anhand von JWT-Login-Tokens den Zugriff auf vorgerenderte Seiten steuern
    • Dynamische personalisierte Inhalte können aus im CDN gecachten Daten bereitgestellt werden
  • Eine weitere Veränderung besteht darin, prozessbasierte Funktionen in Serverless-Anwendungen durch Wasm-basierte Funktionen zu ersetzen
    • Suborbital ermöglicht es, eigene Wasm-basierte Funktionsausführungsumgebungen zu bauen, und bietet auch die Möglichkeit, Wasm-Funktionen zu Workflows zu verketten
    • Viele Ausführungsplattformen empfehlen ein einzelnes Modul pro Anfrage und nutzen die Möglichkeiten von Shared Memory oder schnellen Aufrufen mehrerer Module nicht ausreichend aus
    • Wenn Interface Types standardisiert werden, könnte ein Middleware-Datenmodell ähnlich Rack entstehen
  • Wasm kann auch innerhalb von Lambda-Funktionen ausgeführt werden
    • In bestehender Infrastruktur lassen sich gesnapshotete Anwendungsversionen nutzen
    • Diese Kombination ist interessant, wird aber als Technologiemix behandelt, der letztlich verschwinden könnte

Richtung des nächsten Web-Anwendungsmodells

  • Wasm wird als Technologie dargestellt, die Performance erhöhen, Sicherheit auf Prozessebene einfacher machen und Build- sowie Ausführungskosten von Serverless Functions senken kann
  • Es kann nahezu jede Sprache ausführen und durch Module Linking und Interface Types die Latenz zwischen Funktionen deutlich reduzieren
  • Der zentrale Grund, Wasm als neues CGI zu betrachten, ist, dass sich durch veränderte Systemgrenzen Dinge ermöglichen lassen, die zuvor unmöglich waren

1 Kommentare

 
GN⁺ 2024-10-11
Hacker-News-Meinungen
  • Ich verstehe nicht ganz, was WASM von älteren Technologien wie Java Applets, ActiveX, Silverlight oder Macromedia Flash unterscheidet.
    Das Ausführen von nicht vertrauenswürdigem kompiliertem Code Dritter im Browser schien eigentlich eine Lektion zu sein, die man bereits gelernt hatte, und es wirkt wie eine Struktur, bei der unter dem Vorwand einer besseren Nutzererfahrung Rechenkosten vom Server auf den Client verlagert werden.

    • Java und Flash konnten ihr Versprechen einer unzerbrechlichen Sandbox, in der sich „alles sicher ausführen“ lasse, nicht halten.
      Die Implementierungen hatten viele Schwachstellen und wurden im Browser letztlich praktisch unbenutzbar, während andere Technologien ein solches Versprechen von vornherein wohl gar nicht abgegeben hatten.
      JavaScript hat dieses Versprechen tatsächlich eingehalten, und heutige Browser führen von jeder Domain geladenes JavaScript aus, ohne den Nutzer zu fragen, ob er ihm vertraut.
      WASM läuft auf der JavaScript-Engine auf und bietet ähnliche Sicherheitsgarantien, weshalb es sich nicht grundlegend von JVM-Bytecode unterscheidet; der praktische Unterschied ist, dass WASM seine Sicherheit bewiesen hat, die JVM jedoch nicht.
      Google Chrome ist inzwischen so sicher, dass Milliarden Menschen bösartiges WASM ausführen können, ohne dass ihre Smartphones kompromittiert werden, und dieselbe Engine lässt sich auf den Server bringen, um Skripte vieler Nutzer in einer starken Sandbox auszuführen und dabei Ressourcen gemeinsam zu nutzen.
      Die Alternative ist Virtualisierung: Man kann Code in WASM-Pakete kompilieren und auf einem großen WASM-Server ausführen oder ein amd64-Binary zusammen mit einem abgespeckten Linux-Kernel bündeln und in einer VM laufen lassen.
      Im Moment ist schwer zu sagen, welcher Ansatz klar gewinnt; beide haben ihre Vor- und Nachteile.
    • Anders als ActiveX, Silverlight und Flash ist WASM ein offener Standard, an dem mehrere Akteure der Branche arbeiten, und es gibt mehrere Implementierungen; allein das macht es schon deutlich besser als die Alternativen.
      Anders als die JVM bietet WASM linearen Speicher und standardmäßig keine Garbage Collection, wodurch es sich besser als Kompilierungsziel für eine breitere Sprachfamilie eignet, etwa wenn man C/C++ mit Emscripten kompiliert oder Rust darauf abzielt.
      WASM ist Bytecode, und die meisten Implementierungen teilen sich vermutlich große Teile der Host-JavaScript-Engine und der Runtime.
      Die Verlagerung von Rechenkosten zwischen Client und Server ist Teil der seit Langem zu beobachtenden Bewegung zwischen dicken Clients und dünnen Clients, und dieses Pendel wird sich auch künftig weiter bewegen.
    • Wasm hat gegenüber den älteren Technologien deutliche Vorteile.
      Es gibt eine Validierungsspezifikation, die WASM-Bytecode erfüllen muss, und durch diese validierte Teilmenge werden viele der Sicherheitslücken, die man bei früheren Technologien sah, von vornherein unmöglich.
      Angriffe, die auf Hardware-Fehlverhalten beruhen, wie Heartbleed oder Rowhammer, mögen möglich sein, aber man kann die VM zum Beispiel nicht dazu bringen, eine Zahl als Pointer zu interpretieren und so außerhalb des eigenen Wasm-Speichers zu referenzieren.
      WASM-Bytecode lässt sich sehr einfach in Maschinencode übersetzen, sodass eine Implementierung kleiner und schneller sein kann als bei einer VM.
      Es ist nicht Eigentum eines bestimmten Unternehmens, es gibt eine gut geschriebene öffentliche Spezifikation, die jeder nutzen kann, und als Webstandard benötigt es keine Browser-Erweiterung.
      Client-seitige Berechnung findet schon heute in JavaScript statt, und Wasm-Code kann auf eine Weise effizient sein, die mit JavaScript nicht möglich ist, also gilt das dort sogar noch mehr.
    • Java Applets und ActiveX vermittelten den Zugriff auf das darunterliegende Betriebssystem weniger stark.
      Bei Applets in gewissem Maß, bei ActiveX fast gar nicht, und die „Außenplattform“ von WASM ist grob gesagt die JavaScript-Runtime, während die Außenplattform von Applets eher execve(2) nahekommt.
    • Dieser Artikel behandelt WASM auf dem Server, also ist das etwas anderes als die Verlagerung von Server-Rechenkosten auf den Client.
      WASM kann dafür verwendet werden, aber nicht immer, und Unterschiede wie besseres Sandboxing und stärkere Isolation wurden in anderen Antworten bereits gut erklärt.
  • Zu sagen, „Amazon habe mit Lambda das Zeitalter des Serverless Computing eingeläutet“, passt nicht ganz, denn Google App Engine erschien schon 2008 und war damit 6 Jahre früher als Lambda.

    • Es gab auch Heroku und die damalige Generation von PaaS.
      Solche Produkte und auch eine Bezeichnung dafür gab es bereits seit einigen Jahren, daher ist mir nicht ganz klar, warum dann der Name „serverless“ aufkam und woher er stammt.
      App Engine hatte ebenfalls Batch-Worker und Web-Worker, und bei Heroku war es genauso.
      Beides waren Produkte aus der Zeit vor Docker, daher mag es sein, dass Menschen sie anders wahrnehmen, aber auch Lambda wurde meines Wissens nicht von Anfang an mit Docker eingeführt.
  • Die Aussage „Aus Sicherheitsgründen ist die dynamische Erzeugung von Wasm-Code nicht erlaubt, daher ist JIT-Kompilierung unmöglich“ scheint nicht zu stimmen
    Um Dinge wie sauberes Hot Reloading von Code zu erlauben, wäre das nahezu eine grundlegende Funktion
    Die Sicherheitslogik dahinter halte ich für schwach
    JS kann Hot Reload während der Ausführung oder sogar aggressivere Code-Erzeugung ermöglichen, ohne die Sicherheit zu verletzen, und wenn man die gesamte Wasm-Runtime dynamisch neu lädt und dabei den Speicher erhält, könnte man Code-Erzeugung oder Hot Reload ebenfalls nachahmen, auch wenn die User Experience grob wäre
    Ich sehe keinen Grund, warum das technisch unmöglich sein sollte, und wenn es eine Sicherheitsmaßnahme ist, scheint sie zu leicht umgehbar zu sein
    WASM-Bytecode ist konzeptionell Dingen wie .NET IL oder Java-Bytecode, die mit Blick auf JIT-Kompilierung entworfen wurden, sehr ähnlich
    Ich mag WASM nicht besonders, weil es wie ein Projekt wirkt, dem eine klare Richtung und der Wille fehlen, rechtzeitig erfolgreich zu werden
    Der Name deutet auf „Assembly für das Web“ an, also Maschinensprache für eine virtuelle CPU, tatsächlich ist es aber eine Zwischenrepräsentation für Compiler-Backends, und auch höherstufige Funktionen wie Garbage-Collection-Unterstützung sind geplant, wodurch das Konzept unscharf wirkt
    Die zuvor genannten Grundfunktionen wie Hot Reload, Threading ohne hackartige Umwege, direkte DOM-Anbindung ohne JavaScript, Grafik-/Rechen-APIs mit geringem Overhead und Audio-Zugriff auf niedriger Ebene fehlen ebenfalls noch
    Es ist schwer, große Multimedia-Apps ohne große Kompromisse laufen zu lassen

    • Der Satz stimmt
      Wasm kann Speicher nicht als ausführbar markieren und ist faktisch eher wie eine Harvard-Architektur aufgebaut, bei der Code und Speicher getrennt sind
      Außerdem kann es nicht zu beliebigen Stellen im Code springen, und es gibt auch keine eigentlichen Sprungbefehle
      JIT bedeutet hier, während der Ausführung nativen Code zu kompilieren und auszuführen, was im Browser oder in einer Wasm-Sandbox ein großes Sicherheitsrisiko wäre
      Das ist in das Design und den Befehlssatz eingebaut und keine Eigenschaft, die sich leicht umgehen lässt; Details dazu stehen unter https://webassembly.org/docs/security/
      Wasm ähnelt .NET IL oder Java-Bytecode insofern, als die Engine das JIT übernimmt, aber es wäre riskant, Nutzern die Möglichkeit zu geben, außerhalb der Runtime nativen Code zu erzeugen und dorthin zu springen
    • Browser verwenden für WASM eindeutig irgendeine Form von JIT
      Daher kann es ähnlich wie bei JIT beim ersten Ausführen von WASM-Code zu einer kurzen „Warmup-Pause“ kommen, wobei sich das in den letzten Jahren stark verbessert hat
      Außerdem kann man meines Wissens im Browser auch dynamisch WASM-Blöcke erzeugen, instanziieren und ausführen
      Ob das auch in anderen WASM-Runtimes möglich ist, weiß ich nicht, und im Browser braucht man dafür JavaScript, aber wenn man auf irgendeine „Web-API“ zugreifen will, braucht man das ohnehin
  • WASM macht aus einer sprachspezifischen VM wie einer JavaScript-VM eine allgemeine VM, die überall dort genutzt werden kann, wo eine JavaScript-VM eingesetzt wird
    Natürlich ist es nicht nur darauf beschränkt
    Allgemein bedeutet hier, dass sich mit einem Compiler oder Interpreter fast alles ausführen lässt, einschließlich JavaScript
    Da es meist als Teil einer JavaScript-Engine implementiert wird, übernimmt es viele Eigenschaften wie Sandboxing und den Zugang zu den betreffenden APIs
    Die Standardisierung dieses Zugangs ist noch im Gange, aber am Ende werden Dinge, die heute nur mit JavaScript möglich sind, auch in WASM möglich sein, und zusätzlich noch mehr Dinge, die mit JavaScript schwierig oder unmöglich sind
    Es könnte auch schneller und flüssiger laufen
    Der Kern von WASM besteht darin, viele der Einschränkungen zu beseitigen, die in von JavaScript dominierten Umgebungen bestanden
    JavaScript ist eine Sprache, die polarisiert, also wird sie von der einzigen Option zu einer unter mehreren
    WASM wurde schon als JavaScript-Ersatz, Docker-Ersatz, Java-Ersatz und CGI-Ersatz beschrieben; kurz gesagt ist es all das und noch mehr

    • Mit JavaScript selbst habe ich kein Problem, aber das Ökosystem zur Auslieferung von JS im Web ist aus meiner Sicht das Problem
      Es gibt zu viele Werkzeuge für ähnliche Aufgaben, und die Grenzen zwischen ihnen sind unklar
      Am Ende bekommt man zwar alles zum Laufen, aber für mich wirkt es fragil, und für Leute, die das nicht beruflich machen, ist es abschreckend
      Wenn ich heute etwas fürs Web bauen muss, nutze ich meist leptos; die Developer Experience ist viel besser, und obwohl es noch nicht einmal 1.x ist, fühlt es sich stabiler an, als fünf Tools zusammenzukleben, nur um JS-Bundles zu transpilen, zu obfuskieren, zu minifizieren und zu verpacken
  • Dieser Artikel erinnert mich an ein altes Software-Gesetz, das früher oft zitiert wurde
    Eine hinreichend große und langlebige Anwendung wird am Ende den gesamten Software-Stack, auf dem sie läuft, bis hin zum Betriebssystem neu implementieren — und zwar schlecht
    Ich weiß nicht mehr genau, woher das stammt, aber erstaunlich oft trifft es zu

    • Die pointierte Version ist als Greenspuns zehntes Gesetz bekannt
      „Jedes hinreichend komplexe C- oder Fortran-Programm enthält eine ad-hoc, informell spezifizierte, fehlerbehaftete und langsame Implementierung von der Hälfte von Common Lisp“
      Das allgemeinere Muster wird als Inner-Platform Effect bezeichnet
  • Wenn man die Prämisse des Titels weiter fasst, dann müsste WASM, um der echte Nachfolger in dieser Linie zu sein, genauso einfach zu deployen sein wie eine PHP-App auf irgendeinem gehosteten LAMP-Stack hochzuladen und bereitzustellen
    Im Moment scheint es noch nicht so einfach zu sein wie die PHP-Deployment-Erfahrung

    • WASM läuft im Browser
      Ich weiß nicht, was sich beim Hosting dafür ändern müsste
  • Ich sehe das anders
    Ich denke, die Zukunft ist local-first
    Also ein Modell, bei dem eine App kaum Hilfe vom Server braucht und größtenteils im Browser des Nutzers läuft
    Apps wie Figma, Linear und Superhuman nutzen dieses Modell sehr erfolgreich, und Stackblitz bis zu einem gewissen Grad ebenfalls
    Wenn eine einigermaßen komplexe App wie Figma fast vollständig im Browser des Nutzers laufen kann, dann dürfte das bei den meisten Apps ebenfalls möglich sein
    Der Server übernimmt dabei hauptsächlich die Rolle, Daten zwischen verschiedenen Instanzen zu synchronisieren, wenn Nutzer die App von mehreren Orten aus verwenden
    Es entstehen gerade Werkzeuge wie Electric-SQL, aber sie sind noch nicht ausgereift; wenn solche Bibliotheken reifer werden, wird dieser Bereich stark wachsen
    Serverless dient größtenteils dazu, dass Unternehmen wie Amazon und Azure Geld verdienen, und wird am Ende wie CGI enden
    WASM kann ebenfalls erfolgreich sein, aber wahrscheinlich vor allem im Browser des Nutzers
    Microsoft setzt WASM für C#/Blazor ein, aber ich glaube nicht, dass dotnet im Browser so schnell wie JavaScript wird, daher halte ich das nicht für den richtigen Ansatz

    • CGI gibt Nutzern und kleinen Websites Macht
      Niemand redet nur darüber, weil es sich nicht auf 1 Billion Ad-Impressions pro Sekunde skalieren lässt
      Jedes Mal, wenn jemand eine Serverless-Funktion schreibt, wird Bezos’ Yacht um 10 Fuß länger
    • Es ist fraglich, Figma als local-first zu bezeichnen
      Wenn man offline ist oder in einer Umgebung mit instabilem WLAN sitzt, kann man Designs nicht laden, und zumindest wenn sich das nicht kürzlich geändert hat, wird nach dem Bearbeiten auch nichts gespeichert, wenn man den Browser schließt, während das WLAN weg ist
    • Mit anderen Worten: Die Zukunft ist also eine Rückkehr dazu, wie wir Apps vor dem Web-Zeitalter ausgeführt haben
    • Ich unterstütze die Weiterentwicklung von Client-seitigen Anwendungen, glaube aber nicht, dass sie zwingend im Browser oder in einer Sandbox laufen oder über einen App Store gekauft werden müssen
      Und es ist auch überhaupt keine neue Idee
    • dotnet im Browser ist vielleicht nicht so schnell wie JavaScript, aber beide werden schnell genug sein
      Wir entwickeln mit Blazor WASM, und in puncto Performance ist dotnet nicht das Problem
  • Im Grunde bauen wir also die JVM und ihr Ökosystem neu?

    • Bis zu einem gewissen Grad ja, aber WASM wurde mit anderen Randbedingungen entworfen, die besser passen, wenn man eine Runtime überall hineindrücken möchte
      Manchmal ist es tatsächlich eine großartige Idee, X neu zu bauen und dabei die Lehren der Vergangenheit einzubeziehen
    • In gewisser Hinsicht ja, aber WASM unterstützt viel mehr Sprachen
      Als man zum Beispiel um 2010 herum begann zu untersuchen, wie man C/C++-Code im Browser ausführen könnte, war es praktisch unmöglich, C/C++ zur JVM zu kompilieren
      Damals waren Java-Applets noch relevant, also wäre das schön gewesen, wenn es möglich gewesen wäre; WASM gab es aber noch nicht, Emscripten schon, und darüber ging es über asm.js schließlich zur Entstehung von WASM
    • Die JVM ist großartig, aber das bedeutet nicht, dass sie die endgültige Antwort für dieses Genre ist
      Als jemand, der in Sprachkursen der 2000er mit Classloadern herumgespielt und JVM-Assembler von Hand geschrieben hat, bin ich mir nicht einmal sicher, ob die JVM hier den Höhepunkt darstellt
      Sie hat zwar ein großes Ökosystem ermöglicht, aber die Schnittstellen der JVM zur Außenwelt sind wirklich ein grobes Durcheinander
      Seit über 20 Jahren stöhne ich jedes Mal, wenn ich auf irgendetwas mit JVM-Bezug stoße
      Wenn man Packaging und Ökosystem von Rust mit Python oder, noch schlimmer, C++ vergleicht, zeigt das, dass eine Neuerfindung unter Einbeziehung der Lehren der letzten Jahrzehnte sehr gut sein kann
    • WASM hat allerdings ein großes Classloader-/Linker-Problem
      Zwei wasm-Dateien zu einer zusammenzuführen und die Speicherzusammenführung korrekt hinzubekommen, ist nach wie vor sehr schwierig
      Das Komponentenmodell könnte das vielleicht beheben, aber es ist mit so viel unnötigem Ballast aufgebläht, dass es bis zur Übernahme durch Safari noch lange dauern könnte
    • Ja, und das gilt genauso für .Net CLR usw.
  • Ich denke schon seit Langem, dass wir auf eine Welt zusteuern, in der WASM den Code von Lambda-Funktionen in der Cloud ersetzt
    Traditionell wird WASM als etwas betrachtet, das auf einer Host-Plattform läuft, aber es gibt keinen zwingenden Grund, warum das so sein muss
    Wegen des Sandbox-Charakters von WASM könnte es technisch sogar außerhalb des Betriebssystems oder in ring0 laufen und so viel Betriebssystem-Overhead umgehen
    Wenn man nach WASM kompiliert, werden viele Deployment-Probleme aus Sicht der Nutzer deutlich einfacher, und die Hosting-Umgebung bietet viel Spielraum für Optimierungen
    Es könnte sogar spezielle Hardware geben, um WASM schneller auszuführen

  • Beliebigen Code aus beliebigen nicht vertrauenswürdigen Quellen automatisch auszuführen, ist schlecht, und man kann auch nicht sagen, dass das dieselbe Rolle wie serverseitiges CGI erfüllt