mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-15 06:26:07 +00:00
WIP
This commit is contained in:
parent
2fbd2f2f6a
commit
2a955de4b3
@ -20,11 +20,11 @@ const jetzig = @import("jetzig");
|
|||||||
/// can also be modified.
|
/// can also be modified.
|
||||||
my_custom_value: []const u8,
|
my_custom_value: []const u8,
|
||||||
|
|
||||||
const Self = @This();
|
const DemoMiddleware = @This();
|
||||||
|
|
||||||
/// Initialize middleware.
|
/// Initialize middleware.
|
||||||
pub fn init(request: *jetzig.http.Request) !*Self {
|
pub fn init(request: *jetzig.http.Request) !*DemoMiddleware {
|
||||||
var middleware = try request.allocator.create(Self);
|
var middleware = try request.allocator.create(DemoMiddleware);
|
||||||
middleware.my_custom_value = "initial value";
|
middleware.my_custom_value = "initial value";
|
||||||
return middleware;
|
return middleware;
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ pub fn init(request: *jetzig.http.Request) !*Self {
|
|||||||
/// Invoked immediately after the request is received but before it has started processing.
|
/// Invoked immediately after the request is received but before it has started processing.
|
||||||
/// Any calls to `request.render` or `request.redirect` will prevent further processing of the
|
/// Any calls to `request.render` or `request.redirect` will prevent further processing of the
|
||||||
/// request, including any other middleware in the chain.
|
/// request, including any other middleware in the chain.
|
||||||
pub fn afterRequest(self: *Self, request: *jetzig.http.Request) !void {
|
pub fn afterRequest(self: *DemoMiddleware, request: *jetzig.http.Request) !void {
|
||||||
try request.server.logger.DEBUG(
|
try request.server.logger.DEBUG(
|
||||||
"[DemoMiddleware:afterRequest] my_custom_value: {s}",
|
"[DemoMiddleware:afterRequest] my_custom_value: {s}",
|
||||||
.{self.my_custom_value},
|
.{self.my_custom_value},
|
||||||
@ -42,7 +42,11 @@ pub fn afterRequest(self: *Self, request: *jetzig.http.Request) !void {
|
|||||||
|
|
||||||
/// Invoked immediately before the response renders to the client.
|
/// Invoked immediately before the response renders to the client.
|
||||||
/// The response can be modified here if needed.
|
/// The response can be modified here if needed.
|
||||||
pub fn beforeResponse(self: *Self, request: *jetzig.http.Request, response: *jetzig.http.Response) !void {
|
pub fn beforeResponse(
|
||||||
|
self: *DemoMiddleware,
|
||||||
|
request: *jetzig.http.Request,
|
||||||
|
response: *jetzig.http.Response,
|
||||||
|
) !void {
|
||||||
try request.server.logger.DEBUG(
|
try request.server.logger.DEBUG(
|
||||||
"[DemoMiddleware:beforeResponse] my_custom_value: {s}, response status: {s}",
|
"[DemoMiddleware:beforeResponse] my_custom_value: {s}, response status: {s}",
|
||||||
.{ self.my_custom_value, @tagName(response.status_code) },
|
.{ self.my_custom_value, @tagName(response.status_code) },
|
||||||
@ -51,7 +55,11 @@ pub fn beforeResponse(self: *Self, request: *jetzig.http.Request, response: *jet
|
|||||||
|
|
||||||
/// Invoked immediately after the response has been finalized and sent to the client.
|
/// Invoked immediately after the response has been finalized and sent to the client.
|
||||||
/// Response data can be accessed for logging, but any modifications will have no impact.
|
/// Response data can be accessed for logging, but any modifications will have no impact.
|
||||||
pub fn afterResponse(self: *Self, request: *jetzig.http.Request, response: *jetzig.http.Response) !void {
|
pub fn afterResponse(
|
||||||
|
self: *DemoMiddleware,
|
||||||
|
request: *jetzig.http.Request,
|
||||||
|
response: *jetzig.http.Response,
|
||||||
|
) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
_ = response;
|
_ = response;
|
||||||
try request.server.logger.DEBUG("[DemoMiddleware:afterResponse] response completed", .{});
|
try request.server.logger.DEBUG("[DemoMiddleware:afterResponse] response completed", .{});
|
||||||
@ -60,6 +68,6 @@ pub fn afterResponse(self: *Self, request: *jetzig.http.Request, response: *jetz
|
|||||||
/// Invoked after `afterResponse` is called. Use this function to do any clean-up.
|
/// Invoked after `afterResponse` is called. Use this function to do any clean-up.
|
||||||
/// Note that `request.allocator` is an arena allocator, so any allocations are automatically
|
/// Note that `request.allocator` is an arena allocator, so any allocations are automatically
|
||||||
/// freed before the next request starts processing.
|
/// freed before the next request starts processing.
|
||||||
pub fn deinit(self: *Self, request: *jetzig.http.Request) void {
|
pub fn deinit(self: *DemoMiddleware, request: *jetzig.http.Request) void {
|
||||||
request.allocator.destroy(self);
|
request.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,12 @@ pub const jetzig_options = struct {
|
|||||||
// performance. Log messages should aim to fit in the message buffer.
|
// performance. Log messages should aim to fit in the message buffer.
|
||||||
// pub const log_message_buffer_len: usize = 4096;
|
// pub const log_message_buffer_len: usize = 4096;
|
||||||
|
|
||||||
|
// Maximum log pool size. When a log buffer is no longer required it is returned to a pool
|
||||||
|
// for recycling. When logging i/o is slow, a high volume of requests will result in this
|
||||||
|
// pool growing. When the pool size reaches the maximum value defined here, log events are
|
||||||
|
// freed instead of recycled.
|
||||||
|
// pub const max_log_pool_len: usize = 256;
|
||||||
|
|
||||||
// Path relative to cwd() to serve public content from. Symlinks are not followed.
|
// Path relative to cwd() to serve public content from. Symlinks are not followed.
|
||||||
// pub const public_content_path = "public";
|
// pub const public_content_path = "public";
|
||||||
|
|
||||||
|
@ -88,6 +88,12 @@ pub const config = struct {
|
|||||||
/// performance. Log messages should aim to fit in the message buffer.
|
/// performance. Log messages should aim to fit in the message buffer.
|
||||||
pub const log_message_buffer_len: usize = 4096;
|
pub const log_message_buffer_len: usize = 4096;
|
||||||
|
|
||||||
|
/// Maximum log pool size. When a log buffer is no longer required it is returned to a pool
|
||||||
|
/// for recycling. When logging i/o is slow, a high volume of requests will result in this
|
||||||
|
/// pool growing. When the pool size reaches the maximum value defined here, log events are
|
||||||
|
/// freed instead of recycled.
|
||||||
|
pub const max_log_pool_len: usize = 256;
|
||||||
|
|
||||||
/// Path relative to cwd() to serve public content from. Symlinks are not followed.
|
/// Path relative to cwd() to serve public content from. Symlinks are not followed.
|
||||||
pub const public_content_path = "public";
|
pub const public_content_path = "public";
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ const builtin = @import("builtin");
|
|||||||
const jetzig = @import("../../jetzig.zig");
|
const jetzig = @import("../../jetzig.zig");
|
||||||
|
|
||||||
const buffer_size = jetzig.config.get(usize, "log_message_buffer_len");
|
const buffer_size = jetzig.config.get(usize, "log_message_buffer_len");
|
||||||
|
const max_pool_len = jetzig.config.get(usize, "max_log_pool_len");
|
||||||
|
|
||||||
const List = std.DoublyLinkedList(Event);
|
const List = std.DoublyLinkedList(Event);
|
||||||
const Buffer = [buffer_size]u8;
|
const Buffer = [buffer_size]u8;
|
||||||
@ -41,8 +42,8 @@ const Event = struct {
|
|||||||
pub fn init(allocator: std.mem.Allocator) LogQueue {
|
pub fn init(allocator: std.mem.Allocator) LogQueue {
|
||||||
return .{
|
return .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.node_allocator = std.heap.MemoryPool(List.Node).init(allocator),
|
.node_allocator = initPool(allocator, List.Node),
|
||||||
.buffer_allocator = std.heap.MemoryPool(Buffer).init(allocator),
|
.buffer_allocator = initPool(allocator, Buffer),
|
||||||
.list = List{},
|
.list = List{},
|
||||||
.condition = std.Thread.Condition{},
|
.condition = std.Thread.Condition{},
|
||||||
.condition_mutex = std.Thread.Mutex{},
|
.condition_mutex = std.Thread.Mutex{},
|
||||||
@ -58,11 +59,6 @@ pub fn deinit(self: *LogQueue) void {
|
|||||||
self.node_pool.deinit();
|
self.node_pool.deinit();
|
||||||
self.buffer_pool.deinit();
|
self.buffer_pool.deinit();
|
||||||
|
|
||||||
while (self.list.popFirst()) |node| {
|
|
||||||
if (node.data.ptr) |ptr| self.allocator.free(ptr);
|
|
||||||
self.allocator.destroy(node.data.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.buffer_allocator.deinit();
|
self.buffer_allocator.deinit();
|
||||||
self.node_allocator.deinit();
|
self.node_allocator.deinit();
|
||||||
|
|
||||||
@ -211,7 +207,12 @@ pub const Reader = struct {
|
|||||||
if (self.queue.writer.position < self.queue.buffer_pool.items.len) {
|
if (self.queue.writer.position < self.queue.buffer_pool.items.len) {
|
||||||
self.queue.buffer_pool.items[self.queue.writer.position] = event.message;
|
self.queue.buffer_pool.items[self.queue.writer.position] = event.message;
|
||||||
} else {
|
} else {
|
||||||
try self.queue.buffer_pool.append(event.message); // TODO: Prevent unlimited inflation
|
if (self.queue.buffer_pool.items.len >= max_pool_len) {
|
||||||
|
self.queue.buffer_allocator.destroy(@alignCast(event.message));
|
||||||
|
self.queue.writer.position += 1;
|
||||||
|
} else {
|
||||||
|
try self.queue.buffer_pool.append(event.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +254,12 @@ fn popFirst(self: *LogQueue) !?Event {
|
|||||||
if (self.position < self.node_pool.items.len) {
|
if (self.position < self.node_pool.items.len) {
|
||||||
self.node_pool.items[self.position] = node;
|
self.node_pool.items[self.position] = node;
|
||||||
} else {
|
} else {
|
||||||
try self.node_pool.append(node); // TODO: Set a maximum here to avoid never-ending inflation.
|
if (self.node_pool.items.len >= max_pool_len) {
|
||||||
|
self.node_allocator.destroy(node);
|
||||||
|
self.position += 1;
|
||||||
|
} else {
|
||||||
|
try self.node_pool.append(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
} else {
|
} else {
|
||||||
@ -261,6 +267,10 @@ fn popFirst(self: *LogQueue) !?Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initPool(allocator: std.mem.Allocator, T: type) std.heap.MemoryPool(T) {
|
||||||
|
return std.heap.MemoryPool(T).initPreheated(allocator, max_pool_len) catch @panic("OOM");
|
||||||
|
}
|
||||||
|
|
||||||
fn writeWindows(file: std.fs.File, writer: anytype, event: Event) !void {
|
fn writeWindows(file: std.fs.File, writer: anytype, event: Event) !void {
|
||||||
var info: std.os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
|
var info: std.os.windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
|
||||||
const config: std.io.tty.Config = if (std.os.windows.kernel32.GetConsoleScreenBufferInfo(
|
const config: std.io.tty.Config = if (std.os.windows.kernel32.GetConsoleScreenBufferInfo(
|
||||||
|
@ -15,7 +15,7 @@ pub fn init(request: *jetzig.http.Request) !*Self {
|
|||||||
/// content rendered directly by the view function.
|
/// content rendered directly by the view function.
|
||||||
pub fn afterRequest(self: *Self, request: *jetzig.http.Request) !void {
|
pub fn afterRequest(self: *Self, request: *jetzig.http.Request) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
if (request.getHeader("HX-Target")) |target| {
|
if (request.headers.get("HX-Target")) |target| {
|
||||||
try request.server.logger.DEBUG(
|
try request.server.logger.DEBUG(
|
||||||
"[middleware-htmx] htmx request detected, disabling layout. (#{s})",
|
"[middleware-htmx] htmx request detected, disabling layout. (#{s})",
|
||||||
.{target},
|
.{target},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user