Mercurial
view seobeo/README.md @ 269:de291f396881
install initial production config
Copy the ignored repository config into /etc/mrjunejune on first deployment while preserving existing production configuration on later deploys.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 07 Aug 2026 13:08:10 -0700 |
| parents | 609d3c6aff4e |
| children |
line wrap: on
line source
# seobeo HTTP client and networking library for C. ## Features - HTTP/HTTPS client - SSL/TLS support - Async networking with libuv - Joinable/detached tasks and bounded worker pools - Server-Sent Events routes and event framing - Snapshot testing utilities ## Files | File | Description | |------|-------------| | `seobeo.h` | Public API header | | `seobeo_internal.h` | Internal declarations | | `s_http_client.c` | HTTP client implementation | | `s_network.c` | Network utilities | | `s_sse.c` | Server-Sent Events framing and stream lifecycle | | `s_ssl.c` | SSL/TLS handling | | `s_logging.c` | Logging utilities | | `s_worker.c` | Thread and worker-pool implementation | | `seobeo_worker.h` | Public worker API | | `snapshot_creator.c/h` | Snapshot testing | | `docs/` | Documentation | | `examples/` | Usage examples | | `tests/` | Unit tests | | `os/` | OS-specific code | ## Usage ```c #include "seobeo/seobeo.h" // Make HTTP request HttpResponse* resp = http_get("https://example.com"); // handle response... http_response_free(resp); ``` ## Building ```bash bazel build //seobeo:seobeo bazel test //seobeo:seobeo_test ``` ## Background workers Use a detached task for simple fire-and-forget work: ```c void Convert_Image(void *p_context) { Conversion *p_conversion = p_context; Run_FFmpeg(p_conversion); } Seobeo_Worker_Result result = Seobeo_Thread_Start_Detached( Convert_Image, p_conversion, free); if (result != SEOBEO_WORKER_OK) free(p_conversion); ``` Use a bounded pool when requests can enqueue expensive work: ```c Seobeo_Worker_Pool *p_pool = Seobeo_Worker_Pool_Create(2, 16); Seobeo_Worker_Result result = Seobeo_Worker_Pool_Submit( p_pool, Convert_Image, p_conversion, free); Seobeo_Worker_Pool_Shutdown(p_pool, TRUE); Seobeo_Worker_Pool_Destroy(p_pool); ``` Submitting transfers context ownership only when it returns `SEOBEO_WORKER_OK`. Cleanup runs after successful work and for queued tasks discarded by a non-draining shutdown. User callbacks never run while the pool mutex is held. ## Server-Sent Events Register an SSE route separately from ordinary response and stream handlers: ```c static void Build_Events( Seobeo_SSE_Stream *p_stream, Seobeo_Request_Entry *p_request, Dowa_Arena *p_arena) { (void)p_request; (void)p_arena; Seobeo_SSE_Event event = { .event = "build", .id = "42", .data = "started\ncompiling", .retry_ms = 2000, }; Seobeo_SSE_Send(p_stream, &event); Seobeo_SSE_Send_Comment(p_stream, "heartbeat"); } Seobeo_Router_Register_SSE("/events/builds", Build_Events); ``` SSE handlers run once when a client connects and must return promptly so edge workers remain available. Call `Seobeo_SSE_Retain` before storing a stream for later work and pair it with `Seobeo_SSE_Release`; use `Seobeo_SSE_Is_Open` before sending. Do not retain the request map or arena after the handler returns. A return value of `1` means the record was retained behind socket backpressure and `Seobeo_SSE_Flush` should be retried later. `SEOBEO_SSE_BACKPRESSURE` means the bounded pending queue is full and the new record was not accepted. Events are bounded by the handle write-buffer capacity so one record is queued atomically; larger records return `SEOBEO_SSE_EVENT_TOO_LARGE`. ## Dependencies - libuv (via //third_party/libuv) - OpenSSL