Quellcode durchsuchen

Zap upgraded to 0.8 (#9254)

* Zap upgraded to 0.8

* Zap 0.8 fixes
Dragos Varovici vor 1 Jahr
Ursprung
Commit
ba69235094

+ 21 - 21
frameworks/Zig/zap/build.zig

@@ -1,9 +1,12 @@
 const std = @import("std");
+const ModuleMap = std.StringArrayHashMap(*std.Build.Module);
+var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+const allocator = gpa.allocator();
 
 // 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 {
+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
@@ -15,41 +18,38 @@ pub fn build(b: *std.Build) void {
     // set a preferred release mode, allowing the user to decide how to optimize.
     const optimize = b.standardOptimizeOption(.{});
 
+    const dep_opts = .{ .target = target, .optimize = optimize };
+
     const exe = b.addExecutable(.{
         .name = "zap",
         // 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 = "src/main.zig" },
+        .root_source_file = b.path("src/main.zig"),
         .target = target,
         .optimize = optimize,
     });
 
-    //exe.addPackagePath("random", "src/random.zig");
-
     const zap = b.dependency("zap", .{
         .target = target,
         .optimize = optimize,
         .openssl = false, // set to true to enable TLS support
     });
-    exe.addModule("zap", zap.module("zap"));
 
-    const pg = b.dependency("pg", .{
-        .target = target,
-        .optimize = optimize,
-    });
-    exe.addModule("pg", pg.module("pg"));
+    var modules = ModuleMap.init(allocator);
+    defer modules.deinit();
 
-    const dig = b.dependency("dig", .{
-    .target = target,
-    .optimize = optimize,
-    });
-    exe.addModule("dns", dig.module("dns"));
+    const zap_module = b.dependency("zap", dep_opts).module("zap");
+    const pg_module = b.dependency("pg", dep_opts).module("pg");
+    const dig_module = b.dependency("dig", dep_opts).module("dns");
+
+    try modules.put("zap", zap_module);
+    try modules.put("pg", pg_module);
+    try modules.put("dig", dig_module);
 
-    // const mustache = b.dependency("mustache", .{
-    //     .target = target,
-    //     .optimize = optimize,
-    // });
-    // exe.addModule("mustache", mustache.module("mustache"));
+    //     // Expose this as a module that others can import
+    exe.root_module.addImport("zap", zap_module);
+    exe.root_module.addImport("pg", pg_module);
+    exe.root_module.addImport("dig", dig_module);
 
     exe.linkLibrary(zap.artifact("facil.io"));
 
@@ -84,7 +84,7 @@ pub fn build(b: *std.Build) void {
     // 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" },
+        .root_source_file = b.path("src/main.zig"),
         .target = target,
         .optimize = optimize,
     });

+ 13 - 21
frameworks/Zig/zap/build.zig.zon

@@ -1,21 +1,13 @@
-.{
-    .name = "Zap testing",
-    .version = "0.1.0",
-
-    .dependencies = .{
-        // zap v0.5.1
-        .zap = .{
-            .url = "https://github.com/zigzap/zap/archive/refs/tags/v0.5.1.tar.gz",
-            .hash = "1220d4802fb09d4e99c0e7265f90d6f3cfdc3e5e31c1b05f0924ee2dd26d9d6dbbf4",
-        },
-        .pg = .{
-            .url = "https://github.com/karlseguin/pg.zig/archive/f3f4a0b3b9996bfb1bf9bd0bdd0d73b36e915a86.tar.gz",
-            .hash = "1220337202642ee66408a35f254549f22cf3a096c6fa6c28e6f87a0161d5a6c0f4ab"
-        },
-        .dig = .{
-            .url = "https://github.com/lun-4/zigdig/archive/2ec407ec3c7f347e747717977958e9ba339eb82f.tar.gz",
-            .hash = "1220dfdb3089dfe9a4e4bc1226fcff08d91d0c0853f287d98d8b81270da251790331"
-        },
-
-    }
-}
+.{ .name = "Zap testing", .version = "0.1.1", .paths = .{
+    "build.zig",
+    "build.zig.zon",
+    "src",
+}, .dependencies = .{
+    .zap = .{
+        .url = "https://github.com/zigzap/zap/archive/refs/tags/v0.8.0.tar.gz",
+        .hash = "12209936c3333b53b53edcf453b1670babb9ae8c2197b1ca627c01e72670e20c1a21",
+    },
+    .pg = .{ .url = "https://github.com/karlseguin/pg.zig/archive/239a4468163a49d8c0d03285632eabe96003e9e2.tar.gz", 
+        .hash = "1220a1d7e51e2fa45e547c76a9e099c09d06e14b0b9bfc6baa89367f56f1ded399a0" },
+    .dig = .{ .url = "https://github.com/lun-4/zigdig/archive/a54c85c26aa83c64ee81e3ee1818890be5cbed0b.tar.gz", .hash = "1220f078ab62d1328339504f9122dc4d241be30ada451628d78b8a3bf5bb9be1dcba" },
+} }

+ 1 - 1
frameworks/Zig/zap/run.sh

@@ -1,3 +1,3 @@
-echo "Waiting for ZAP to start..."
+echo "Waiting for ZAP framework to start..."
 
 zap

+ 16 - 17
frameworks/Zig/zap/src/endpoints.zig

@@ -64,27 +64,27 @@ pub const FortunesEndpoint = struct {
         defer conn.release();
 
         var rows = try conn.query("SELECT id, message FROM Fortune", .{});
-        rows.deinit();
+        defer rows.deinit();
 
         var fortunes = std.ArrayList(Fortune).init(middleware.SharedAllocator.getAllocator());
         defer fortunes.deinit();
 
         while (try rows.next()) |row| {
-            var fortune = Fortune{ .id = row.get(i32, 0), .message = row.get([]const u8, 1) };
-            _ = try fortunes.append(fortune);
+            const fortune = Fortune{ .id = row.get(i32, 0), .message = row.get([]const u8, 1) };
+            try fortunes.append(fortune);
         }
 
-        var fortune = Fortune{ .id = 0, .message = "Additional fortune added at request time." };
-        _ = try fortunes.append(fortune);
+        const fortune = Fortune{ .id = 0, .message = "Additional fortune added at request time." };
+        try fortunes.append(fortune);
 
-        var fortunes_slice = try fortunes.toOwnedSlice();
+        const fortunes_slice = try fortunes.toOwnedSlice();
         std.mem.sort(Fortune, fortunes_slice, {}, cmpFortuneByMessage);
 
         return fortunes_slice;
     }
 
     fn getFortunesHtml(self: *Self, pool: *pg.Pool) ![]const u8 {
-        var fortunes = try getFortunes(pool);
+        const fortunes = try getFortunes(pool);
 
         self.mutex.lock();
         const ret = self.mustache.build(.{ .fortunes = fortunes });
@@ -95,7 +95,7 @@ pub const FortunesEndpoint = struct {
 
         // std.debug.print("mustache output {s}\n", .{raw});
 
-        var html = try deescapeHtml(raw);
+        const html = try deescapeHtml(raw);
 
         // std.debug.print("html output {s}\n", .{html});
 
@@ -103,7 +103,7 @@ pub const FortunesEndpoint = struct {
     }
 
     pub fn get(ep: *zap.Endpoint, req: zap.Request) void {
-        const self = @fieldParentPtr(Self, "ep", ep);
+        const self: *FortunesEndpoint = @fieldParentPtr("ep", ep);
 
         if (!checkPath(ep, req)) return;
 
@@ -118,7 +118,7 @@ pub const FortunesEndpoint = struct {
             }
         }
 
-        var fortunes_html = getFortunesHtml(self, pool) catch return;
+        const fortunes_html = getFortunesHtml(self, pool) catch return;
 
         req.sendBody(fortunes_html) catch return;
 
@@ -146,7 +146,7 @@ pub const DbEndpoint = struct {
     }
 
     pub fn get(ep: *zap.Endpoint, req: zap.Request) void {
-        const self = @fieldParentPtr(Self, "ep", ep);
+        const self: *DbEndpoint = @fieldParentPtr("ep", ep);
 
         if (!checkPath(ep, req)) return;
 
@@ -177,14 +177,13 @@ pub const DbEndpoint = struct {
         var conn = pool.acquire() catch return;
         defer conn.release();
 
-        var row_result = conn.row("SELECT id, randomNumber FROM World WHERE id = $1", .{random_number}) catch |err| {
+        const row_result = conn.row("SELECT id, randomNumber FROM World WHERE id = $1", .{random_number}) catch |err| {
             std.debug.print("Error querying database: {}\n", .{err});
             return;
         };
         var row = row_result.?;
-        defer row.deinit();
 
-        var world = World{ .id = row.get(i32, 0), .randomNumber = row.get(i32, 1) };
+        const world = World{ .id = row.get(i32, 0), .randomNumber = row.get(i32, 1) };
 
         var buf: [100]u8 = undefined;
         var json_to_send: []const u8 = undefined;
@@ -218,7 +217,7 @@ pub const PlaintextEndpoint = struct {
     }
 
     pub fn get(ep: *zap.Endpoint, req: zap.Request) void {
-        const self = @fieldParentPtr(Self, "ep", ep);
+        const self: *PlaintextEndpoint = @fieldParentPtr("ep", ep);
         _ = self;
 
         if (!checkPath(ep, req)) return;
@@ -248,14 +247,14 @@ pub const JsonEndpoint = struct {
     }
 
     pub fn get(ep: *zap.Endpoint, req: zap.Request) void {
-        const self = @fieldParentPtr(Self, "ep", ep);
+        const self: *JsonEndpoint  = @fieldParentPtr("ep", ep);
         _ = self;
 
         if (!checkPath(ep, req)) return;
 
         req.setContentType(.JSON) catch return;
 
-        var message = Message{ .message = "Hello, World!" };
+        const message = Message{ .message = "Hello, World!" };
 
         var buf: [100]u8 = undefined;
         var json_to_send: []const u8 = undefined;

+ 3 - 8
frameworks/Zig/zap/src/main.zig

@@ -21,16 +21,12 @@ pub fn main() !void {
         .child_allocator = gpa.allocator(),
     };
 
-    var allocator = tsa.allocator();
+    const allocator = tsa.allocator();
 
     var pg_pool = try pool.initPool(allocator);
     defer pg_pool.deinit();
 
-    var rnd = std.rand.DefaultPrng.init(blk: {
-        var seed: u64 = undefined;
-        try std.os.getrandom(std.mem.asBytes(&seed));
-        break :blk seed;
-    });
+    var prng = std.rand.DefaultPrng.init(@as(u64, @bitCast(std.time.milliTimestamp())));
 
     middleware.SharedAllocator.init(allocator);
 
@@ -66,7 +62,7 @@ pub fn main() !void {
     );
 
     var headerHandler = middleware.HeaderMiddleWare.init(dbEndpointHandler.getHandler());
-    var prngHandler = middleware.PrngMiddleWare.init(headerHandler.getHandler(), &rnd);
+    var prngHandler = middleware.RandomMiddleWare.init(headerHandler.getHandler(), &prng);
     var pgHandler = middleware.PgMiddleWare.init(prngHandler.getHandler(), pg_pool);
 
     var listener = try zap.Middleware.Listener(middleware.Context).init(
@@ -92,4 +88,3 @@ pub fn main() !void {
         .workers = 1,
     });
 }
-

+ 5 - 5
frameworks/Zig/zap/src/middleware.zig

@@ -22,7 +22,7 @@ pub const SharedAllocator = struct {
 
 // create a combined context struct
 pub const Context = struct {
-    prng: ?PrngMiddleWare.Prng = null,
+    prng: ?RandomMiddleWare.Prng = null,
     pg: ?PgMiddleWare.Pg = null,
 };
 
@@ -47,7 +47,7 @@ pub const HeaderMiddleWare = struct {
     // note that the first parameter is of type *Handler, not *Self !!!
     pub fn onRequest(handler: *Handler, req: zap.Request, context: *Context) bool {
         // this is how we would get our self pointer
-        var self = @fieldParentPtr(Self, "handler", handler);
+        const self: *Self = @fieldParentPtr("handler", handler);
         _ = self;
 
         req.setHeader("Server", "Zap") catch return false;
@@ -57,7 +57,7 @@ pub const HeaderMiddleWare = struct {
     }
 };
 
-pub const PrngMiddleWare = struct {
+pub const RandomMiddleWare = struct {
     handler: Handler,
     rnd: *std.rand.DefaultPrng,
 
@@ -83,7 +83,7 @@ pub const PrngMiddleWare = struct {
     pub fn onRequest(handler: *Handler, req: zap.Request, context: *Context) bool {
 
         // this is how we would get our self pointer
-        var self = @fieldParentPtr(Self, "handler", handler);
+        const self: *RandomMiddleWare = @fieldParentPtr("handler", handler);
 
         context.prng = Prng{ .rnd = self.rnd };
 
@@ -118,7 +118,7 @@ pub const PgMiddleWare = struct {
     pub fn onRequest(handler: *Handler, req: zap.Request, context: *Context) bool {
 
         // this is how we would get our self pointer
-        var self = @fieldParentPtr(Self, "handler", handler);
+        const self: *Self = @fieldParentPtr("handler", handler);
 
         // do our work: fill in the user field of the context
         context.pg = Pg{ .pool = self.pool };

+ 44 - 33
frameworks/Zig/zap/src/pool.zig

@@ -1,7 +1,7 @@
 const std = @import("std");
-const pg = @import("pg");
 const regex = @import("regex");
-const dns = @import("dns");
+const dns = @import("dig");
+const pg = @import("pg");
 
 const Allocator = std.mem.Allocator;
 const Pool = pg.Pool;
@@ -9,31 +9,22 @@ const ArrayList = std.ArrayList;
 const Regex = regex.Regex;
 
 pub fn initPool(allocator: Allocator) !*pg.Pool {
-    const info = try parsePostgresConnStr();
-    std.debug.print("Cconnection info: {s}:{s}@{s}:{d}/{s}\n", .{ info.username, info.password, info.hostname, info.port, info.database });
-
-    const hostname = std.os.getenv("PG_HOST") orelse "localhost";
-    var addresses = try dns.helpers.getAddressList(hostname, allocator);
-    defer addresses.deinit();
-
-    var hostAddress = std.net.Address.parseIp("127.0.0.1", 0) catch unreachable;
-
-    for (addresses.addrs) |address| {
-        hostAddress = address;
-    }
-
-    std.debug.print("tfb hostname {}\n", .{hostAddress.in});
-
-    const host = try addressAsString(hostAddress);
-
-    var pg_pool = try Pool.init(allocator, .{ .size = 28, .connect = .{
-        .port = info.port,
-        .host = host,
-    }, .auth = .{
-        .username = info.username,
-        .database = info.database,
-        .password = info.password,
-    }, .timeout = 10_000,});
+    const info = try parsePostgresConnStr(allocator);
+    std.debug.print("Connection: {s}:{s}@{s}:{d}/{s}\n", .{ info.username, info.password, info.hostname, info.port, info.database });
+
+    const pg_pool = try Pool.init(allocator, .{
+        .size = 28,
+        .connect = .{
+            .port = info.port,
+            .host = info.hostname,
+        },
+        .auth = .{
+            .username = info.username,
+            .database = info.database,
+            .password = info.password,
+        },
+        .timeout = 10_000,
+    });
 
     return pg_pool;
 }
@@ -67,12 +58,32 @@ fn addressAsString(address: std.net.Address) ![]const u8 {
     return output;
 }
 
-fn parsePostgresConnStr() !ConnectionInfo {
+fn parsePostgresConnStr(allocator: Allocator) !ConnectionInfo {
+    const pg_port = try getEnvVar(allocator, "PG_PORT", "5432");
+    std.debug.print("tfb port {s}\n", .{pg_port});
+    var port = try std.fmt.parseInt(u16, pg_port, 0);
+
+    if (port == 0) {
+        port = 5432;
+    }
+
     return ConnectionInfo{
-        .username = std.os.getenv("PG_USER") orelse "benchmarkdbuser",
-        .password = std.os.getenv("PG_PASS") orelse "benchmarkdbpass",
-        .hostname = std.os.getenv("PG_HOST") orelse "localhost", // ,
-        .port = try std.fmt.parseInt(u16, std.os.getenv("PG_PORT") orelse "5432", 0),
-        .database = std.os.getenv("PG_DB") orelse "hello_world",
+        .username = try getEnvVar(allocator, "PG_USER", "benchmarkdbuser"),
+        .password = try getEnvVar(allocator, "PG_PASS", "benchmarkdbpass"),
+        .hostname = try getEnvVar(allocator, "PG_HOST", "localhost"),
+        .port = port,
+        .database = try getEnvVar(allocator, "PG_DB", "hello_world"),
     };
 }
+
+fn getEnvVar(allocator: Allocator, name: []const u8, default: []const u8) ![]const u8 {
+    const env_var = std.process.getEnvVarOwned(allocator, name) catch |err| switch (err) {
+        error.EnvironmentVariableNotFound => return default,
+        error.OutOfMemory => return err,
+        error.InvalidWtf8 => return err,
+    };
+
+    if (env_var.len == 0) return default;
+
+    return env_var;
+}

+ 25 - 21
frameworks/Zig/zap/zap.dockerfile

@@ -1,42 +1,46 @@
-#FROM ziglang/static-base:llvm15-aarch64-3 as build
-FROM buddyspencer/ziglang:0.11.0-r3 as build
+FROM fedora:40 AS build
 
 WORKDIR /zap
 
+ENV PG_USER=benchmarkdbuser
+ENV PG_PASS=benchmarkdbpass
+ENV PG_DB=hello_world
+ENV PG_HOST=tfb-database
+ENV PG_PORT=5432
+
 COPY src src
+COPY run.sh run.sh
 
 COPY build.zig.zon build.zig.zon
 COPY build.zig build.zig
 
-RUN apk update
-RUN apk add yaml-dev sqlite-dev
-RUN apk add bind-tools
-RUN apk add --no-cache bash
-RUN dig +short localhost | head -n 1
-RUN zig build -Doptimize=ReleaseFast --prefix-exe-dir /usr/bin
+RUN dnf install -y zig
 RUN zig version
-RUN ls
+# RUN zig build -Doptimize=ReleaseFast 
+RUN zig build
+RUN cp /zap/zig-out/bin/zap /usr/local/bin
 
 EXPOSE 3000
 
 CMD ["sh", "run.sh"]
 
-FROM alpine:3.19
+# FROM alpine:3.19
 
-WORKDIR /zap
+# WORKDIR /zap
 
-ENV PG_USER=benchmarkdbuser
-ENV PG_PASS=benchmarkdbpass
-ENV PG_DB=hello_world
-ENV PG_HOST=tfb-database
-ENV PG_PORT=5432
+# ENV PG_USER=benchmarkdbuser
+# ENV PG_PASS=benchmarkdbpass
+# ENV PG_DB=hello_world
+# ENV PG_HOST=tfb-database
+# ENV PG_PORT=5432
 
-COPY run.sh run.sh
+# RUN apk update
+# RUN apk add libc6-compat
 
-RUN apk update
+# COPY run.sh run.sh
 
-COPY --from=build /usr/bin/zap /usr/bin/zap
+# COPY --from=build /zap/zig-out/bin/zap /usr/local/bin
 
-EXPOSE 3000
+# EXPOSE 3000
 
-CMD ["sh", "run.sh"]
+# CMD ["sh", "run.sh"]