瀏覽代碼

improvement (#9407)

Kayden 8 月之前
父節點
當前提交
7b79969fd5

+ 2 - 2
frameworks/Zig/httpz/.gitignore

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

+ 0 - 25
frameworks/Zig/httpz/build.zig

@@ -1,48 +1,23 @@
 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 {
-    // 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 nots
-    // 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 = "httpz",
-        // 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 = b.path("src/main.zig"),
         .target = target,
         .optimize = optimize,
     });
 
-    var modules = ModuleMap.init(allocator);
-    defer modules.deinit();
-
     const httpz_module = b.dependency("httpz", dep_opts).module("httpz");
     const pg_module = b.dependency("pg", dep_opts).module("pg");
     const datetimez_module = b.dependency("datetimez", dep_opts).module("zig-datetime");
     const mustache_module = b.dependency("mustache", dep_opts).module("mustache");
 
-    try modules.put("httpz", httpz_module);
-    try modules.put("pg", pg_module);
-    try modules.put("datetimez", datetimez_module);
-    try modules.put("mustache", mustache_module);
-
-    //     // Expose this as a module that others can import
     exe.root_module.addImport("httpz", httpz_module);
     exe.root_module.addImport("pg", pg_module);
     exe.root_module.addImport("datetimez", datetimez_module);

+ 14 - 23
frameworks/Zig/httpz/src/endpoints.zig

@@ -4,7 +4,6 @@ const pg = @import("pg");
 const datetimez = @import("datetimez");
 const mustache = @import("mustache");
 
