Browse Source

[Zig] Add ZZZ framework (#9715)

* feat(zig) add zzz

* Update benchmark_config.json

* feat(zig/zzz): add date header

* fix(main.zig) build error

* fix(main.zig) build error 2

* Dupa date

* Alloc date

* Fix build error

* Update main.zig

* Fix date

* Update README.md

* Fix build error 3
Kayden 4 months ago
parent
commit
20e3c17011

+ 2 - 0
frameworks/Zig/zzz/.gitignore

@@ -0,0 +1,2 @@
+.zig-out
+.zig-cache

+ 18 - 0
frameworks/Zig/zzz/README.md

@@ -0,0 +1,18 @@
+
+# [ZZZ](https://github.com/tardy-org/zzz) - Web Franework.
+
+## Description
+
+ZZZ is a framework for writing performant and reliable networked services in Zig. It supports both HTTP and HTTPS.
+
+## Test URLs
+
+### Test 1: JSON Encoding
+
+    http://localhost:8080/json
+
+### Test 2: Plaintext
+
+    http://localhost:8080/plaintext
+
+

+ 24 - 0
frameworks/Zig/zzz/benchmark_config.json

@@ -0,0 +1,24 @@
+{
+  "framework": "zzz",
+  "tests": [{
+    "default": {
+      "json_url": "/json",
+      "plaintext_url": "/plaintext",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "None",
+      "framework": "zzz",
+      "language": "Zig",
+      "flavor": "None",
+      "orm": "None",
+      "platform": "None",
+      "webserver": "None",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "ZZZ (Zig)",
+      "notes": "",
+      "versus": ""
+    }
+  }]
+}

+ 22 - 0
frameworks/Zig/zzz/build.zig

@@ -0,0 +1,22 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+    const target = b.standardTargetOptions(.{});
+    const optimize = b.standardOptimizeOption(.{});
+    const root_source_file = b.path("src/main.zig");
+
+    const zzz = b.dependency("zzz", .{
+        .target = target,
+        .optimize = optimize,
+    });
+
+    const exe = b.addExecutable(.{
+        .name = "zzz",
+        .target = target,
+        .optimize = optimize,
+        .root_source_file = root_source_file,
+        .strip = true,
+    });
+    exe.root_module.addImport("zzz", zzz.module("zzz"));
+    b.installArtifact(exe);
+}

+ 17 - 0
frameworks/Zig/zzz/build.zig.zon

@@ -0,0 +1,17 @@
+.{
+    .name = .zzz_bench,
+    .version = "0.0.0",
+    .fingerprint = 0xab2ef1c28b2bcc91,
+    .minimum_zig_version = "0.14.0",
+    .dependencies = .{
+        .zzz = .{
+            .url = "git+https://github.com/tardy-org/zzz#90cc62494644e7234efd85ab1df5d65440f9eead",
+            .hash = "zzz-0.3.0-4HoaJqpQAgDgcImt8cC2cpT59J25JNDynMDt4qLaXDYK",
+        },
+    },
+    .paths = .{
+        "src/",
+        "build.zig",
+        "build.zig.zon",
+    },
+}

+ 94 - 0
frameworks/Zig/zzz/src/main.zig

@@ -0,0 +1,94 @@
+const std = @import("std");
+
+const zzz = @import("zzz");
+const http = zzz.HTTP;
+
+const tardy = zzz.tardy;
+const Tardy = tardy.Tardy(.auto);
+const Runtime = tardy.Runtime;
+const Socket = tardy.Socket;
+
+const Server = http.Server;
+const Router = http.Router;
+const Context = http.Context;
+const Route = http.Route;
+const Respond = http.Respond;
+
+const Message = struct { message: []const u8 };
+var date: [29]u8 = undefined;
+
+pub fn main() !void {
+    const host: []const u8 = "0.0.0.0";
+    const port: u16 = 8080;
+
+    const date_thread = try std.Thread.spawn(.{}, struct {
+        fn a() !void {
+            while (true) {
+                var d = http.Date.init(std.time.timestamp());
+                const http_date = d.to_http_date();
+                _ = try http_date.into_buf(date[0..]);
+                std.time.sleep(std.time.ns_per_ms * 985);
+            }
+        }
+    }.a, .{});
+
+    date_thread.detach();
+
+    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+    defer if (gpa.deinit() == .leak) {
+        @panic("Memory leak has occurred!");
+    };
+
+    const allocator = gpa.allocator();
+
+    var t = try Tardy.init(allocator, .{
+        .threading = .all,
+    });
+    defer t.deinit();
+
+    var router = try Router.init(allocator, &.{
+        Route.init("/plaintext").get({}, home_handler).layer(),
+        Route.init("/json").get({}, json_handler).layer(),
+    }, .{});
+    defer router.deinit(allocator);
+
+    var socket = try Socket.init(.{ .tcp = .{ .host = host, .port = port } });
+    defer socket.close_blocking();
+    try socket.bind();
+    try socket.listen(4096);
+
+    const EntryParams = struct {
+        router: *const Router,
+        socket: Socket,
+    };
+
+    try t.entry(
+        EntryParams{ .router = &router, .socket = socket },
+        struct {
+            fn entry(rt: *Runtime, p: EntryParams) !void {
+                var server = Server.init(.{
+                    .capture_count_max = 0,
+                });
+                try server.serve(rt, p.router, .{ .normal = p.socket });
+            }
+        }.entry,
+    );
+}
+
+pub fn home_handler(ctx: *const Context, _: void) !Respond {
+    try ctx.response.headers.put("Date", try ctx.allocator.dupe(u8, date[0..]));
+    return ctx.response.apply(.{
+        .mime = http.Mime.TEXT,
+        .body = "Hello, World!",
+        .status = .OK,
+    });
+}
+
+pub fn json_handler(ctx: *const Context, _: void) !Respond {
+    try ctx.response.headers.put("Date", try ctx.allocator.dupe(u8, date[0..]));
+    return ctx.response.apply(.{
+        .mime = http.Mime.JSON,
+        .body = try std.json.stringifyAlloc(ctx.allocator, Message{ .message = "Hello, World!" }, .{}),
+        .status = .OK,
+    });
+}

+ 21 - 0
frameworks/Zig/zzz/zzz.dockerfile

@@ -0,0 +1,21 @@
+FROM debian:12.9
+
+WORKDIR /app
+
+COPY src src
+COPY build.zig.zon build.zig.zon
+COPY build.zig build.zig
+
+ARG ZIG_VER=0.14.0
+
+RUN apt-get update && apt-get install -y curl xz-utils ca-certificates
+
+RUN curl https://ziglang.org/download/${ZIG_VER}/zig-linux-$(uname -m)-${ZIG_VER}.tar.xz -o zig-linux.tar.xz && \
+  tar xf zig-linux.tar.xz && \
+  mv zig-linux-$(uname -m)-${ZIG_VER}/ /opt/zig
+
+RUN /opt/zig/zig build -Doptimize=ReleaseFast
+
+EXPOSE 8080
+
+CMD ["zig-out/bin/zzz"]