Skip to content

Commit

Permalink
Improve docs
Browse files Browse the repository at this point in the history
Make it easier for interested people to find stuff.
  • Loading branch information
tdittr authored and folkertdev committed May 22, 2024
1 parent 65fa7b7 commit 86361cf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,36 @@ A webserver with predictable memory use.

## Aim

Web servers are hard to deploy. The high-level languages that most backend developers like (ruby, php, nodejs, etc.) suffer from high memory use and garbage collection pauses. Low-level languages (rust, zig, etc.) make it possible to control performance and memory use, but struggle to provide the ergonomics of the industry-standard high-level languages.
Web servers are hard to deploy. The high-level languages that most backend developers like (ruby, php, nodejs, etc.)
suffer from high memory use and garbage collection pauses. Low-level languages (rust, zig, etc.) make it possible to
control performance and memory use, but struggle to provide the ergonomics of the industry-standard high-level
languages.

Nea aims to provide both more reliable performance (by being smarter about allocations) and a convenient high-level language experience via the [roc programming language](https://www.roc-lang.org/).
Nea aims to provide both more reliable performance (by being smarter about allocations) and a convenient high-level
language experience via the [roc programming language](https://www.roc-lang.org/).

Nothing comes for free though. Nea imposes two serious constraints: each request only gets a fixed amount of memory, and in total there is a fixed amount of such memory regions. Combined, that means that nea can perform just one (very large) allocation at startup, and thereafter will not touch the system allocator again. When a request is done, its memory region is wiped and reused for later requests.
Nothing comes for free though. Nea imposes two serious constraints: each request only gets a fixed amount of memory, and
in total there is a fixed amount of such memory regions. Combined, that means that nea can perform just one (very large)
allocation at startup, and thereafter will not touch the system allocator again. When a request is done, its memory
region is wiped and reused for later requests.

This is, of course, a tradeoff. It assumes that the request handling takes a decent amount of memory and that the request workload is reasonably consistent (not too many outliers). Because the one alloctation is of a fixed size, there is no way to scale an individual nea instance: changes in traffic volume can only be responded to by in- or decreasing the number of nea instances.
This is, of course, a tradeoff. It assumes that the request handling takes a decent amount of memory and that the
request workload is reasonably consistent (not too many outliers). Because the one alloctation is of a fixed size, there
is no way to scale an individual nea instance: changes in traffic volume can only be responded to by in- or decreasing
the number of nea instances.

But in return you get a very reliable system: peak memory use is average memory use, there will never be any global garbage collection pauses, and when a particular request does exceed its memory limit, only that request gets cancelled (by sending a proper http error).
But in return you get a very reliable system: peak memory use is average memory use, there will never be any global
garbage collection pauses, and when a particular request does exceed its memory limit, only that request gets
cancelled (by sending a proper http error).

## Getting started

* For how it works check out this [blog post](https://tweedegolf.nl/en/blog/114/building-an-async-runtime-with-mio)
* Look at the [`rust-nea` benchmark](benchmarks/rust-nea) for a usage from Rust
* Look at the [`roc-nea` benchmark](benchmarks/roc-nea) for a usage from Roc

*Note:* This crate only works on Linux on x86_64 because of the manual implementation of
setjmp/longjmp [here](shared/src/setjmp_longjmp.rs).

## Funders

Expand Down
4 changes: 4 additions & 0 deletions shared/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
pub mod allocator;
pub mod indexer;

/// Implementation of setjmp/longjmp
///
/// The libc crate does not expose these because it is too unsafe.
pub mod setjmp_longjmp;

0 comments on commit 86361cf

Please sign in to comment.