-const Allocator = std.mem.Allocator;
 const Thread = std.Thread;
 const Mutex = Thread.Mutex;
 const template = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>{{#fortunes}}<tr><td>{{id}}</td><td>{{message}}</td></tr>{{/fortunes}}</table></body></html>";
@@ -12,14 +11,9 @@ const template = "<!DOCTYPE html><html><head><title>Fortunes</title></head><body
 pub const Global = struct {
     pool: *pg.Pool,
     prng: *std.rand.DefaultPrng,
-    allocator: Allocator,
     mutex: std.Thread.Mutex = .{},
 };
 
-const Message = struct {
-    message: []const u8,
-};
-
 const World = struct {
     id: i32,
     randomNumber: i32,
@@ -30,23 +24,21 @@ const Fortune = struct {
     message: []const u8,
 };
 
-pub fn plaintext(global: *Global, _: *httpz.Request, res: *httpz.Response) !void {
-    try setHeaders(global.allocator, res);
+pub fn plaintext(_: *Global, _: *httpz.Request, res: *httpz.Response) !void {
+    try setHeaders(res.arena, res);
 
     res.content_type = .TEXT;
     res.body = "Hello, World!";
 }
 
-pub fn json(global: *Global, _: *httpz.Request, res: *httpz.Response) !void {
-    try setHeaders(global.allocator, res);
+pub fn json(_: *Global, _: *httpz.Request, res: *httpz.Response) !void {
+    try setHeaders(res.arena, res);
 
-    const message = Message{ .message = "Hello, World!" };
-
-    try res.json(message, .{});
+    try res.json(.{ .message = "Hello, World!" }, .{});
 }
 
 pub fn db(global: *Global, _: *httpz.Request, res: *httpz.Response) !void {
-    try setHeaders(global.allocator, res);
+    try setHeaders(res.arena, res);
 
     global.mutex.lock();
     const random_number = 1 + (global.prng.random().uintAtMost(u32, 9999));
@@ -61,15 +53,15 @@ pub fn db(global: *Global, _: *httpz.Request, res: *httpz.Response) !void {
 }
 
 pub fn fortune(global: *Global, _: *httpz.Request, res: *httpz.Response) !void {
-    try setHeaders(global.allocator, res);
+    try setHeaders(res.arena, res);
 
-    const fortunes_html = try getFortunesHtml(global.allocator, global.pool);
+    const fortunes_html = try getFortunesHtml(res.arena, global.pool);
 
     res.header("content-type", "text/html; charset=utf-8");
     res.body = fortunes_html;
 }
 
-fn getWorld(pool: *pg.Pool, random_number: u32) !World{
+fn getWorld(pool: *pg.Pool, random_number: u32) !World {
     var conn = try pool.acquire();
     defer conn.release();
 
@@ -81,7 +73,7 @@ fn getWorld(pool: *pg.Pool, random_number: u32) !World{
     return World{ .id = row.get(i32, 0), .randomNumber = row.get(i32, 1) };
 }
 
-fn setHeaders(allocator: Allocator, res: *httpz.Response) !void {
+fn setHeaders(allocator: std.mem.Allocator, res: *httpz.Response) !void {
     res.header("Server", "Httpz");
 
     const now = datetimez.datetime.Date.now();
@@ -97,10 +89,10 @@ fn setHeaders(allocator: Allocator, res: *httpz.Response) !void {
     res.header("Date", now_str);
 }
 
-fn getFortunesHtml(allocator: Allocator, pool: *pg.Pool) ![]const u8 {
+fn getFortunesHtml(allocator: std.mem.Allocator, pool: *pg.Pool) ![]const u8 {
     const fortunes = try getFortunes(allocator, pool);
 
-    const raw = try mustache.allocRenderText(allocator, template,.{ .fortunes = fortunes });
+    const raw = try mustache.allocRenderText(allocator, template, .{ .fortunes = fortunes });
 
     // std.debug.print("mustache output {s}\n", .{raw});
 
@@ -111,7 +103,7 @@ fn getFortunesHtml(allocator: Allocator, pool: *pg.Pool) ![]const u8 {
     return html;
 }
 
-fn getFortunes(allocator: Allocator, pool: *pg.Pool) ![]const Fortune {
+fn getFortunes(allocator: std.mem.Allocator, pool: *pg.Pool) ![]const Fortune {
     var conn = try pool.acquire();
     defer conn.release();
 
@@ -139,7 +131,7 @@ fn cmpFortuneByMessage(_: void, a: Fortune, b: Fortune) bool {
     return std.mem.order(u8, a.message, b.message).compare(std.math.CompareOperator.lt);
 }
 
-fn deescapeHtml(allocator: Allocator, input: []const u8) ![]const u8 {
+fn deescapeHtml(allocator: std.mem.Allocator, input: []const u8) ![]const u8 {
     var output = std.ArrayList(u8).init(allocator);
     defer output.deinit();
 
@@ -189,4 +181,3 @@ fn deescapeHtml(allocator: Allocator, input: []const u8) ![]const u8 {
 
     return output.toOwnedSlice();
 }
-

+ 13 - 13
frameworks/Zig/httpz/src/main.zig

@@ -11,9 +11,10 @@ const RndGen = std.rand.DefaultPrng;
 const Allocator = std.mem.Allocator;
 const Pool = pg.Pool;
 
-var server: httpz.ServerCtx(*endpoints.Global,*endpoints.Global) = undefined;
+var server: httpz.ServerCtx(*endpoints.Global, *endpoints.Global) = undefined;
 
 pub fn main() !void {
+    const cpu_count = try std.Thread.getCpuCount();
     var gpa = std.heap.GeneralPurposeAllocator(.{
         .thread_safe = true,
     }){};
@@ -25,15 +26,20 @@ pub fn main() !void {
 
     var prng = std.rand.DefaultPrng.init(@as(u64, @bitCast(std.time.milliTimestamp())));
 
-    var global = endpoints.Global{ .pool = pg_pool, .prng = &prng, .allocator = allocator };
+    var global = endpoints.Global{
+        .pool = pg_pool,
+        .prng = &prng,
+    };
 
-    server = try httpz.ServerApp(*endpoints.Global).init(allocator, .{
-        .port = 3000, .address = "0.0.0.0", }, &global);
+    server = try httpz.ServerApp(*endpoints.Global).init(allocator, .{ .port = 3000, .address = "0.0.0.0", .workers = .{
+        .count = @truncate(cpu_count),
+        .max_conn = 4096,
+    }, .thread_pool = .{ .count = @truncate(cpu_count * 2) } }, &global);
     defer server.deinit();
 
     // now that our server is up, we register our intent to handle SIGINT
     try std.posix.sigaction(std.posix.SIG.INT, &.{
-        .handler = .{.handler = shutdown},
+        .handler = .{ .handler = shutdown },
         .mask = std.posix.empty_sigset,
         .flags = 0,
     }, null);
@@ -50,22 +56,16 @@ pub fn main() !void {
 }
 
 fn shutdown(_: c_int) callconv(.C) void {
-    // this will unblock the server.listen()
     server.stop();
 }
 
 fn notFound(_: *httpz.Request, res: *httpz.Response) !void {
     res.status = 404;
-
-    // you can set the body directly to a []u8, but note that the memory
-    // must be valid beyond your handler. Use the res.arena if you need to allocate
-    // memory for the body.
     res.body = "Not Found";
 }
 
-// note that the error handler return `void` and not `!void`
 fn errorHandler(req: *httpz.Request, res: *httpz.Response, err: anyerror) void {
     res.status = 500;
     res.body = "Internal Server Error";
-    std.log.warn("httpz: unhandled exception for request: {s}\nErr: {}", .{req.url.raw, err});
-}
+    std.log.warn("httpz: unhandled exception for request: {s}\nErr: {}", .{ req.url.raw, err });
+}