Skip to content

Commit

Permalink
feat: add support for zig (vmware-labs#144)
Browse files Browse the repository at this point in the history
  • Loading branch information
voigt committed Aug 17, 2023
1 parent 42dfc27 commit d01b8c1
Show file tree
Hide file tree
Showing 7 changed files with 519 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Wasm Workers Server focuses on simplicity. We want you to run workers (written i
| Go | ✅ | No | [#95](https://github.com/vmware-labs/wasm-workers-server/issues/95) |
| Ruby | ✅ | [Yes](https://workers.wasmlabs.dev/docs/languages/ruby#installation) | [#63](https://github.com/vmware-labs/wasm-workers-server/issues/63) |
| Python | ✅ | [Yes](https://workers.wasmlabs.dev/docs/languages/python#installation) | [#63](https://github.com/vmware-labs/wasm-workers-server/issues/63) |
| Zig | 🚧 | No | [#144](https://github.com/vmware-labs/wasm-workers-server/issues/144) |
| Zig | | Yes | [#144](https://github.com/vmware-labs/wasm-workers-server/issues/144) |
| PHP | 🚧 | No | [#100](https://github.com/vmware-labs/wasm-workers-server/issues/100) |
To get more information about multi-language support in Wasm Workers Server, [check our documentation](https://workers.wasmlabs.dev/docs/languages/introduction).
Expand Down
4 changes: 4 additions & 0 deletions kits/zig/worker/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
zig-cache/
zig-out/
examples/json.zig
examples/output.zig
49 changes: 49 additions & 0 deletions kits/zig/worker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Zig kit

This folder contains the Zig kit or SDK for Wasm Workers Server. Currently, it uses the regular STDIN / STDOUT approach to receive the request and provide the response.

> *Note: this assumes Zig `0.11.0`*
## build

To build all example in ./examples

```bash
$ zig build -Dtarget="wasm32-wasi"
```

To build a specific example

```bash
$ zig build-exe examples/<example>.zig -target wasm32-wasi
```

## testing

from `./kits/zig/worker` execute

```bash
$ zig build -Dtarget="wasm32-wasi"
$ wws ./zig-out/bin/
```

## sockaddr issue

Using `*http.Server.Response` was unsuccessful and lead to following error:

```
$ worker git:(144_-_add_support_for_zig) ✗ zig build -Dtarget="wasm32-wasi"
zig build-exe main Debug wasm32-wasi: error: the following command failed with 1 compilation errors:
/Users/c.voigt/.asdf/installs/zig/0.11.0/zig build-exe /Users/c.voigt/go/src/github.com/voigt/wasm-workers-server/kits/zig/worker/examples/main.zig --cache-dir /Users/c.voigt/go/src/github.com/voigt/wasm-workers-server/kits/zig/worker/zig-cache --global-cache-dir /Users/c.voigt/.cache/zig --name main -target wasm32-wasi -mcpu generic --mod worker::/Users/c.voigt/go/src/github.com/voigt/wasm-workers-server/kits/zig/worker/src/worker.zig --deps worker --listen=-
Build Summary: 6/9 steps succeeded; 1 failed (disable with --summary none)
install transitive failure
└─ install main transitive failure
└─ zig build-exe main Debug wasm32-wasi 1 errors
/Users/c.voigt/.asdf/installs/zig/0.11.0/lib/std/os.zig:182:28: error: root struct of file 'os.wasi' has no member named 'sockaddr'
pub const sockaddr = system.sockaddr;
~~~~~~^~~~~~~~~
referenced by:
Address: /Users/c.voigt/.asdf/installs/zig/0.11.0/lib/std/net.zig:18:12
Address: /Users/c.voigt/.asdf/installs/zig/0.11.0/lib/std/net.zig:17:28
remaining reference traces hidden; use '-freference-trace' to see all reference traces
```
85 changes: 85 additions & 0 deletions kits/zig/worker/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const std = @import("std");

const package_name = "worker";
const package_path = "src/worker.zig";

const examples = [2][]const u8{ "main", "basic" };
// const examples = [4][]const u8{ "main", "basic", "json", "output" };

pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{ });
const optimize = b.standardOptimizeOption(.{});

const worker_module = b.createModule(.{
.source_file = .{ .path = package_path },
});

inline for (examples) |example| {
const exe = b.addExecutable(.{
.name = example,
.root_source_file = .{ .path = "examples/" ++ example ++ ".zig" },
.target = target,
.optimize = optimize,
});

exe.addModule("worker", worker_module);

b.installArtifact(exe);
}

// const exe = b.addExecutable(.{
// .name = "worker",
// // In this case the main source file is merely a path, however, in more
// // complicated build scripts, this could be a generated file.
// .root_source_file = .{ .path = "examples/main.zig" },
// .target = target,
// .optimize = optimize,
// });

// exe.addModule("worker", worker_module);
// // exe.install();

// // This declares intent for the executable to be installed into the
// // standard location when the user invokes the "install" step (the default
// // step when running `zig build`).
// b.installArtifact(exe);

// // This *creates* a Run step in the build graph, to be executed when another
// // step is evaluated that depends on it. The next line below will establish
// // such a dependency.
// const run_cmd = b.addRunArtifact(exe);

// // By making the run step depend on the install step, it will be run from the
// // installation directory rather than directly from within the cache directory.
// // This is not necessary, however, if the application depends on other installed
// // files, this ensures they will be present and in the expected location.
// run_cmd.step.dependOn(b.getInstallStep());

// // This allows the user to pass arguments to the application in the build
// // command itself, like this: `zig build run -- arg1 arg2 etc`
// if (b.args) |args| {
// run_cmd.addArgs(args);
// }

// // This creates a build step. It will be visible in the `zig build --help` menu,
// // and can be selected like this: `zig build run`
// // This will evaluate the `run` step rather than the default, which is "install".
// const run_step = b.step("run", "Run the app");
// run_step.dependOn(&run_cmd.step);

// // Creates a step for unit testing. This only builds the test executable
// // but does not run it.
// const unit_tests = b.addTest(.{
// .root_source_file = .{ .path = "src/main.zig" },
// .target = target,
// .optimize = optimize,
// });

// const run_unit_tests = b.addRunArtifact(unit_tests);

// // Similar to creating the run step earlier, this exposes a `test` step to
// // the `zig build --help` menu, providing a way for the user to request
// // running the unit tests.
// const test_step = b.step("test", "Run unit tests");
// test_step.dependOn(&run_unit_tests.step);
}
23 changes: 23 additions & 0 deletions kits/zig/worker/examples/basic.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const std = @import("std");
const io = std.io;
const http = std.http;
const worker = @import("worker");

var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = arena.allocator();

// Not working with *http.Server.Response
// fn cool(resp: *http.Server.Response, r: *http.Client.Request) void {
fn requestFn(resp: *worker.Response, r: *http.Client.Request) void {
_ = r;
std.debug.print("Hello from function\n", .{ });

_ = &resp.httpHeader.append("content-type", "text/plain");
_ = &resp.httpHeader.append("x-generated-by", "wasm-workers-server");

_ = &resp.writeAll("Zig World!");
}

pub fn main() !void {
worker.ServeFunc(requestFn);
}
38 changes: 38 additions & 0 deletions kits/zig/worker/examples/main.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const std = @import("std");
const io = std.io;
const http = std.http;
const worker = @import("worker");

var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = arena.allocator();

// Not working with *http.Server.Response
// fn cool(resp: *http.Server.Response, r: *http.Client.Request) void {
fn requestFn(resp: *worker.Response, r: *http.Client.Request) void {
_ = r;
std.debug.print("Hello from function\n", .{ });

// TODO: prepare to read request body and send it back
// std.debug.print("+++ doing payload \n", .{ });
// var payload: []const u8 = "";
// var reqBody = r.reader().readAllAlloc(allocator, 8192) catch unreachable;
// defer allocator.free(reqBody);

// if (reqBody.len == 0) {
// payload = "-";
// } else {
// payload = reqBody;
// }
// std.debug.print("+++ finished payload \n", .{ });

// var resp = r.response;

_ = &resp.httpHeader.append("content-type", "text/plain");
_ = &resp.httpHeader.append("x-generated-by", "wasm-workers-server");

_ = &resp.writeAll("Zig World!");
}

pub fn main() !void {
worker.ServeFunc(requestFn);
}
Loading

0 comments on commit d01b8c1

Please sign in to comment.