:book: docs: main branch
:warning: On linux --linker=legacy
is necessary for this package because of this Roc issue.
A webserver platform with a simple interface.
:racing_car: basic-webserver uses Rust's high-performance hyper and tokio libraries to execute your Roc function on incoming requests.
Run this example server with $ roc helloweb.roc
(on linux, add --linker=legacy
) and go to http://localhost:8000
in your browser. You can change the port (8000) and the host (localhost) by setting the environment variables ROC_BASIC_WEBSERVER_PORT and ROC_BASIC_WEBSERVER_HOST.
app [Model, server] { pf: platform "https://github.com/roc-lang/basic-webserver/releases/download/0.9.0/taU2jQuBf-wB8EJb0hAkrYLYOGacUU5Y9reiHG45IY4.tar.br" }
import pf.Stdout
import pf.Http exposing [Request, Response]
import pf.Utc
# Model is produced by `init`.
Model : {}
# With `init` you can set up a database connection once at server startup,
# generate css by running `tailwindcss`,...
# In this case we don't have anything to initialize, so it is just `Task.ok {}`.
server = { init: Task.ok {}, respond }
respond : Request, Model -> Task Response [ServerErr Str]_
respond = \req, _ ->
# Log request datetime, method and url
datetime = Utc.now! |> Utc.toIso8601Str
Stdout.line! "$(datetime) $(Http.methodToStr req.method) $(req.url)"
Task.ok { status: 200, headers: [], body: Str.toUtf8 "<b>Hello, web!</b></br>" }
If you'd like to contribute, check out our group chat and let us know what you're thinking, we're friendly!
If you have cloned this repository and want to run the examples without using a packaged release (...tar.br), you will need to build the platform first by running roc build.roc
. Run examples with roc examples/hello.roc
(on linux, add --linker=legacy
).
Basic webserver should have decent performance due to being built on top of Rust's hyper. That said, it has a few known issues that hurt performance:
That said, running benchmarks and debugging performance is still a great idea. It can help improve both Roc and basic-webserver.
Lots of load generators exist. Generally, it is advised to use one that avoids coordinated omission. A trusted generator that fits this criteria is wrk2 (sadly doesn't work on Apple Silicon).
If you are benchmarking on a single machine, you can use the TOKIO_WORKER_THREADS
environment variable to limit parallelism of the webserver.
Note: When benchmarking, it is best to run the load generator and the webserver on different machines.
When benchmarking on a single 8 core machine with wrk2
, these commands could be used (simply tune connections -c
and rate -R
):
roc build --optimize my-webserver.roc
TOKIO_WORKER_THREADS=4 ./my-webserver
wrk -t4 -c100 -d30s -R2000 http://127.0.0.1:8000