Современные реалии таковы, что не каждый бизнес может себе позволить сайт, особенно стартующий бизнес. Поэтому выгодно воспользоваться конструктором сайтов, например filandor. Запуск сайта через несколько минут.

Запуск Zig с WASI на Cloudflare Workers

После недавнего объявления о поддержке WASI в Workers я решил посмотреть, что потребуется, чтобы заставить код, написанный на Zig, работать как Worker, и это оказалось тривиальным. Этот пост документирует процесс, которому я следовал как новый пользователь Zig. Так здорово видеть, что Cloudflare Workers — это многоязычная платформа, позволяющая вам писать программы на языке, который вы любите, или на языке, который вы изучаете!

Привет, мир!

Я ни в коем случае не эксперт по Zig, и, честно говоря, я только начал изучать язык, но нам всем нужно с чего-то начинать. Так что, если мой Zig-код не идеален, потерпите меня. Моя цель состояла в том, чтобы создать настоящую небольшую программу с использованием Zig и развернуть ее на Cloudflare Workers. И посмотреть, как быстро я смогу перейти от пустого экрана к рабочему коду.

Моя цель для этого не была амбициозной, просто прочитайте какой-нибудь текст со стандартного ввода и распечатайте его на стандартный вывод с номерами строк, например, запуск cat -n. Но это показывает, насколько проста парадигма рабочих. Эта программа Zig одинаково работает в командной строке на моем ноутбуке и как HTTP API, развернутый на Cloudflare Workers.

Вот мой код. Он читает строку из стандартного ввода и выводит ту же строку с префиксом номера строки. Он завершается, когда больше нет ввода.

const std = @import("std");

pub fn main() anyerror!void {
	// setup allocator
	var gpa = std.heap.GeneralPurposeAllocator(.{}){};
	defer std.debug.assert(!gpa.deinit());
	const allocator = gpa.allocator();

	// setup streams
	const stdout = std.io.getStdOut().writer();
	const in = std.io.getStdIn();
	var reader = std.io.bufferedReader(in.reader()).reader();

	var counter: u32 = 1;

	// read input line by line
	while (try reader.readUntilDelimiterOrEofAlloc(allocator, '\n', std.math.maxInt(usize))) |line| {
    	    defer allocator.free(line);
    	    try stdout.print("{d}\t{s}\n", .{counter, line});
    	    counter = counter + 1;
	}
}

Чтобы построить Zig-код, вы создаете build.zig файл, который определяет, как построить ваш проект. Для этого тривиального случая я просто решил собрать исполняемый файл из исходников.

const std = @import("std");

pub fn build(b: *std.build.Builder) void {
	const target = b.standardTargetOptions(.{});
	const mode = b.standardReleaseOptions();

	const exe = b.addExecutable("print-with-line-numbers", "src/main.zig");
	exe.setTarget(target);
	exe.setBuildMode(mode);
	exe.install();
}

Запустив zig build компилятор запустится и выведет двоичный файл под zig-out/bin

$ zig build

$ ls zig-out/bin
print-with-line-numbers

$ echo "Hello\nWorld" | ./zig-out/bin/print-with-line-numbers
1    Hello
2    World

БЫЛ ЛИ Я

Следующий шаг — заставить это работать на Workers, но сначала мне нужно скомпилировать его в WASM с поддержкой WASI.

К счастью, это встроено в последние версии Zig, поэтому вы можете просто указать компилятору собрать исполняемый файл, используя wasm32-wasi target, который создаст файл, который можно запустить в любой WASI-совместимой среде выполнения WebAssembly, такой как wasmtime.

Этот же файл .wasm можно запустить в wasmtime и развернуть непосредственно в Cloudflare Workers. Это упрощает сборку, тестирование и развертывание.

$ zig build -Dtarget=wasm32-wasi

$ ls zig-out/bin
print-with-line-numbers.wasm

$ echo "Hello\nWorld" | wasmtime ./zig-out/bin/print-with-line-numbers.wasm
1    Hello
2    World

Zig на рабочих

Когда наш бинарный файл готов к работе, осталось запустить его на Cloudflare Workers с помощью wrangler2. Это так же просто, как опубликовать файл .wasm на work.dev. Если у вас нет учетной записи worker.dev, вы можете пройти обучение в нашем руководстве по началу работы, которое поможет вам перейти от кода к развертыванию за считанные минуты!

Фактически, как только я зарегистрировался в своей учетной записи, все, что мне нужно было сделать, это выполнить первые два шага, установить wrangler и войти в систему.

$ npx wrangler@wasm login
Attempting to login via OAuth...
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth
Successfully logged in.

Затем я выполнил следующую команду, чтобы опубликовать своего работника:

$ npx wrangler@wasm publish --name print-with-line-numbers --compatibility-date=2022-07-07 zig-out/bin/print-with-line-numbers.wasm
Uploaded print-with-line-numbers (3.04 sec)
Published print-with-line-numbers (6.28 sec)
  print-with-line-numbers.workers.dev

После завершения этого шага рабочий процесс готов к запуску, и его можно вызвать, вызвав URL-адрес, напечатанный из приведенного выше вывода.

echo "Hello\nWorld" | curl https://print-with-line-numbers.workers.dev -X POST --data-binary @-
1    Hello
2    World

Успех!

Вывод

Что меня больше всего впечатлило, так это простота этого процесса.

Сначала у меня был скомпилирован двоичный файл для архитектуры моего ноутбука, затем я скомпилировал код в WebAssembly, просто передав флаг компилятору, и, наконец, я запустил это на рабочих процессах. без необходимости изменять какой-либо код.

Конечно, эта программа не очень сложна и не делает ничего, кроме чтения из STDIN и записи в STDOUT, но она дает мне уверенность в том, что это возможно, особенно по мере развития такой технологии, как WASI.