From 7c265cbff13367447099cc2a34afc0c6a3aabbb8 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 16 Dec 2023 14:52:21 +0900 Subject: [PATCH 1/7] build.zig: declare lambda_module as const Zig 0.12 (0.12.0-dev.1664+8ca4a5240) throws error for var declarations that are never mutated. --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 12b8e7f..cffbd56 100644 --- a/build.zig +++ b/build.zig @@ -17,7 +17,7 @@ pub fn build(b: *std.Build) !void { const optimize = b.standardOptimizeOption(.{}); // create a module to be used internally. - var lambda_module = b.createModule(.{ + const lambda_module = b.createModule(.{ .source_file = .{ .path = "src/lambda.zig" }, }); From ba500245e57ce047941b28bacea5d7f600017d75 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 16 Dec 2023 15:15:48 +0900 Subject: [PATCH 2/7] lambda.zig: fix var declarations as const Zig 0.12 (0.12.0-dev.1664+8ca4a5240) throws error for var declarations that are never mutated. --- src/lambda.zig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lambda.zig b/src/lambda.zig index e130837..a36db92 100644 --- a/src/lambda.zig +++ b/src/lambda.zig @@ -101,7 +101,7 @@ pub fn run(allocator: ?std.mem.Allocator, handler: anytype) !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const alloc = allocator orelse gpa.allocator(); - var env = (try Env.fromOs()).?; + const env = (try Env.fromOs()).?; var runtime = try Runtime.init(alloc, env, .{ .allocator = alloc }); defer runtime.deinit(); var events = try runtime.events(); @@ -227,18 +227,18 @@ const EventIterator = struct { try req.wait(); var hdrs = req.response.headers; log.debug("recieved next event {any}", .{hdrs}); - var request_id = hdrs.getFirstValue("Lambda-Runtime-Aws-Request-Id").?; - var deadline_ms = try std.fmt.parseInt(u64, hdrs.getFirstValue("Lambda-Runtime-Deadline-Ms").?, 10); - var invoked_function_arn = hdrs.getFirstValue("Lambda-Runtime-Invoked-Function-Arn").?; - var trace_id = hdrs.getFirstValue("Lambda-Runtime-Trace-Id").?; + const request_id = hdrs.getFirstValue("Lambda-Runtime-Aws-Request-Id").?; + const deadline_ms = try std.fmt.parseInt(u64, hdrs.getFirstValue("Lambda-Runtime-Deadline-Ms").?, 10); + const invoked_function_arn = hdrs.getFirstValue("Lambda-Runtime-Invoked-Function-Arn").?; + const trace_id = hdrs.getFirstValue("Lambda-Runtime-Trace-Id").?; // _ = hdrs.getFirstValue("Lambda-Runtime-Client-Context"); // _ = hdrs.getFirstValue("Lambda-Runtime-Cognito-Identity"); - var content_length = @as(usize, @intCast(req.response.content_length.?)); + const content_length = @as(usize, @intCast(req.response.content_length.?)); var payload = try std.ArrayList(u8).initCapacity(self.allocator, content_length); defer payload.deinit(); try payload.resize(content_length); // make a copy of the response data that we own - var data = try payload.toOwnedSlice(); + const data = try payload.toOwnedSlice(); errdefer self.allocator.free(data); _ = try req.readAll(data); log.debug("constructing event with data {s} and request id {s}", .{ data, request_id }); From 6a586a089fed1966d1f846cb4d0304577740ad9f Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 23 Dec 2023 20:40:08 +0900 Subject: [PATCH 3/7] Make handler take anytype context Allows using anonymous structs / comptime generated types --- src/lambda.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lambda.zig b/src/lambda.zig index a36db92..be8e2e5 100644 --- a/src/lambda.zig +++ b/src/lambda.zig @@ -42,7 +42,7 @@ pub const Context = struct { /// Currently accepting an allocator, request context, and bytes associated with event and error union with bytes returned in response pub fn Handler( comptime Ctx: type, - comptime handleFn: fn (context: Ctx, std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8, + comptime handleFn: fn (context: anytype, std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8, ) type { return struct { context: Ctx, @@ -69,7 +69,7 @@ pub fn Wrap() type { return .{ .context = self }; } - pub fn handle(self: *Self, allocator: std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8 { + pub fn handle(self: anytype, allocator: std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8 { return self.f(allocator, ctx, event); } }; @@ -387,7 +387,7 @@ test "custom handler" { pub fn handler(self: *Self) EchoHandler { return .{ .context = self }; } - pub fn handle(self: *Self, allocator: std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8 { + pub fn handle(self: anytype, allocator: std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8 { _ = self; _ = allocator; _ = ctx; From 5792d0e50cbd8542a5e09ed54c8dea146b9bc9ef Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 23 Dec 2023 20:40:47 +0900 Subject: [PATCH 4/7] Update http.client usage --- src/lambda.zig | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/src/lambda.zig b/src/lambda.zig index be8e2e5..26e4389 100644 --- a/src/lambda.zig +++ b/src/lambda.zig @@ -217,15 +217,16 @@ const EventIterator = struct { log.debug("requesting next event", .{}); var headers = std.http.Headers.init(self.allocator); defer headers.deinit(); - var req = try self.client.request(.GET, self.next_uri.uri, headers, .{}); + var res = try self.client.fetch(self.allocator, .{ + .location = .{ .uri = self.next_uri.uri }, + .method = .GET, + .headers = headers, + }); defer { log.debug("next request deinit", .{}); - req.deinit(); + res.deinit(); } - try req.start(); - try req.finish(); - try req.wait(); - var hdrs = req.response.headers; + var hdrs = res.headers; log.debug("recieved next event {any}", .{hdrs}); const request_id = hdrs.getFirstValue("Lambda-Runtime-Aws-Request-Id").?; const deadline_ms = try std.fmt.parseInt(u64, hdrs.getFirstValue("Lambda-Runtime-Deadline-Ms").?, 10); @@ -233,14 +234,7 @@ const EventIterator = struct { const trace_id = hdrs.getFirstValue("Lambda-Runtime-Trace-Id").?; // _ = hdrs.getFirstValue("Lambda-Runtime-Client-Context"); // _ = hdrs.getFirstValue("Lambda-Runtime-Cognito-Identity"); - const content_length = @as(usize, @intCast(req.response.content_length.?)); - var payload = try std.ArrayList(u8).initCapacity(self.allocator, content_length); - defer payload.deinit(); - try payload.resize(content_length); - // make a copy of the response data that we own - const data = try payload.toOwnedSlice(); - errdefer self.allocator.free(data); - _ = try req.readAll(data); + const data: []const u8 = if (res.body) |body| try self.allocator.dupe(u8, body) else &.{}; log.debug("constructing event with data {s} and request id {s}", .{ data, request_id }); return .{ .allocator = self.allocator, .data = data, .request_id = try self.allocator.dupe(u8, request_id), .deadline_ms = deadline_ms, .invoked_function_arn = try self.allocator.dupe(u8, invoked_function_arn), .trace_id = try self.allocator.dupe(u8, trace_id), .client = self.client, .uri = self.uri }; } @@ -291,13 +285,13 @@ const Event = struct { // fixme. self.client segfaults on every other success. we really shouldn't need a new client on every response var client = std.http.Client{ .allocator = self.allocator }; defer client.deinit(); - var req = try client.request(.POST, uri, headers, .{}); + var req = try self.client.fetch(self.allocator, .{ + .location = .{ .uri = uri }, + .method = .POST, + .headers = headers, + .payload = .{ .string = body }, + }); defer req.deinit(); - req.transfer_encoding = .{ .content_length = body.len }; - try req.start(); - try req.writeAll(body); - try req.finish(); - try req.wait(); log.debug("response complete", .{}); } @@ -328,13 +322,13 @@ const Event = struct { , .{@errorName(caught)}); defer self.allocator.free(body); log.debug("sending error report", .{}); - var req = try self.client.request(.POST, uri, headers, .{}); + var req = try self.client.fetch(self.allocator, .{ + .location = .{ .uri = uri }, + .method = .POST, + .headers = headers, + .payload = .{ .string = body }, + }); defer req.deinit(); - req.transfer_encoding = .{ .content_length = body.len }; - try req.start(); - try req.writeAll(body); - try req.finish(); - try req.wait(); log.debug("error report complete", .{}); } }; From efe3b9b527de9e94de7d0ff020d759ed99f63222 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 23 Dec 2023 20:46:29 +0900 Subject: [PATCH 5/7] update build.zig.zon --- build.zig.zon | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build.zig.zon b/build.zig.zon index bd43cf7..a046912 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1 +1,9 @@ -.{ .name = "lambda", .version = "0.1.0" } +.{ + .name = "lambda", + .version = "0.1.0", + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + }, +} From d4e1d1693632696be90e30ec60902b0e5d529bc9 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 23 Dec 2023 20:53:02 +0900 Subject: [PATCH 6/7] add cleanupFn to handler --- src/lambda.zig | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/lambda.zig b/src/lambda.zig index 26e4389..1e7c6e3 100644 --- a/src/lambda.zig +++ b/src/lambda.zig @@ -43,12 +43,16 @@ pub const Context = struct { pub fn Handler( comptime Ctx: type, comptime handleFn: fn (context: anytype, std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8, + comptime cleanupFn: fn (context: anytype, std.mem.Allocator, ctx: Context, data: []const u8) anyerror!void, ) type { return struct { context: Ctx, pub fn handle(self: *@This(), allocator: std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8 { return handleFn(self.context, allocator, ctx, event); } + pub fn cleanup(self: *@This(), allocator: std.mem.Allocator, ctx: Context, data: []const u8) anyerror!void { + return cleanupFn(self.context, allocator, ctx, data); + } }; } @@ -64,7 +68,7 @@ pub fn Wrap() type { return struct { f: *const fn (std.mem.Allocator, Context, []const u8) anyerror![]const u8, const Self = @This(); - pub const Wrapped = Handler(*Self, handle); + pub const Wrapped = Handler(*Self, handle, cleanup); pub fn handler(self: *Self) Wrapped { return .{ .context = self }; } @@ -72,6 +76,8 @@ pub fn Wrap() type { pub fn handle(self: anytype, allocator: std.mem.Allocator, ctx: Context, event: []const u8) anyerror![]const u8 { return self.f(allocator, ctx, event); } + + pub fn cleanup(_: anytype, _: std.mem.Allocator, _: Context, _: []const u8) anyerror!void {} }; } @@ -122,6 +128,7 @@ pub fn run(allocator: ?std.mem.Allocator, handler: anytype) !void { log.err("failed to send response {s}", .{@errorName(err)}); continue; }; + try hand.cleanup(runtime.allocator, e.context(), response); } } @@ -377,7 +384,7 @@ test "wrapped handler" { test "custom handler" { const Echo = struct { const Self = @This(); - const EchoHandler = Handler(*Self, handle); + const EchoHandler = Handler(*Self, handle, cleanup); pub fn handler(self: *Self) EchoHandler { return .{ .context = self }; } @@ -387,6 +394,7 @@ test "custom handler" { _ = ctx; return event; } + pub fn cleanup(_: anytype, _: std.mem.Allocator, _: Context, _: []const u8) anyerror!void {} }; const allocator = std.testing.allocator; var custom = Echo{}; From b26b54146e9ca5029e0f488596acd25f3b7c01dd Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 27 Jan 2024 14:42:29 +0900 Subject: [PATCH 7/7] Update to zig 0.12.0-dev.2341+92211135f --- build.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.zig b/build.zig index cffbd56..87f1392 100644 --- a/build.zig +++ b/build.zig @@ -18,7 +18,7 @@ pub fn build(b: *std.Build) !void { // create a module to be used internally. const lambda_module = b.createModule(.{ - .source_file = .{ .path = "src/lambda.zig" }, + .root_source_file = .{ .path = "src/lambda.zig" }, }); // register the module so it can be referenced @@ -66,7 +66,7 @@ pub fn build(b: *std.Build) !void { .optimize = optimize, }); - exe.addModule("lambda", lambda_module); + exe.root_module.addImport("lambda", lambda_module); // install the artifact - depending on the example exe const example_build_step = b.addInstallArtifact(exe, .{});