Browse Source

Add Zig Zinc framework (#9289)

* Adding Zinc framework

* Update num_threads and fixed headers

* Update dependency

* Update build command

* Update Zinc documentation

* Run workflow

* Update Zinc approach

* Update zinc Allocator and plaintext test

* Update zinc dependencies

* bug fix

* Fixed zinc dependencies and port
DravenK 10 months ago
parent
commit
3d7db350d2

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

@@ -0,0 +1,2 @@
+zig-cache/**/*',
+zig-out: 'zig-out/**/*',

+ 32 - 0
frameworks/Zig/zinc/README.md

@@ -0,0 +1,32 @@
+# [Zinc](https://zinc.zon.dev) web framework
+
+## Description
+
+Zinc is a web framework written in pure Zig with a focus on high performance, usability, security, and extensibility.
+
+* [Documentation](https://zinc.zon.dev/)
+
+### Some features are:
+- **Fast**
+- **Custom allocator**
+- **Multithreading**
+- **Middleware**
+- **Routes grouping**
+- **Rendering built-in**
+- **Extensible**
+- **Suite of unit tests**
+- **Usability**
+
+## Important Libraries
+The tests were run with:
+* [Software](https://zinc.zon.dev/)
+* [Example](https://github.com/zon-dev/zinc-examples)
+
+## Test URLs
+### JSON
+
+http://localhost:8080/json
+
+### PLAINTEXT
+
+http://localhost:8080/plaintext

+ 26 - 0
frameworks/Zig/zinc/benchmark_config.json

@@ -0,0 +1,26 @@
+{
+  "framework": "zinc",
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 3000,
+        "approach": "Realistic",
+        "classification": "Fullstack",
+        "database": "None",
+        "framework": "Zinc",
+        "language": "Zig",
+        "flavor": "None",
+        "orm": "None",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "Zinc",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 78 - 0
frameworks/Zig/zinc/build.zig

@@ -0,0 +1,78 @@
+const std = @import("std");
+
+// Although this function looks imperative, note that its job is to
+// declaratively construct a build graph that will be executed by an external
+// runner.
+pub fn build(b: *std.Build) void {
+    // Standard target options allows the person running `zig build` to choose
+    // what target to build for. Here we do not override the defaults, which
+    // means any target is allowed, and the default is native. Other options
+    // for restricting supported target set are available.
+    const target = b.standardTargetOptions(.{});
+
+    // Standard optimization options allow the person running `zig build` to select
+    // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
+    // set a preferred release mode, allowing the user to decide how to optimize.
+    const optimize = b.standardOptimizeOption(.{});
+
+    const exe = b.addExecutable(.{
+        .name = "zinc",
+        .root_source_file = b.path("src/main.zig"),
+        .target = target,
+        .optimize = optimize,
+    });
+
+    const zinc = b.dependency("zinc", .{
+        .target = target,
+        .optimize = optimize,
+    });
+    exe.root_module.addImport("zinc", zinc.module("zinc"));
+
+    const datetime = b.dependency("zig-datetime", .{
+        .target = target,
+        .optimize = optimize,
+    });
+    exe.root_module.addImport("datetime", datetime.module("zig-datetime"));
+
+    // 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);
+
+    const exe_unit_tests = b.addTest(.{
+        .root_source_file = b.path("src/main.zig"),
+        .target = target,
+        .optimize = optimize,
+    });
+
+    const run_exe_unit_tests = b.addRunArtifact(exe_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_exe_unit_tests.step);
+}

+ 27 - 0
frameworks/Zig/zinc/build.zig.zon

@@ -0,0 +1,27 @@
+.{
+    .name = "zinc",
+    .version = "0.1.0",
+    .dependencies = .{
+        .zinc = .{
+            .url = "https://github.com/zon-dev/zinc/archive/refs/tags/0.1.0-beta.5.tar.gz",
+            .hash = "12201444aa36b4a83f262f319e7c17ccdcff9fbde2efbeb5fc94f1a07eda0d99428e",
+        },
+        .@"zig-datetime" = .{
+            .url = "git+https://github.com/frmdstryr/zig-datetime#70aebf28fb3e137cd84123a9349d157a74708721",
+            .hash = "122077215ce36e125a490e59ec1748ffd4f6ba00d4d14f7308978e5360711d72d77f",
+        },
+        .pg = .{
+            .url = "git+https://github.com/karlseguin/pg.zig#21db2306aff657802f9cb10a1e7f8fe9c33e7990",
+            .hash = "1220df8995ceea78a4a37a505fc779ded75725d0606c33fded26103953524dde1619",
+        },
+        .mustache = .{
+            .url = "git+https://github.com/batiati/mustache-zig#ac358646ab9e6123285b90c947ecd40f7966d531",
+            .hash = "1220cd6e1b49bdd0a568682957dab9a6864554755908f7de990ec7c050f58cf41da2",
+        },
+    },
+    .paths = .{
+        "build.zig",
+        "build.zig.zon",
+        "src",
+    },
+}

+ 3 - 0
frameworks/Zig/zinc/run.sh

@@ -0,0 +1,3 @@
+echo "Waiting for Zinc framework to start..."
+
+zinc

+ 43 - 0
frameworks/Zig/zinc/src/main.zig

@@ -0,0 +1,43 @@
+const std = @import("std");
+const zinc = @import("zinc");
+const Datetime = @import("datetime").datetime.Datetime;
+
+pub fn main() !void {
+    var gpa = std.heap.GeneralPurposeAllocator(.{ .thread_safe = true }){};
+    defer _ = gpa.deinit();
+    const allocator = gpa.allocator();
+
+    var z = try zinc.init(.{
+        .port = 3000,
+        .allocator = allocator,
+        .num_threads = 16 * @as(u8, @intCast(std.Thread.getCpuCount() catch 1)),
+    });
+    defer z.deinit();
+
+    var router = z.getRouter();
+    try router.use(&.{setupHeader});
+    try router.get("/json", json);
+    try router.get("/plaintext", plaintext);
+
+    try z.run();
+}
+
+fn plaintext(ctx: *zinc.Context) anyerror!void {
+    try ctx.setHeader("Content-Type", "text/plain; charset=utf-8");
+    try ctx.setBody("Hello, world!");
+}
+
+fn json(ctx: *zinc.Context) anyerror!void {
+    try ctx.json(.{ .message = "Hello, World!" }, .{});
+}
+
+fn setupHeader(ctx: *zinc.Context) anyerror!void {
+    try ctx.setHeader("Server", "Zinc");
+
+    const now = Datetime.now();
+    const now_str = try now.formatHttp(ctx.allocator);
+    // defer ctx.allocator.free(now_str);
+
+    // The time is now: Fri, 20 Dec 2019 22:03:02 UTC
+    try ctx.setHeader("date", now_str);
+}

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

@@ -0,0 +1,21 @@
+FROM fedora:40 AS build
+
+WORKDIR /zinc
+
+COPY src src
+COPY run.sh run.sh
+
+COPY build.zig.zon build.zig.zon
+COPY build.zig build.zig
+
+RUN dnf install -y zig
+RUN zig version
+RUN zig build -Doptimize=ReleaseFast
+RUN cp /zinc/zig-out/bin/zinc /usr/local/bin
+
+EXPOSE 3000
+ARG BENCHMARK_ENV
+ARG TFB_TEST_DATABASE
+ARG TFB_TEST_NAME
+
+CMD ["sh", "run.sh"]