Add Discord sharding support and related configurations
Some checks failed
CI / Bot (Python) (push) Successful in 12s
CI / Dashboard (Next.js) (push) Failing after 9s

Enhance the bot's architecture by introducing sharding capabilities, allowing for better scalability and performance. Update environment files to include sharding options, and modify the bot's core logic to handle shard connections and latencies. Implement shard-specific logging and API synchronization, ensuring that only the primary shard performs certain tasks. Update API schemas and routes to reflect shard information, improving the overall status reporting and monitoring of the bot's performance across multiple shards.
This commit is contained in:
TheOnlyMace
2026-07-21 23:09:35 +02:00
parent 36b32de34c
commit 4f57cccea5
9 changed files with 136 additions and 12 deletions

View File

@@ -80,6 +80,48 @@ OWNER_IDS_STR: list[str] = [str(i) for i in OWNER_IDS]
# Discord application / OAuth client id (same as dashboard DISCORD_CLIENT_ID)
DISCORD_CLIENT_ID = os.getenv("DISCORD_CLIENT_ID", "").strip()
# ── Discord sharding ──────────────────────────────────────────────────────────
# SHARD_COUNT empty = AutoShardedBot asks Discord for recommended count (in-process).
# SHARD_IDS (e.g. "0,1") + SHARD_COUNT = this process only runs those shards (cluster).
# Primary process runs API / slash sync / emoji sync / stats (shard 0 or override).
def _parse_optional_int(env_key: str) -> int | None:
raw = os.getenv(env_key, "").strip()
if not raw or not raw.isdigit():
return None
return int(raw)
SHARD_COUNT: int | None = _parse_optional_int("SHARD_COUNT")
SHARD_IDS: list[int] = _parse_ids("SHARD_IDS")
def get_shard_kwargs() -> dict:
"""Kwargs for AutoShardedBot.__init__ (omit keys for full auto-sharding)."""
kwargs: dict = {}
if SHARD_COUNT is not None:
kwargs["shard_count"] = SHARD_COUNT
if SHARD_IDS:
if SHARD_COUNT is None:
raise ValueError("SHARD_IDS requires SHARD_COUNT to be set")
kwargs["shard_ids"] = SHARD_IDS
kwargs["shard_count"] = SHARD_COUNT
return kwargs
def _resolve_is_shard_primary() -> bool:
raw = os.getenv("SHARD_PRIMARY", "").strip().lower()
if raw in ("1", "true", "yes", "on"):
return True
if raw in ("0", "false", "no", "off"):
return False
if not SHARD_IDS:
return True
return 0 in SHARD_IDS
IS_SHARD_PRIMARY: bool = _resolve_is_shard_primary()
# Aliases kept for backwards compatibility with files that import these names
BOT_OWNER_IDS = OWNER_IDS
BOT_OWNER_IDS_STR = OWNER_IDS_STR