spawn new thread per connection, add yaml for docs and also add GSI to readme

This commit is contained in:
2026-02-17 14:50:50 -05:00
parent 178b38fe18
commit 6bc1a03347
3 changed files with 926 additions and 8 deletions

View File

@@ -6,6 +6,7 @@ import vmem "core:mem/virtual"
import "core:net"
import "core:strings"
import "core:strconv"
import "core:thread"
// HTTP Method enumeration
HTTP_Method :: enum {
@@ -100,7 +101,6 @@ response_set_body :: proc(resp: ^HTTP_Response, data: []byte) {
}
// Request handler function type
// Takes context pointer, request, and request-scoped allocator
Request_Handler :: #type proc(ctx: rawptr, request: ^HTTP_Request, request_alloc: mem.Allocator) -> HTTP_Response
// Server configuration
@@ -122,6 +122,13 @@ default_server_config :: proc() -> Server_Config {
}
}
// Connection task data - passed to worker threads
Connection_Task_Data :: struct {
server: ^Server,
conn: net.TCP_Socket,
source: net.Endpoint,
}
// Server
Server :: struct {
allocator: mem.Allocator,
@@ -168,9 +175,9 @@ server_start :: proc(server: ^Server) -> bool {
server.socket = socket
server.running = true
fmt.printfln("HTTP server listening on %v", server.endpoint)
fmt.printfln("HTTP server listening on %v (thread-per-connection)", server.endpoint)
// Accept loop
// Accept loop - spawn a thread for each connection
for server.running {
conn, source, accept_err := net.accept_tcp(socket)
if accept_err != nil {
@@ -180,9 +187,24 @@ server_start :: proc(server: ^Server) -> bool {
continue
}
// Handle connection in separate goroutine would go here
// For now, handle synchronously (should spawn thread)
handle_connection(server, conn, source)
// Allocate connection data
conn_data := new(Connection_Task_Data, server.allocator)
conn_data.server = server
conn_data.conn = conn
conn_data.source = source
// Spawn a new thread for this connection
t := thread.create(connection_worker_thread)
if t != nil {
t.init_context = context
t.data = conn_data
thread.start(t)
// Thread will clean itself up when done
} else {
// Failed to create thread, close connection
net.close(conn)
free(conn_data, server.allocator)
}
}
return true
@@ -190,12 +212,24 @@ server_start :: proc(server: ^Server) -> bool {
server_stop :: proc(server: ^Server) {
server.running = false
// Close listening socket
if sock, ok := server.socket.?; ok {
net.close(sock)
server.socket = nil
}
}
// Worker thread procedure
connection_worker_thread :: proc(t: ^thread.Thread) {
defer thread.destroy(t) // Clean up thread when done
conn_data := cast(^Connection_Task_Data)t.data
defer free(conn_data, conn_data.server.allocator)
handle_connection(conn_data.server, conn_data.conn, conn_data.source)
}
// Handle a single connection
handle_connection :: proc(server: ^Server, conn: net.TCP_Socket, source: net.Endpoint) {
defer net.close(conn)
@@ -214,7 +248,7 @@ handle_connection :: proc(server: ^Server, conn: net.TCP_Socket, source: net.End
request_alloc := vmem.arena_allocator(&arena)
// TODO: Double check if we want *all* downstream allocations to use the request arena?
// Set request arena as context allocator for downstream allocations
old := context.allocator
context.allocator = request_alloc
defer context.allocator = old