Skip to content

Commit

Permalink
Per-request database connection
Browse files Browse the repository at this point in the history
Use JetQuery's new `Repo.bindConnect()` to get a new Repo bound to a
connection for each request. This significantly simplifies connection
management and offloads all the connection pool
management/reconnecting/etc. to pg.zig where it belongs.

Improve development mode SQL syntax highlighting - highlight `SELECT`,
`UPDATE`, `DELETE`, `INSERT` in different bolded colors for clarity.
  • Loading branch information
bobf committed Nov 30, 2024
1 parent ac60032 commit 9cf6705
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 26 deletions.
8 changes: 4 additions & 4 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
.hash = "12201d75d73aad5e1c996de4d5ae87a00e58479c8d469bc2eeb5fdeeac8857bc09af",
},
.jetquery = .{
.url = "https://github.com/jetzig-framework/jetquery/archive/f520d4bb3f7099f8d670926328c93efd8849c3cc.tar.gz",
.hash = "1220021eb5c36e78c1aafbf04a303433deb9fcb7edf29d8686b3bb33881884f2d23b",
.url = "https://github.com/jetzig-framework/jetquery/archive/52e1cf900c94f3c103727ade6ba2dab3057c8663.tar.gz",
.hash = "12208a37407d1a7548fd7e81d9f6a9d4897793918023ed559a279a7647dab2d43145",
},
.jetcommon = .{
.url = "https://github.com/jetzig-framework/jetcommon/archive/86f24cfdf2aaa0e8ada4539a6edef882708ced2b.tar.gz",
Expand All @@ -27,8 +27,8 @@
.hash = "1220411a8c46d95bbf3b6e2059854bcb3c5159d428814099df5294232b9980517e9c",
},
.pg = .{
.url = "https://github.com/karlseguin/pg.zig/archive/f376f4b30c63f1fdf90bc3afe246d3bc4175cd46.tar.gz",
.hash = "12200a55304988e942015b6244570b2dc0e87e5764719c9e7d5c812cd7ad34f6b138",
.url = "https://github.com/karlseguin/pg.zig/archive/0bfc46029c6a3e8ded7a3e0544fcbcb5baba2208.tar.gz",
.hash = "1220fb3f43073a6f9f201764c3ae78aa87b29edbc7b021c1174b29b020967d0b146c",
},
.smtp_client = .{
.url = "https://github.com/karlseguin/smtp_client.zig/archive/3cbe8f269e4c3a6bce407e7ae48b2c76307c559f.tar.gz",
Expand Down
4 changes: 2 additions & 2 deletions cli/build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
.hash = "1220411a8c46d95bbf3b6e2059854bcb3c5159d428814099df5294232b9980517e9c",
},
.jetquery = .{
.url = "https://github.com/jetzig-framework/jetquery/archive/f520d4bb3f7099f8d670926328c93efd8849c3cc.tar.gz",
.hash = "1220021eb5c36e78c1aafbf04a303433deb9fcb7edf29d8686b3bb33881884f2d23b",
.url = "https://github.com/jetzig-framework/jetquery/archive/52e1cf900c94f3c103727ade6ba2dab3057c8663.tar.gz",
.hash = "12208a37407d1a7548fd7e81d9f6a9d4897793918023ed559a279a7647dab2d43145",
},
},
.paths = .{
Expand Down
6 changes: 4 additions & 2 deletions src/commands/routes.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ pub fn main() !void {
.get => jetzig.colors.cyan("{s: <7}"),
.index => jetzig.colors.blue("{s: <7}"),
.new => jetzig.colors.green("{s: <7}"),
.edit => jetzig.colors.bold(.yellow, "{s: <7}"),
.post => jetzig.colors.yellow("{s: <7}"),
.put => jetzig.colors.magenta("{s: <7}"),
.patch => jetzig.colors.bright_magenta("{s: <7}"),
.patch => jetzig.colors.bold(.magenta, "{s: <7}"),
.delete => jetzig.colors.red("{s: <7}"),
.custom => unreachable,
};
Expand All @@ -36,6 +37,7 @@ pub fn main() !void {
route.uri_path ++ switch (route.action) {
.index, .post => "",
.new => "/new",
.edit => "/:id/edit",
.get, .put, .patch, .delete => "/:id",
.custom => "",
},
Expand All @@ -54,7 +56,7 @@ pub fn main() !void {

for (jetzig_app.custom_routes.items) |route| {
log(
" " ++ jetzig.colors.bold(jetzig.colors.white("{s: <7}")) ++ " " ++ padded_path ++ " {s}:{s}",
" " ++ jetzig.colors.bold(.white, "{s: <7}") ++ " " ++ padded_path ++ " {s}:{s}",
.{ route.name, route.uri_path, route.view_name, route.name },
);
}
Expand Down
37 changes: 23 additions & 14 deletions src/jetzig/colors.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ const builtin = @import("builtin");
const types = @import("types.zig");
const jetzig = @import("../jetzig.zig");

pub const Color = enum {
black,
red,
green,
yellow,
blue,
magenta,
cyan,
white,
bright_black,
bright_red,
bright_green,
bright_yellow,
bright_blue,
bright_magenta,
bright_cyan,
bright_white,
};

// Must be consistent with `std.io.tty.Color` for Windows compatibility.
pub const codes = .{
.escape = "\x1b[",
Expand Down Expand Up @@ -53,12 +72,7 @@ const ansi_colors = .{
.{ "2", .dim },
.{ "0", .reset },
};
pub const codes_map = if (@hasDecl(std, "ComptimeStringMap"))
std.ComptimeStringMap(std.io.tty.Color, ansi_colors)
else if (@hasDecl(std, "StaticStringMap"))
std.StaticStringMap(std.io.tty.Color).initComptime(ansi_colors)
else
unreachable;
pub const codes_map = std.StaticStringMap(std.io.tty.Color).initComptime(ansi_colors);

// Map basic ANSI color codes to Windows TextAttribute colors
// used by std.os.windows.SetConsoleTextAttribute()
Expand All @@ -83,12 +97,7 @@ const windows_colors = .{
.{ "2", 7 },
.{ "0", 7 },
};
pub const windows_map = if (@hasDecl(std, "ComptimeStringMap"))
std.ComptimeStringMap(u16, windows_colors)
else if (@hasDecl(std, "StaticStringMap"))
std.StaticStringMap(u16).initComptime(windows_colors)
else
unreachable;
pub const windows_map = std.StaticStringMap(u16).initComptime(windows_colors);

/// Colorize a log message. Note that we force `.escape_codes` when we are a TTY even on Windows.
/// `jetzig.loggers.LogQueue` parses the ANSI codes and uses `std.io.tty.Config.setColor` to
Expand Down Expand Up @@ -122,8 +131,8 @@ fn runtimeWrap(allocator: std.mem.Allocator, attribute: []const u8, message: []c
);
}

pub fn bold(comptime message: []const u8) []const u8 {
return codes.escape ++ codes.bold ++ message ++ codes.escape ++ codes.reset;
pub fn bold(comptime color: Color, comptime message: []const u8) []const u8 {
return codes.escape ++ @field(codes, @tagName(color)) ++ codes.escape ++ codes.bold ++ message ++ codes.escape ++ codes.reset;
}

pub fn black(comptime message: []const u8) []const u8 {
Expand Down
13 changes: 11 additions & 2 deletions src/jetzig/http/Server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ cache: *jetzig.kv.Store,
repo: *jetzig.database.Repo,
global: *anyopaque,
decoded_static_route_params: []*jetzig.data.Value = &.{},
debug_mutex: std.Thread.Mutex = .{},

const Server = @This();

Expand Down Expand Up @@ -92,6 +93,7 @@ pub fn listen(self: *Server) !void {
},
.request = .{
.max_multiform_count = jetzig.config.get(usize, "max_multipart_form_fields"),
.max_body_size = jetzig.config.get(usize, "max_bytes_request_body"),
},
},
Dispatcher{ .server = self },
Expand All @@ -116,7 +118,11 @@ pub fn errorHandlerFn(self: *Server, request: *httpz.Request, response: *httpz.R

self.logger.ERROR("Encountered error: {s} {s}", .{ @errorName(err), request.url.raw }) catch {};
const stack = @errorReturnTrace();
if (stack) |capture| self.logStackTrace(capture, request.arena) catch {};
if (stack) |capture| {
self.debug_mutex.lock();
defer self.debug_mutex.unlock();
self.logStackTrace(capture, request.arena) catch {};
}

response.body = "500 Internal Server Error";
}
Expand All @@ -128,6 +134,9 @@ pub fn processNextRequest(
) !void {
const start_time = std.time.nanoTimestamp();

var repo = try self.repo.bindConnect(.{ .allocator = httpz_response.arena });
defer repo.release();

var response = try jetzig.http.Response.init(httpz_response.arena, httpz_response);
var request = try jetzig.http.Request.init(
httpz_response.arena,
Expand All @@ -136,7 +145,7 @@ pub fn processNextRequest(
httpz_request,
httpz_response,
&response,
self.repo,
&repo,
);

try request.process();
Expand Down
18 changes: 16 additions & 2 deletions src/jetzig/loggers/DevelopmentLogger.zig
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,16 @@ const sql_tokens = .{
"VALUES",
};

const sql_statement_map = std.StaticStringMap(jetzig.colors.Color).initComptime(.{
.{ "SELECT", .blue },
.{ "DELETE", .red },
.{ "UPDATE", .yellow },
.{ "INSERT", .green },
});

fn printSql(self: *const DevelopmentLogger, sql: []const u8) !void {
const string_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.green;
const identifier_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.yellow;
const identifier_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.white;
const reset_color = jetzig.colors.codes.escape ++ jetzig.colors.codes.reset;
var buf: [4096]u8 = undefined;
var stream = std.io.fixedBufferStream(&buf);
Expand Down Expand Up @@ -221,9 +228,16 @@ fn printSql(self: *const DevelopmentLogger, sql: []const u8) !void {
try writer.print("{c}", .{sql[index]});
index += 1;
} else {
@setEvalBranchQuota(2000);
inline for (sql_tokens) |token| {
if (std.mem.startsWith(u8, sql[index..], token)) {
try writer.print(jetzig.colors.cyan(token), .{});
const formatted_token = if (sql_statement_map.get(token)) |color|
switch (color) {
inline else => |tag| jetzig.colors.bold(tag, token),
}
else
jetzig.colors.cyan(token);
try writer.print("{s}", .{formatted_token});
index += token.len;
break;
}
Expand Down

0 comments on commit 9cf6705

Please sign in to comment.