Skip to main content

Module distributed

Module distributed 

Source
Expand description

The distributed-store seam: the engine-side traits and key helpers for Redis-backed (or any backend) rate limiting and bans.

Sources: guard_core/handlers/ratelimit_handler.py, _ipban_bans.py, _ipban_queries.py, redis_handler.py. The traits are synchronous and assumption-ready, the same pattern the geo handler seam uses.

The engine stays I/O-free: the traits are synchronous and assumption-ready (the same pattern the crate::geo::GeoIpHandler seam uses), and backends live in adapters - the facade crate ships a Redis implementation behind its redis feature.

§The reference window semantics, point by point

One recorded hit runs the reference’s four operations in one transaction over the key {prefix}rate_limit:rate:{ip} (global scope) or {prefix}rate_limit:rate:{ip}:{sha256(endpoint)} (endpoint scope, _hash_identity_segment):

  1. ZADD key now now
  2. ZREMRANGEBYSCORE key 0 (now - window) (the reference bounds are inclusive, exactly its Lua/pipeline arguments)
  3. ZCARD key
  4. EXPIRE key window * 2

The Redis store compares the post-recording count against the limit (allowed = count <= limit); the in-memory store compares the pre-recording count (count < limit) - the same boundary, as the reference documents on its own module docstring.

§Ban storage

A ban writes SET {prefix}banned_ips:{ip} <expiry unix seconds> EX ttl (the reference set_key("banned_ips", ip, str(expiry), ttl=duration)); a lookup reads the key, honors now <= expiry, and deletes the stale key otherwise (the reference _check_redis_exact). A failed ban write degrades to the local store with the TTL clamped to the local cap, exactly the reference except branch.

§Failure semantics

The reference redis_fail_open flag (false by default): a failing Redis call raises GuardRedisError(503, "Redis rate limiting unavailable") when closed, and falls back to the in-memory window (with a one-time warning) when open. The port mirrors both: a StoreError from the window store surfaces as Err (the facade stage answers the 503) or degrades to the in-memory window under fail-open.

Structs§

MemoryStore
An in-memory backend for the distributed paths: the same operations a Redis runs, keyed the same way, so the engine’s store paths are testable without a backend process.
StoreError
A backend failure, wrapped losslessly as a string (the engine never sees backend types).

Traits§

BanStore
The reference banned_ips storage operations (the {prefix}banned_ips:{ip} namespace).
SlidingWindowStore
The reference rate-limit window operations, one hit per call.

Functions§

ban_key
The {prefix}banned_ips:{ip} ban key (set_key("banned_ips", ip, ...)’s full key).
identity_hash
_hash_identity_segment: the sha256 hex digest of the UTF-8 value.
rate_window_key
The {prefix}rate_limit:rate:{ip} window key, the global tier’s bucket (rate_key = f"rate:{client_ip}").
rate_window_key_endpoint
The {prefix}rate_limit:rate:{ip}:{endpoint hash} window key, the endpoint tier’s bucket (_hash_identity_segment = sha256 hex).