Add a Postgres advisory-lock leader election for multi-host deploys (#229)
The subscription notifier elects one leader via a host-local flock (THERMOGRAPH_SINGLETON_LOCK) so multiple uvicorn workers on one host don't each run it. Under multi-host Swarm that guard is insufficient: each host would independently elect its own leader, multiplying Open-Meteo quota use N-fold again. Add claim_pg(key) alongside the existing claim(lock_path): a cluster-wide Postgres advisory lock, visible to every host talking to the same database. The holding connection is dedicated and kept for the process lifetime (advisory locks are session-scoped); a dead connection is dropped and re-election retried on the next call. claim_leader() dispatches between the two mechanisms from env: THERMOGRAPH_SINGLETON_PG (+ Postgres) -> claim_pg; else THERMOGRAPH_SINGLETON_LOCK -> claim; else always leader, unchanged. Wired in at web/app.py in place of the direct claim() call. Off by default, so today's single-host behavior is unaffected.
This commit is contained in:
parent
1f7e8552cf
commit
213b3818e7
1 changed files with 8 additions and 0 deletions
|
|
@ -49,6 +49,14 @@ THERMOGRAPH_COOKIE_SECURE=1
|
||||||
# not once per worker. ~200 MB RAM per worker.
|
# not once per worker. ~200 MB RAM per worker.
|
||||||
WORKERS=4
|
WORKERS=4
|
||||||
|
|
||||||
|
# THERMOGRAPH_SINGLETON_LOCK arbitrates workers on ONE host. Under multi-host Swarm,
|
||||||
|
# each host would independently elect its own leader — multiplying the Open-Meteo
|
||||||
|
# quota use N-fold again. Set THERMOGRAPH_SINGLETON_PG=1 (with THERMOGRAPH_DATABASE_URL
|
||||||
|
# pointing at Postgres) to switch to a cluster-wide Postgres advisory lock instead, so
|
||||||
|
# exactly one host — not one per host — runs the notifier. Leave unset on a single-host
|
||||||
|
# deploy (today's default); the flock above is sufficient there.
|
||||||
|
#THERMOGRAPH_SINGLETON_PG=1
|
||||||
|
|
||||||
# Base path the app is served under.
|
# Base path the app is served under.
|
||||||
# / -> app at the domain root (Thermograph owns the whole domain —
|
# / -> app at the domain root (Thermograph owns the whole domain —
|
||||||
# this is what the Caddyfile expects: thermograph.org proxies "/")
|
# this is what the Caddyfile expects: thermograph.org proxies "/")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue