Compare commits
No commits in common. "abc26837a08a8459791c56fe46136ee21efd19fa" and "8b8463cd6abfbc617f7b3f0c85241649fb51baf9" have entirely different histories.
abc26837a0
...
8b8463cd6a
38
README.md
38
README.md
|
@ -26,33 +26,13 @@ library can be found in src/main-lib.zig.
|
||||||
Architecture
|
Architecture
|
||||||
------------
|
------------
|
||||||
|
|
||||||
This library assumes the use of Linux as a host. While the primary engine is not
|
TODO:
|
||||||
tied to Linux, the file watcher module uses inotify and friends and will not
|
|
||||||
work outside that OS. PRs are welcome.
|
|
||||||
|
|
||||||
The system is built with a pre-release version of zig, currently zig version
|
We assume Linux.
|
||||||
[0.11.0-dev.3312+ab37ab33c](https://github.com/marler8997/zig-unofficial-releases#0110-dev3312ab37ab33c-summary).
|
|
||||||
This version has web server in the standard library, so it is useful.
|
|
||||||
|
|
||||||
To achieve the lowest latency possible, this server loads dynamic libraries
|
Built with zig 0.11.0-dev.3312+ab37ab33c (provide permalink). Explain lock to 0.11 when released.
|
||||||
using [dlopen(3)](https://linux.die.net/man/3/dlopen) based on a configuration
|
|
||||||
file in the current working directory called `proxy.ini`. An example of the
|
|
||||||
configuration is in this directory, and it is relatively simple string prefix
|
|
||||||
matching, again, for speed.
|
|
||||||
|
|
||||||
On startup, a thread pool will be created. Request paths and header matching
|
To achieve the lowest latency possible and eliminate the proliferation, The architecture of this server is setup
|
||||||
is loaded from the configuration file, and file watches are initiated on all
|
|
||||||
libraries mentioned in the configuration file. Libraries are loaded on demand
|
|
||||||
when a request arrives that needs the library. When a library changes for a new
|
|
||||||
version, the file watcher will take note and unload the previous version.
|
|
||||||
|
|
||||||
Changes to the configuration file are not watched, relying instead on a HUP
|
|
||||||
signal to force a reload. At that point, all libraries ("executors") are
|
|
||||||
unloaded, and configuration is re-read.
|
|
||||||
|
|
||||||
As libraries are loaded directly into main process space, bugs in the libraries
|
|
||||||
can and will crash the engine. As such, some supervisory process (dockerd,
|
|
||||||
systemd, etc) should monitor and restart if necessary.
|
|
||||||
|
|
||||||
Security
|
Security
|
||||||
--------
|
--------
|
||||||
|
@ -73,13 +53,11 @@ reported by the system (although thread count is limited to 4 threads when
|
||||||
compiled in debug mode). This can be controlled with the environment variable
|
compiled in debug mode). This can be controlled with the environment variable
|
||||||
`SERVER_THREAD_COUNT`.
|
`SERVER_THREAD_COUNT`.
|
||||||
|
|
||||||
The port by default is 8069, although this can be set with the `PORT`
|
Future plans include an environment variable for IP address and port to listen
|
||||||
environment variable. Future plans include an environment variable for IP
|
on, as well as the amount of pre-allocated memory for response data (currently
|
||||||
address as well as the amount of pre-allocated memory for response data (currently
|
hardcoded to 1k/thread). Pre-allocated memory reduces the number of system
|
||||||
hardcoded to 8k/thread). Pre-allocated memory reduces the number of system
|
|
||||||
calls required for memory allocation, and pre-allocation/allocation statistics
|
calls required for memory allocation, and pre-allocation/allocation statistics
|
||||||
per request are reported in the logs. The current pre-allocation provides
|
per request are reported in the logs.
|
||||||
approximately 4k per request without requiring system calls.
|
|
||||||
|
|
||||||
Logs
|
Logs
|
||||||
----
|
----
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub fn build(b: *std.Build) void {
|
||||||
const optimize = b.standardOptimizeOption(.{});
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
const exe = b.addExecutable(.{
|
const exe = b.addExecutable(.{
|
||||||
.name = "flexilib",
|
.name = "faas-proxy",
|
||||||
// In this case the main source file is merely a path, however, in more
|
// In this case the main source file is merely a path, however, in more
|
||||||
// complicated build scripts, this could be a generated file.
|
// complicated build scripts, this could be a generated file.
|
||||||
.root_source_file = .{ .path = "src/main.zig" },
|
.root_source_file = .{ .path = "src/main.zig" },
|
||||||
|
@ -27,7 +27,7 @@ pub fn build(b: *std.Build) void {
|
||||||
exe.linkLibC();
|
exe.linkLibC();
|
||||||
|
|
||||||
const lib = b.addSharedLibrary(.{
|
const lib = b.addSharedLibrary(.{
|
||||||
.name = "flexilib-sample-lib",
|
.name = "faas-proxy-sample-lib",
|
||||||
// In this case the main source file is merely a path, however, in more
|
// In this case the main source file is merely a path, however, in more
|
||||||
// complicated build scripts, this could be a generated file.
|
// complicated build scripts, this could be a generated file.
|
||||||
.root_source_file = .{ .path = "src/main-lib.zig" },
|
.root_source_file = .{ .path = "src/main-lib.zig" },
|
||||||
|
@ -37,7 +37,7 @@ pub fn build(b: *std.Build) void {
|
||||||
lib.linkLibC();
|
lib.linkLibC();
|
||||||
|
|
||||||
const interface_lib = b.addStaticLibrary(.{
|
const interface_lib = b.addStaticLibrary(.{
|
||||||
.name = "flexilib",
|
.name = "libfaasproxy",
|
||||||
// In this case the main source file is merely a path, however, in more
|
// In this case the main source file is merely a path, however, in more
|
||||||
// complicated build scripts, this could be a generated file.
|
// complicated build scripts, this could be a generated file.
|
||||||
.root_source_file = .{ .path = "src/interface.zig" },
|
.root_source_file = .{ .path = "src/interface.zig" },
|
||||||
|
|
|
@ -6,6 +6,6 @@
|
||||||
|
|
||||||
# Example of match based on an HTTP header. The key is space-delimited:
|
# Example of match based on an HTTP header. The key is space-delimited:
|
||||||
# <http header key>: <header match prefix> <path match prefix>
|
# <http header key>: <header match prefix> <path match prefix>
|
||||||
Host: iam / = zig-out/lib/libflexilib-sample-lib.so
|
Host: iam / = zig-out/lib/libfaas-proxy-sample-lib.so
|
||||||
/c = zig-out/lib/libflexilib-in-c.so
|
/c = zig-out/lib/libfaas-proxy-sample-lib-in-c.so
|
||||||
/ = zig-out/lib/libflexilib-sample-lib.so
|
/ = zig-out/lib/libfaas-proxy-sample-lib.so
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub const Request = extern struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
// If the library is Zig, we can use these helpers
|
// If the library is Zig, we can use these helpers
|
||||||
threadlocal var allocator: ?*std.mem.Allocator = null;
|
var allocator: ?*std.mem.Allocator = null;
|
||||||
|
|
||||||
const log = std.log.scoped(.interface);
|
const log = std.log.scoped(.interface);
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ pub fn handleRequest(request: *Request, zigRequestHandler: ZigRequestHandler) ?*
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
log.debug("response ptr: {*}", .{response.items.ptr});
|
||||||
// Marshall data back for handling by server
|
// Marshall data back for handling by server
|
||||||
|
|
||||||
var rc = alloc.create(Response) catch {
|
var rc = alloc.create(Response) catch {
|
||||||
|
|
|
@ -362,10 +362,7 @@ pub fn main() !void {
|
||||||
var server = std.http.Server.init(allocator, .{ .reuse_address = true });
|
var server = std.http.Server.init(allocator, .{ .reuse_address = true });
|
||||||
defer server.deinit();
|
defer server.deinit();
|
||||||
|
|
||||||
const address = try std.net.Address.parseIp(
|
const address = try std.net.Address.parseIp("0.0.0.0", PORT);
|
||||||
"0.0.0.0",
|
|
||||||
if (std.os.getenv("PORT")) |p| try std.fmt.parseInt(u16, p, 10) else PORT,
|
|
||||||
);
|
|
||||||
try server.listen(address);
|
try server.listen(address);
|
||||||
const server_port = server.socket.listen_address.in.getPort();
|
const server_port = server.socket.listen_address.in.getPort();
|
||||||
log.info("listening on port: {d}", .{server_port});
|
log.info("listening on port: {d}", .{server_port});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user