From 35e09a2472df9f4ab64e087a5dcd4070e691e05c Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Sat, 2 Oct 2021 12:23:19 -0700 Subject: [PATCH] move lambda runtime interface out of main --- src/lambda.zig | 57 +++++++++++++++++++++++++++++++++++++++++ src/main.zig | 69 ++++++++------------------------------------------ 2 files changed, 68 insertions(+), 58 deletions(-) create mode 100644 src/lambda.zig diff --git a/src/lambda.zig b/src/lambda.zig new file mode 100644 index 0000000..48188e7 --- /dev/null +++ b/src/lambda.zig @@ -0,0 +1,57 @@ +const std = @import("std"); +const requestz = @import("requestz"); + +pub fn run(event_handler: fn (*std.mem.Allocator, []const u8) anyerror![]const u8) !void { // TODO: remove inferred error set? + const prefix = "http://"; + const postfix = "/2018-06-01/runtime/invocation"; + const lambda_runtime_uri = std.os.getenv("AWS_LAMBDA_RUNTIME_API"); + + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + defer _ = gpa.deinit(); + const allocator = &gpa.allocator; + + const url = try std.fmt.allocPrint(allocator, "{s}{s}{s}/next", .{ prefix, lambda_runtime_uri, postfix }); + defer allocator.free(url); + + std.log.info("Event Url: {s}", .{url}); + + while (true) { + var req_alloc = std.heap.ArenaAllocator.init(allocator); + defer req_alloc.deinit(); + const req_allocator = &req_alloc.allocator; + var client = try requestz.Client.init(req_allocator); + // defer client.deinit(); + var response = client.get(url, .{}) catch |err| { + // TODO: report error + std.log.err("Get fail: {}", .{err}); + continue; + }; + defer response.deinit(); + + var request_id: ?[]const u8 = null; + for (response.headers.items()) |h| { + if (std.mem.indexOf(u8, h.name.value, "Lambda-Runtime-Aws-Request-Id")) |_| + request_id = h.value; + } + if (request_id == null) { + // TODO: report error + std.log.err("Could not find request id: skipping request", .{}); + continue; + } + const req_id = request_id.?; + + const event_response = event_handler(req_allocator, response.body) catch |err| { + // TODO: report error + std.log.err("Error posting response for request id {s}: {}", .{ req_id, err }); + continue; + }; + const response_url = try std.fmt.allocPrint(req_allocator, "{s}{s}{s}/{s}/response", .{ prefix, lambda_runtime_uri, postfix, req_id }); + // defer req_allocator.free(response_url); + var resp_resp = client.post(response_url, .{ .content = event_response }) catch |err| { + // TODO: report error + std.log.err("Error posting response for request id {s}: {}", .{ req_id, err }); + continue; + }; + defer resp_resp.deinit(); + } +} diff --git a/src/main.zig b/src/main.zig index 82c296c..cb33dc2 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,67 +1,20 @@ const std = @import("std"); -const requestz = @import("requestz"); +const lambda = @import("lambda.zig"); -// zig build -Drelease-safe && strip zig-out/bin/bootstrap && zip -j9 function.zip zig-out/bin/bootstrap && aws lambda update-function-code --function-name zig-test --zip-file fileb://function.zip +// zig package -Drelease-safe does the following: +// +// zig build -Drelease-safe +// strip zig-out/bin/bootstrap # should this be stripped? +// zip -j9 zig-out/bin/function.zip zig-out/bin/bootstrap +// +// zig deploy will also do something like: +// +// aws lambda update-function-code --function-name zig-test --zip-file fileb://function.zip pub fn main() anyerror!void { - try run(handler); + try lambda.run(handler); } fn handler(allocator: *std.mem.Allocator, event_data: []const u8) ![]const u8 { _ = allocator; return event_data; } - -pub fn run(event_handler: fn (*std.mem.Allocator, []const u8) anyerror![]const u8) !void { // TODO: remove inferred error set? - const prefix = "http://"; - const postfix = "/2018-06-01/runtime/invocation"; - const lambda_runtime_uri = std.os.getenv("AWS_LAMBDA_RUNTIME_API"); - - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - defer _ = gpa.deinit(); - const allocator = &gpa.allocator; - - const url = try std.fmt.allocPrint(allocator, "{s}{s}{s}/next", .{ prefix, lambda_runtime_uri, postfix }); - defer allocator.free(url); - - std.log.info("Event Url: {s}", .{url}); - - while (true) { - var req_alloc = std.heap.ArenaAllocator.init(allocator); - defer req_alloc.deinit(); - const req_allocator = &req_alloc.allocator; - var client = try requestz.Client.init(req_allocator); - // defer client.deinit(); - var response = client.get(url, .{}) catch |err| { - // TODO: report error - std.log.err("Get fail: {}", .{err}); - continue; - }; - defer response.deinit(); - - var request_id: ?[]const u8 = null; - for (response.headers.items()) |h| { - if (std.mem.indexOf(u8, h.name.value, "Lambda-Runtime-Aws-Request-Id")) |_| - request_id = h.value; - } - if (request_id == null) { - // TODO: report error - std.log.err("Could not find request id: skipping request", .{}); - continue; - } - const req_id = request_id.?; - - const event_response = event_handler(req_allocator, response.body) catch |err| { - // TODO: report error - std.log.err("Error posting response for request id {s}: {}", .{ req_id, err }); - continue; - }; - const response_url = try std.fmt.allocPrint(req_allocator, "{s}{s}{s}/{s}/response", .{ prefix, lambda_runtime_uri, postfix, req_id }); - // defer req_allocator.free(response_url); - var resp_resp = client.post(response_url, .{ .content = event_response }) catch |err| { - // TODO: report error - std.log.err("Error posting response for request id {s}: {}", .{ req_id, err }); - continue; - }; - defer resp_resp.deinit(); - } -}