Cloudflare объявила о первом общедоступном экспериментальном предварительном просмотре поддержки цели компиляции wasm32-unknown-emscripten в наборе инструментов wasm-bindgen и среде Rust Workers. Этот путь позволяет собирать и запускать больше нативных приложений и библиотек Rust в формате WebAssembly на глобальной платформе Workers, вместо ограничения библиотеками, заранее совместимыми с традиционной моделью WebAssembly.
Эта работа объединяет Emscripten, который предоставляет слой для связывания нативного кода с веб-средой и эмуляции таких функций, как файловая система, таймеры и сокеты, с wasm-bindgen, отвечающим за создание bindings между Rust и JavaScript. Согласно новым изменениям, компилятор Rust и компилятор Emscripten могут использовать bindings-слой друг друга в рамках одного процесса сборки.
Расширение совместимости библиотек Rust
Cloudflare заявляет, что первые тесты показали лучшую совместимость с библиотеками Rust, включая низкоуровневые библиотеки. Для таких библиотек, как libc, socket2 и Mio, потребовались лишь ограниченные изменения для добавления цели Emscripten в условия платформы. Наиболее сложной библиотекой оказалась Tokio, поскольку Workers работает в одном потоке внутри цикла событий JavaScript, тогда как Tokio традиционно полагается на приостановку потока во время ожидания операций ввода-вывода.
Для устранения этого различия Cloudflare работает над двумя направлениями. Первое использует WebAssembly JavaScript Promise Integration, позволяющий приостанавливать стек WebAssembly и возвращать управление циклу событий JavaScript. Это требует тщательного управления локальным контекстом потока при приостановке и возобновлении стеков. Второе направление предлагает шаблон LocalEventLoop для Tokio, в котором готовые задачи выполняются через операцию drive(), а ожидание заменяется сигналом уведомления для цикла событий хоста.
Поддержка сокетов и сетей TCP
Поддержка сетей стала ещё одной проблемой, поскольку Tokio использует epoll_wait() через Mio, тогда как Emscripten предоставлял ограниченную поддержку poll() и слой эмуляции WebSocket. Поэтому Cloudflare внесла более 40 запросов на слияние в Emscripten для добавления слоя -sNODERAWSOCKETS, который обеспечивает поддержку epoll, TCP, UDP и Unix-сокетов через интерфейс node:net.
Поскольку Workers обеспечивает совместимость с интерфейсами Node.js, тот же мост можно использовать внутри платформы без добавления отдельных специализированных интерфейсов между Emscripten и Cloudflare. Эти возможности по-прежнему являются экспериментальными, а некоторые исправления для Tokio всё ещё проходят рассмотрение перед окончательным включением в проект.
Практическое тестирование через сервер Minecraft
Чтобы проверить степень совместимости, инженер Cloudflare Dan Lapid запустил написанный на Rust сервер Minecraft, известный как Pumpkin, внутри Durable Object. Поскольку Durable Object работает в одном потоке, игровые циклы, планирование регионов и задачи Rayon были преобразованы в кооперативные задачи внутри цикла Tokio вместо использования отдельных потоков операционной системы.
Сервер использовал файловую систему через интерфейсы Node.js, а файлы хранились в SQLite Durable Object с помощью библиотеки worker-fs-mount. Соединения игроков также проходили через TCP ingress, а затем направлялись на TCP-сервер внутри объекта. По данным Cloudflare, это позволило запустить многопользовательский сервер Minecraft с сохранением состояния и перезапуском объекта из сохранённого мира.
Почему это развитие важно?
Практическая ценность изменения заключается не только в добавлении новой цели компиляции, но и в сокращении числа библиотек и приложений, которые необходимо переписывать для работы на Workers. Однако Cloudflare описывает поддержку как экспериментальную и предрелизную, а новая архитектура Tokio, поддержка JSPI и некоторые интеграции Emscripten всё ещё находятся в разработке и проходят рассмотрение upstream. Поэтому этот путь открывает возможности для экспериментов с запуском нативных приложений Rust, но пока не доказывает, что он является полностью готовой и стабильной заменой для всех традиционных сред выполнения.