2023-09-16 15:14:11 +00:00
|
|
|
const std = @import("std");
|
|
|
|
const build_options = @import("build_options");
|
2023-10-04 13:55:25 +00:00
|
|
|
const flexilib = @import("flexilib-interface");
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
const interface = @import("universal_lambda_interface");
|
2023-09-16 15:14:11 +00:00
|
|
|
|
|
|
|
const log = std.log.scoped(.universal_lambda);
|
|
|
|
|
2023-09-16 17:33:29 +00:00
|
|
|
const runFn = blk: {
|
|
|
|
switch (build_options.build_type) {
|
2023-09-18 15:27:45 +00:00
|
|
|
.awslambda => break :blk @import("lambda.zig").run,
|
2023-09-16 17:33:29 +00:00
|
|
|
.standalone_server => break :blk runStandaloneServer,
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
.flexilib => break :blk @import("flexilib.zig").run,
|
|
|
|
.exe_run, .cloudflare => break :blk @import("console.zig").run,
|
2023-09-16 17:33:29 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-09-16 15:14:11 +00:00
|
|
|
/// Starts the universal lambda framework. Handler will be called when an event is processing.
|
|
|
|
/// Depending on the serverless system used, from a practical sense, this may not return.
|
|
|
|
///
|
|
|
|
/// If an allocator is not provided, an approrpriate allocator will be selected and used
|
|
|
|
/// This function is intended to loop infinitely. If not used in this manner,
|
|
|
|
/// make sure to call the deinit() function
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
pub fn run(allocator: ?std.mem.Allocator, event_handler: interface.HandlerFn) !u8 { // TODO: remove inferred error set?
|
2023-10-23 19:49:18 +00:00
|
|
|
return try runFn(allocator, event_handler);
|
2023-09-16 15:14:11 +00:00
|
|
|
}
|
|
|
|
|
2023-09-16 17:33:29 +00:00
|
|
|
/// Will create a web server and marshall all requests back to our event handler
|
|
|
|
/// To keep things simple, we'll have this on a single thread, at least for now
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
fn runStandaloneServer(allocator: ?std.mem.Allocator, event_handler: interface.HandlerFn) !u8 {
|
2023-09-16 17:33:29 +00:00
|
|
|
const alloc = allocator orelse std.heap.page_allocator;
|
|
|
|
|
|
|
|
var arena = std.heap.ArenaAllocator.init(alloc);
|
|
|
|
defer arena.deinit();
|
|
|
|
|
|
|
|
var aa = arena.allocator();
|
|
|
|
var server = std.http.Server.init(aa, .{ .reuse_address = true });
|
|
|
|
defer server.deinit();
|
|
|
|
const address = try std.net.Address.parseIp("127.0.0.1", 8080); // TODO: allow config
|
|
|
|
try server.listen(address);
|
|
|
|
const server_port = server.socket.listen_address.in.getPort();
|
|
|
|
var uri: ["http://127.0.0.1:99999".len]u8 = undefined;
|
|
|
|
_ = try std.fmt.bufPrint(&uri, "http://127.0.0.1:{d}", .{server_port});
|
|
|
|
log.info("server listening at {s}", .{uri});
|
|
|
|
|
|
|
|
// No threads, maybe later
|
|
|
|
//log.info("starting server thread, tid {d}", .{std.Thread.getCurrentId()});
|
|
|
|
while (true) {
|
|
|
|
defer {
|
|
|
|
if (!arena.reset(.{ .retain_with_limit = 1024 * 1024 })) {
|
|
|
|
// reallocation failed, arena is degraded
|
|
|
|
log.warn("Arena reset failed and is degraded. Resetting arena", .{});
|
|
|
|
arena.deinit();
|
|
|
|
arena = std.heap.ArenaAllocator.init(alloc);
|
|
|
|
aa = arena.allocator();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
processRequest(aa, &server, event_handler) catch |e| {
|
|
|
|
log.err("Unexpected error processing request: {any}", .{e});
|
|
|
|
if (@errorReturnTrace()) |trace| {
|
|
|
|
std.debug.dumpStackTrace(trace.*);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2023-10-23 19:49:18 +00:00
|
|
|
return 0;
|
2023-09-16 17:33:29 +00:00
|
|
|
}
|
|
|
|
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
fn processRequest(aa: std.mem.Allocator, server: *std.http.Server, event_handler: interface.HandlerFn) !void {
|
2023-09-16 17:33:29 +00:00
|
|
|
var res = try server.accept(.{ .allocator = aa });
|
|
|
|
defer {
|
|
|
|
_ = res.reset();
|
|
|
|
if (res.headers.owned and res.headers.list.items.len > 0) res.headers.deinit();
|
|
|
|
res.deinit();
|
|
|
|
}
|
|
|
|
try res.wait(); // wait for client to send a complete request head
|
|
|
|
|
|
|
|
const errstr = "Internal Server Error\n";
|
|
|
|
var errbuf: [errstr.len]u8 = undefined;
|
|
|
|
@memcpy(&errbuf, errstr);
|
|
|
|
var response_bytes: []const u8 = errbuf[0..];
|
|
|
|
|
|
|
|
var body =
|
|
|
|
if (res.request.content_length) |l|
|
|
|
|
try res.reader().readAllAlloc(aa, @as(usize, l))
|
|
|
|
else
|
|
|
|
try aa.dupe(u8, "");
|
|
|
|
// no need to free - will be handled by arena
|
|
|
|
|
2023-10-03 20:52:47 +00:00
|
|
|
response_bytes = event_handler(aa, body, .{ .web_request = &res }) catch |e| brk: {
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
if (res.status.class() == .success) res.status = .internal_server_error;
|
2023-09-16 17:33:29 +00:00
|
|
|
// TODO: more about this particular request
|
|
|
|
log.err("Unexpected error from executor processing request: {any}", .{e});
|
|
|
|
if (@errorReturnTrace()) |trace| {
|
|
|
|
std.debug.dumpStackTrace(trace.*);
|
|
|
|
}
|
|
|
|
break :brk "Unexpected error generating request to lambda";
|
|
|
|
};
|
|
|
|
res.transfer_encoding = .{ .content_length = response_bytes.len };
|
|
|
|
|
|
|
|
try res.do();
|
|
|
|
_ = try res.writer().writeAll(response_bytes);
|
|
|
|
try res.finish();
|
|
|
|
}
|
2023-09-20 21:20:39 +00:00
|
|
|
test {
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
std.testing.refAllDecls(@This());
|
2023-10-06 19:09:49 +00:00
|
|
|
// if (builtin.os.tag == .wasi) return error.SkipZigTest;
|
2023-10-21 05:04:41 +00:00
|
|
|
if (@import("builtin").os.tag != .wasi) {
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
// these use http
|
|
|
|
std.testing.refAllDecls(@import("lambda.zig"));
|
2023-10-21 05:04:41 +00:00
|
|
|
std.testing.refAllDecls(@import("cloudflaredeploy.zig"));
|
|
|
|
std.testing.refAllDecls(@import("CloudflareDeployStep.zig"));
|
|
|
|
}
|
rework context
This commit is a significant refactor that fixes a number of things.
1. Replaces the optional helpers import (which was always weird) with a
mandatory interface import on behalf of the application. This is
actually a good thing as it enables all things below.
2. Removes the severely awkward union that was the lambda context. Now,
no matter how your handler runs, a single object with everything you
need is fully populated and (nearly always) works as you would
expect. There is a slight exception to this with AWS Lambda that is
related to the service itself. It is also possible that not
everything is passed in correctly for Cloudflare, which, if true,
will be addressed later.
3. Allows writes to the context object. These will be added to the
output, but is implementation dependent, and I'm not 100% sure I've
got it right yet, but the infrastructure is there.
4. Allows proper tests throughout this project.
5. Allows proper tests in the application too.
6. Removes the need for the handler to be public under flexlib. Flexilib
handler registration now works just like everything else. Note,
however, that flexilib is unique in that your handler registration
function will return before the program ends. If this is important
for resource cleanup, @import("build_options").build_type is your
friend.
7. Request method can now be passed into console applications using -m
or --method
2023-10-25 06:45:08 +00:00
|
|
|
std.testing.refAllDecls(@import("console.zig"));
|
|
|
|
std.testing.refAllDecls(@import("flexilib.zig"));
|
|
|
|
|
|
|
|
// The following do not currently have tests
|
|
|
|
|
|
|
|
// TODO: Do we want build files here too?
|
2023-09-20 21:20:39 +00:00
|
|
|
}
|