fix(highscores): bound service resource usage
The high-score endpoints previously accepted unbounded request bodies and ran SQLite work directly in async handlers, allowing oversized input or database contention to consume server resources. Add a 1 KiB route body limit, admit only one database operation at a time, shed excess requests with a clear 503, and run accepted SQLite work on blocking threads while retaining admission until that work finishes. Extend the Nginx example with matching request, connection, body, and proxy time limits, and cover the limits, health availability, contention, and cancellation behavior with tests. Test Plan: - `just --justfile tdkpin-rs/justfile test` -- passed (144 tests) - `just --justfile tdkpin-rs/justfile clippy` -- passed - `cargo +nightly fmt --manifest-path tdkpin-rs/highscore-server/Cargo.toml -- --check` -- passed - `rumdl check --flavor commonmark tdkpin-rs/highscore-server/README.md` -- passed - `git diff --cached --check` -- passed
This commit is contained in:
@@ -1,10 +1,31 @@
|
||||
# Add this block inside the nginx server block that serves the game.
|
||||
# Add these directives inside the existing nginx http block. The server-wide
|
||||
# zones bound aggregate traffic, while the address-keyed zones prevent one
|
||||
# client from consuming the whole allowance.
|
||||
limit_req_zone $binary_remote_addr zone=tdkpin_highscore_client_rate:10m rate=5r/s;
|
||||
limit_req_zone $server_name zone=tdkpin_highscore_global_rate:1m rate=50r/s;
|
||||
limit_conn_zone $binary_remote_addr zone=tdkpin_highscore_client_connections:10m;
|
||||
limit_conn_zone $server_name zone=tdkpin_highscore_global_connections:1m;
|
||||
|
||||
# Add these blocks inside the server block that serves the game.
|
||||
location /api/highscores {
|
||||
limit_req zone=tdkpin_highscore_client_rate burst=10 nodelay;
|
||||
limit_req zone=tdkpin_highscore_global_rate burst=25 nodelay;
|
||||
limit_req_status 429;
|
||||
limit_conn tdkpin_highscore_client_connections 10;
|
||||
limit_conn tdkpin_highscore_global_connections 100;
|
||||
limit_conn_status 429;
|
||||
|
||||
client_max_body_size 1k;
|
||||
client_body_timeout 5s;
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_connect_timeout 2s;
|
||||
proxy_send_timeout 5s;
|
||||
proxy_read_timeout 5s;
|
||||
proxy_next_upstream off;
|
||||
}
|
||||
|
||||
# Optional health check for local monitoring.
|
||||
|
||||
Reference in New Issue
Block a user