- memcached (1Gi) shared by both cache servers via a single service - rbcs (java) and kaya-rbcs deployments with identical resource limits (1 cpu / 512Mi) - strict network policies whitelisting only the required communications - manually-triggered benchmark jobs running 'client benchmark -s 256 -e 10000' against the rbcs and rbcs-kaya services
kaya-rbcs
A simplified Python clone of RBCS (Remote Build Cache Server) built on the Kaya web framework.
It implements only the two core cache endpoints — GET and PUT — persisting
values to memcached. Authentication, RBAC, rate limiting, TRACE health checks,
compression and TLS are intentionally left out.
Behavior
The cache key is the request path relative to a configurable URL prefix
(default /), normalized (.. segments are resolved). Values are stored in
memcached together with the Content-Type and Content-Disposition metadata
sent on upload, mirroring RBCS' CacheValueMetadata.
| Request | Response |
|---|---|
PUT /<key> |
201 Created, body = key, Content-Type: text/plain |
GET /<key> (hit) |
200 OK, body = value, stored Content-Type / Content-Disposition |
GET /<key> (miss) |
404 Not Found, empty body |
GET/PUT outside prefix |
400 Bad Request |
Installation
pip install -e . # + kaya-core, aiomcache
pip install -e .[server] # additionally installs granian + kaya-rsgi
Requires Python 3.10+ and a running memcached.
Running
Start the server with the rbcs-server console script or python -m kaya_rbcs:
rbcs-server
Configuration is read from environment variables:
| Variable | Default | Description |
|---|---|---|
RBCS_HOST |
127.0.0.1 |
Bind address |
RBCS_PORT |
8080 |
Bind port |
RBCS_PATH_PREFIX |
/ |
URL prefix that maps to the cache |
RBCS_MEMCACHE_HOST |
127.0.0.1 |
Memcached host |
RBCS_MEMCACHE_PORT |
11211 |
Memcached port |
RBCS_KEY_PREFIX |
(unset) | String appended to each cache key |
RBCS_DIGEST |
(unset) | Hash the key with this algorithm (e.g. sha256) |
RBCS_MAX_AGE |
7d |
Value TTL (s/m/h/d) |
The app is also a plain ASGI application, so it can be served by any ASGI
server, e.g. daphne kaya_rbcs.app:app.
Usage example
curl -X PUT -H 'Content-Type: application/octet-stream' \
--data-binary @build-output.tar http://localhost:8080/my-module/build
curl http://localhost:8080/my-module/build -o build-output.tar
Tests
python -m unittest discover -s tests
Tests use an in-process fake memcached (text protocol), so they run offline with no external dependencies.
Layout
src/kaya_rbcs/
├── __init__.py # package exports + `rbcs-server` entry point
├── __main__.py # Granian (RSGI) launcher
├── config.py # env-based configuration
├── store.py # MemcacheStore: value+metadata encoding, key processing
└── app.py # create_app(): KayaApp with GET/PUT recursive routes
tests/
├── fake_memcached.py
└── test_app.py