docs: Simplify verbose docstrings

- save_map_file(): 55 lines → 12 lines
- is_legacy_backend(): 42 lines → 11 lines
- _check_response_for_errors(): 40 lines → 9 lines

Keep essential info, remove redundant examples and explanations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kaffa
2026-02-03 13:25:45 +09:00
parent 06ab47aca8
commit 95ab0583b3
2 changed files with 13 additions and 120 deletions

View File

@@ -147,61 +147,17 @@ def split_domain_entries(entries: list[tuple[str, str]]) -> tuple[list[tuple[str
def save_map_file(entries: list[tuple[str, str]]) -> None:
"""Save domain-to-backend entries using 2-stage map routing architecture.
"""Save domain-to-backend entries to map files.
This function implements HAProxy's 2-stage domain routing for optimal
performance. Entries are automatically split into two separate map files
based on whether they are exact domains or wildcard patterns.
2-Stage Routing Architecture:
Stage 1 - Exact Match (domains.map):
- HAProxy directive: map_str(req.hdr(host),"/path/domains.map")
- Data structure: ebtree (elastic binary tree)
- Lookup complexity: O(log n)
- Use case: Exact domain matches (e.g., "api.example.com")
Stage 2 - Wildcard Match (wildcards.map):
- HAProxy directive: map_dom(req.hdr(host),"/path/wildcards.map")
- Data structure: Linear suffix search
- Lookup complexity: O(n) where n = number of wildcard entries
- Use case: Wildcard domains (e.g., ".example.com" matches *.example.com)
- Typically small set, so O(n) is acceptable
Performance Characteristics:
- 1000 exact domains: ~10 comparisons (log2(1000) approx 10)
- 10 wildcard entries: 10 suffix comparisons (acceptable)
- By separating exact and wildcard entries, we avoid O(n) lookup
for the common case (exact domain match)
HAProxy Configuration Example:
use_backend %[req.hdr(host),lower,map_str(/etc/haproxy/domains.map)]
if { req.hdr(host),lower,map_str(/etc/haproxy/domains.map) -m found }
use_backend %[req.hdr(host),lower,map_dom(/etc/haproxy/wildcards.map)]
if { req.hdr(host),lower,map_dom(/etc/haproxy/wildcards.map) -m found }
Splits entries into two files for 2-stage routing:
- domains.map: Exact matches (map_str, O(log n))
- wildcards.map: Wildcard entries starting with "." (map_dom, O(n))
Args:
entries: List of (domain, backend) tuples to write.
- Exact domains: "api.example.com" -> written to domains.map
- Wildcards: ".example.com" (matches *.example.com) -> written
to wildcards.map
entries: List of (domain, backend) tuples.
Raises:
IOError: If either map file cannot be written.
File Formats:
domains.map:
# Exact Domain to Backend mapping (for map_str)
api.example.com pool_1
www.example.com pool_2
wildcards.map:
# Wildcard Domain to Backend mapping (for map_dom)
.example.com pool_3 # Matches *.example.com
.test.org pool_4 # Matches *.test.org
Note:
Both files are written atomically using temp file + rename to prevent
corruption during concurrent access or system failures.
IOError: If map files cannot be written.
"""
# Split into exact and wildcard entries
exact_entries, wildcard_entries = split_domain_entries(entries)
@@ -245,46 +201,14 @@ def get_domain_backend(domain: str) -> Optional[str]:
def is_legacy_backend(backend: str) -> bool:
"""Check if backend is a legacy static backend (not a dynamic pool).
This function distinguishes between two backend naming conventions used
in the HAProxy MCP system:
Pool Backends (Dynamic):
- Named: pool_1, pool_2, ..., pool_100
- Pre-configured in haproxy.cfg with 10 server slots each
- Domains are dynamically assigned to available pools via domains.map
- Server slots configured at runtime via Runtime API
- Allows zero-reload domain management
Legacy Backends (Static):
- Named: {domain}_backend (e.g., "api_example_com_backend")
- Defined statically in haproxy.cfg
- Requires HAProxy reload to add new backends
- Used for domains that were configured before pool-based routing
Pool backends: pool_1, pool_2, ..., pool_100 (dynamic, zero-reload)
Legacy backends: {domain}_backend (static, requires reload)
Args:
backend: Backend name to check (e.g., "pool_5" or "api_example_com_backend").
backend: Backend name to check.
Returns:
True if this is a legacy backend (does not start with "pool_"),
False if it's a pool backend.
Usage Scenarios:
- When listing servers: Determines server naming convention
(pool backends use pool_N_M, legacy use {domain}_M)
- When adding servers: Determines which backend configuration
approach to use
- During migration: Helps identify domains that need migration
from legacy to pool-based routing
Examples:
>>> is_legacy_backend("pool_5")
False
>>> is_legacy_backend("pool_100")
False
>>> is_legacy_backend("api_example_com_backend")
True
>>> is_legacy_backend("myservice_backend")
True
True if legacy backend, False if pool backend.
"""
return not backend.startswith("pool_")