Cloudflare hat eine erste öffentliche experimentelle Vorschau auf die Unterstützung des Kompilierungsziels wasm32-unknown-emscripten innerhalb der Toolchain wasm-bindgen und der Umgebung Rust Workers angekündigt. Dieser Weg ermöglicht es, eine größere Zahl nativer Rust-Anwendungen und -Bibliotheken als WebAssembly auf der globalen Workers-Plattform zu erstellen und auszuführen, statt sich auf Bibliotheken zu beschränken, die bereits mit dem herkömmlichen WebAssembly-Modell kompatibel sind.
Diese Arbeit verbindet Emscripten, das eine Schicht zur Anbindung nativen Codes an die Webumgebung und zur Emulation von Funktionen wie Dateisystem, Timern und Sockets bereitstellt, mit wasm-bindgen, das die Erstellung von Bindings zwischen Rust und JavaScript übernimmt. Aufgrund der neuen Änderungen können sowohl der Rust-Compiler als auch der Emscripten-Compiler die jeweils andere Binding-Schicht innerhalb desselben Build-Prozesses verwenden.
Erweiterung der Kompatibilität von Rust-Bibliotheken
Cloudflare zufolge zeigten die ersten Tests eine bessere Kompatibilität mit Rust-Bibliotheken, darunter auch Bibliotheken auf niedriger Ebene. Bibliotheken wie libc, socket2 und Mio benötigten nur begrenzte Anpassungen, um das Emscripten-Ziel zu den Plattformbedingungen hinzuzufügen. Die komplexeste Bibliothek war Tokio, da Workers in einem einzelnen Thread innerhalb einer JavaScript-Ereignisschleife ausgeführt wird, während Tokio traditionell den Thread während des Wartens auf Ein- und Ausgabeoperationen anhält.
Um diesen Unterschied zu bewältigen, arbeitet Cloudflare an zwei Ansätzen. Der erste nutzt WebAssembly JavaScript Promise Integration, die es ermöglicht, den WebAssembly-Stack anzuhalten und die Kontrolle an die JavaScript-Ereignisschleife zurückzugeben. Dies erfordert eine sorgfältige Verwaltung des threadlokalen Kontexts beim Anhalten und Fortsetzen der Stacks. Der zweite Ansatz schlägt ein LocalEventLoop-Muster für Tokio vor, bei dem bereite Aufgaben über eine drive()-Operation ausgeführt werden und das Warten durch ein Wecksignal an die Ereignisschleife des Hosts ersetzt wird.
Unterstützung für Sockets und TCP-Netzwerke
Die Netzwerkunterstützung stellte eine weitere Herausforderung dar, da Tokio über Mio auf epoll_wait() setzt, während Emscripten nur begrenzte Unterstützung für poll() und eine Schicht zur Simulation von WebSocket bereitstellte. Daher steuerte Cloudflare mehr als 40 Pull Requests zu Emscripten bei, um die Schicht -sNODERAWSOCKETS hinzuzufügen, die über die Schnittstelle node:net Unterstützung für epoll, TCP, UDP und Unix-Sockets bereitstellt.
Da Workers Kompatibilität mit Node.js-Schnittstellen bietet, kann dieselbe Brücke innerhalb der Plattform verwendet werden, ohne separate benutzerdefinierte Schnittstellen zwischen Emscripten und Cloudflare hinzuzufügen. Diese Funktionen bleiben experimentell, und einige Tokio-Patches werden weiterhin geprüft, bevor sie endgültig in das Projekt integriert werden.
Praktischer Test mit einem Minecraft-Server
Um den Umfang der Kompatibilität zu testen, führte der Cloudflare-Ingenieur Dan Lapid den in Rust geschriebenen Minecraft-Server namens Pumpkin innerhalb eines Durable Object aus. Da ein Durable Object in einem einzelnen Thread läuft, wurden die Spielschleifen, die Bereichsplanung und die Rayon-Aufgaben in kooperative Aufgaben innerhalb einer Tokio-Schleife umgewandelt, statt auf unabhängige Betriebssystem-Threads zurückzugreifen.
Der Server verwendete das Dateisystem über Node.js-Schnittstellen und speicherte Dateien mithilfe der Bibliothek worker-fs-mount in der SQLite-Datenbank des Durable Object. Die Verbindungen der Spieler liefen außerdem über einen TCP-Ingress und anschließend zu einem TCP-Server innerhalb des Objekts. Cloudflare zufolge ermöglichte dies den Betrieb eines Multiplayer-Minecraft-Servers mit Speicherung des Zustands und einem Neustart des Objekts aus der gespeicherten Welt.
Warum ist diese Entwicklung wichtig?
Der praktische Wert der Änderung liegt nicht nur in der Hinzufügung eines neuen Kompilierungsziels, sondern auch darin, die Zahl der Bibliotheken und Anwendungen zu verringern, die umgeschrieben werden müssen, damit sie auf Workers funktionieren. Cloudflare bezeichnet die Unterstützung jedoch als experimentell und vor der Veröffentlichung. Außerdem befinden sich das neue Tokio-Design, die JSPI-Unterstützung und einige Emscripten-Integrationen weiterhin in Entwicklung und werden upstream geprüft. Der Weg eröffnet daher Experimente mit dem Betrieb nativer Rust-Anwendungen, beweist aber noch nicht, dass er eine vollständige und stabile Alternative für alle herkömmlichen Laufzeitumgebungen darstellt.