perf: gzip responses; multi-worker serving with single collection leader
Documentation / Validate Documentation (push) Failing after 8s
Documentation / Build Sphinx Documentation (push) Successful in 15s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 23s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Integration Test with Services (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 12s
Documentation / Generate API Documentation (push) Successful in 9s
Documentation / Documentation Summary (push) Successful in 2s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 0s

GZipMiddleware (min 500 bytes) compresses the dashboard HTML ~4x and
station JSON up to ~100x, end-to-end through the Caddy TLS terminator —
production load testing showed the deployment is bandwidth-bound once
the response caches hit, so compression is the capacity lever.

WEB_WORKERS (default 2) runs uvicorn multi-process via the app import
string. Every worker executes the lifespan, so a localhost lock port
(COLLECTION_LEADER_PORT, default 8901) elects exactly one
background-collection leader per machine — RID/HII polling stays
once-per-cycle instead of once-per-worker; the lock releases with the
process. Locust clients now send Accept-Encoding so future runs measure
compressed transfer, as browsers do.
This commit is contained in:
2026-08-12 11:34:12 +07:00
parent 039af8caac
commit 1ec5cfb4df
4 changed files with 80 additions and 21 deletions
+5
View File
@@ -91,6 +91,11 @@ class Config:
# TTL for the /measurements/latest response cache (hottest endpoint)
LATEST_CACHE_TTL_SECONDS = int(os.getenv("LATEST_CACHE_TTL_SECONDS", "45"))
# Web server worker processes. Above 1, uvicorn forks workers and a
# localhost lock port elects a single background-collection leader.
WEB_WORKERS = int(os.getenv("WEB_WORKERS", "2"))
COLLECTION_LEADER_PORT = int(os.getenv("COLLECTION_LEADER_PORT", "8901"))
# Umami analytics (self-hosted). The website id is public (it ships in the
# dashboard <script> tag); server-side API tracking posts to /api/send.
UMAMI_API_URL = os.getenv("UMAMI_API_URL", "https://stats.buildfor.life/api/send")