2025-12
December 2025 Update Blog Post
Dependencies
The bulk of work for this month has been getting rid of the Memory dependency from the Http library.
This is incredibly important, because allocation is only done by the Memory library!
This means that excluding Containers and the support ContainersReflection all libraries make No allocation whatsoever.
All of them can work inside fixed buffers or inside dynamically allocated memory allocated by the user that has knowledge of the entire application context.
Plus, it finally makes the internal dependencies graph between all libraries look super cool:
Http
Going back to the actual improvements to Http, I am not sure where to start.
Multiple iterations of the API have been done and it's probably not over yet...
The API at the beginning of the month was something like this, with allocating Buffers usage and raw allocations everywhere (so ugly!):
The point has been making sure that a connection should be able to live within a block of memory that is fixed during its initialization.
This is because most of the time, reasonable defaults and safety limits must be set anyway to control how many Kb of headers can be accepted or how many Kb can be dedicated to streaming large files.
One example on initializing the web server with compile time fixed buffers is the following:
As AsyncStreams have been fully integrated, it's now possible to send even very large file using some tiny fixed buffers.
If they're too tiny, the transfer is going to become very slow, as a lot of syscall will be needed to fully transmit the file, so it's always as good idea sizing the buffers accordingly.
If one wants to decide the size of these buffers at runtime, the API will become slightly more verbose but I would say it's not so bad:
The example shows how to assign memory from Structure Of Arrays style arrangement for these buffers, all equally sized.
This is using an helper class called StableArray that uses VirtualMemory to reserve space for extremely large buffers and just commits to physical RAM the actually used quantity.
The WebServerExample in SCExample also shows how to resize such buffers at runtime, while the web-server is running!
It's also possible to just give each connection a buffers of different sizes, making the memory management slightly more complicated.
The library is still in 🟥 Draft state, and it will likely stay like that for the next months.
I can still see some random lost connections in browser tools from Safari / Firefox / Chrome when trying to visit some test website.
Also the performance / latency looks quite bad for now, but it doesn't make sense to start working on performance before becoming compliant with the spec to some acceptable level!
Detailed list of commits:
- 2802e62 Http: Add helper to configure connection buffers and queues at runtime
- d2971b7 Http: Allow declaring fixed size queues side by side with HttpConnection
- a4b7c3c Http: Allow resizing server connections array
- ae44d2a Http: Allow user to setup header memory for each connection
- 15bb382 Http: Improve Documentation
- 39ebbc2 Http: Let caller supply the streams for async file server stream
- 7e5d3e5 Http: Make buffers pool and pipeline per connection
- 0ce599d Http: Make HttpAsyncServer and HttpAsyncFileServer API more symmetric
- c5eac85 Http: Make ThreadPool mandatory to initialize HttpAsyncFileServer
- f2e7024 Http: Move pipeline from file stream to connection object
- f8506b7 Http: Move slice buffers helper to AsyncStreams
- f107b2b Http: Parse response in HttpClient to read Content-Length
- f39ee2c Http: Remove dependency on Memory (drop HttpClient)
- 802e72e Http: Rename HttpServer to HttpConnectionsPool
- af100a9 Http: Rename HttpWebServer to HttpAsyncFileServer
- b306d31 Http: Use AsyncStreams in HttpResponse
- 52c160b Http: Use AsyncStreams in HttpWebServer
- 31395aa Http: Write response headers to the headers buffer
- bd657cf SCExample: Allow changing buffers sizes at runtime in WebServer Example
- 3ed1d51 SCExample: Use virtual memory for all web server buffers
AsyncStreams
A few changes in AsyncStreams have been made, as consequences of Http improvements.
Writable streams can now be destroyed and pipelines are automatically un-piped after all sinks have finished writing their data.
A few fixes also have been applied, like copying listeners during emit event (to allow changing listeners when inside an handler), emptying the read queue on destroy and resetting the request state on init.
Methods to set queues and buffers for the pool have been separated from initialization, so that they can be set during construction / setup and re-used across multiple successive initializations.
Detailed list of commits:
- 99b3082 AsyncStreams: Add destroy method for writable stream
- 371edff AsyncStreams: Add explicit method to set buffers in the pool
- fed7c05 AsyncStreams: Add method to explicitly set read and write queues
- 7d7db8c AsyncStreams: Automatically un-pipe pipelines after all sinks have finished
- ab7efb9 AsyncStreams: Copy listeners during Event emit
- 3d0e8b8 AsyncStreams: Empty the readQueue when destroying
- 94ad89f AsyncStreams: Explicitly mark buffers to be re-used when their refCount goes to zero
- 71cd729 AsyncStreams: Reset requests state on stream initialization
Async
The extensive testing and improvements of Http library has exposed some issues in Async.
A quite nasty bug in the gather writes has been fixed in Posix, affecting partial writes, that has never been surfacing in the unit tests.
Also it made sense to ignore reporting errors when cancellations fail to submit on windows.
This happens when trying to cancel an async operation that has already finished but for which the overlapped status has not been retrieved yet.
Detailed list of commits:
- b5bbc57 Async: Add method to check if event loop backend needs thread-pool
- eb49c42 Async: Do not report errors when cancellations fail to submit
- 4dcedcf Async: Fix incomplete gather writes on Posix
Others
The usual mix of fixes this month includes a debug visualizer for Span<T> and properly support exporting types across dynamic libraries (by adding SC_COMPILER_EXPORT in all relevant places).
During a bad search and replace done a few months ago, Result lost its [[nodiscard]] status, that has been fixed.
GrowableBuffer has now a Span<char> specialization, to allow using things like StringFormat / StringBuilder with raw char arrays.
VirtualMemory class has been cleaned up and improved, with its destructor properly releasing allocated memory.
A bug in Process was reading incomplete output from child processes terminating very quickly.
Detailed list of commits:
- aed874a DebugVisualizer: Add debug visualizers for Span
- 7b368e3 Everywhere: Add SC_COMPILER_EXPORT clause to many types
- 43df70b File: Add method to read into a fixed buffer until it's full or EOF happens
- a107d6e Foundation: Add GrowableBuffer<Span> specialization
- a9806d7 Foundation: Mark Result as a [[nodiscard]] type again
- 4a3f5cb Memory: Make VirtualMemory fields private and add destructor
- 1f393c0 Process: Read entire process output until in user supplied writable span
See you next month!
Full Changelog: release/2025/11...release/2025/12