diff --git a/README.md b/README.md index b73bcc8..3c00baf 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,35 @@ Configuration is read from environment variables: | `RBCS_DIGEST` | *(unset)* | Hash the key with this algorithm (e.g. `sha256`) | | `RBCS_MAX_AGE` | `7d` | Value TTL (`s`/`m`/`h`/`d`) | +### Configuring Granian + +The server runs on [Granian](https://github.com/emmett-framework/granian) via +its RSGI interface. Any granian option can be configured with its standard +`GRANIAN_*` environment variables (see `granian --help`), for example: + +```bash +GRANIAN_LOOP=rloop GRANIAN_WORKERS=4 GRANIAN_HTTP=2 rbcs-server +``` + +Every granian CLI option has a matching `GRANIAN_*` variable +(`GRANIAN_LOOP`, `GRANIAN_WORKERS`, `GRANIAN_HTTP`, `GRANIAN_TASK_IMPL`, +`GRANIAN_RUNTIME_THREADS`, `GRANIAN_BLOCKING_THREADS`, `GRANIAN_LOG_LEVEL`, +`GRANIAN_METRICS`, `GRANIAN_WS`, ...). + +When a `GRANIAN_*` variable and the corresponding `RBCS_*` variable are both +set, the granian one wins: + +- `GRANIAN_HOST` overrides `RBCS_HOST` (default `127.0.0.1`) +- `GRANIAN_PORT` overrides `RBCS_PORT` (default `8080`) +- `GRANIAN_INTERFACE` overrides the default `rsgi` interface + +The Docker image ships the `rloop` event loop, so `GRANIAN_LOOP=rloop` works +out of the box: + +```bash +docker run -e GRANIAN_LOOP=rloop -e RBCS_MEMCACHE_HOST=memcached kaya-rbcs +``` + The app is also a plain ASGI application, so it can be served by any ASGI server, e.g. `daphne kaya_rbcs.app:app`. diff --git a/pyproject.toml b/pyproject.toml index ef3680f..e020d82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ dependencies = [ server = [ "kaya-rsgi", "granian", + "rloop", ] dev = [ "httpx", diff --git a/requirements.in b/requirements.in index 44756fe..a109ed5 100644 --- a/requirements.in +++ b/requirements.in @@ -4,3 +4,4 @@ kaya-core aiomcache kaya-rsgi granian +rloop diff --git a/requirements.txt b/requirements.txt index c8b0f17..9d23f9b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,6 +25,8 @@ pwo==0.1.2 # via # kaya-core # kaya-rsgi +rloop==0.3.1 + # via -r requirements.in typing-extensions==4.16.0 # via # kaya-core diff --git a/src/kaya_rbcs/__main__.py b/src/kaya_rbcs/__main__.py index d347220..902c78e 100644 --- a/src/kaya_rbcs/__main__.py +++ b/src/kaya_rbcs/__main__.py @@ -1,3 +1,4 @@ +import os import sys from typing import List, NoReturn @@ -14,15 +15,17 @@ def main() -> NoReturn: ) from exc config = Config.from_env() - args: List[str] = [ - '--interface', - 'rsgi', - '--host', - config.host, - '--port', - str(config.port), - 'kaya_rbcs.app:app', - ] + args: List[str] = [] + # Only inject our own values when the equivalent GRANIAN_* environment + # variable is not set, so every granian option stays configurable via + # granian's standard GRANIAN_* environment variables. + if not os.getenv('GRANIAN_INTERFACE'): + args += ['--interface', 'rsgi'] + if not os.getenv('GRANIAN_HOST'): + args += ['--host', config.host] + if not os.getenv('GRANIAN_PORT'): + args += ['--port', str(config.port)] + args.append('kaya_rbcs.app:app') sys.argv = [sys.argv[0], *args] entrypoint() # type: ignore[no-untyped-call] raise SystemExit(0)