Add Discord sharding support and related configurations
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:
54
bot/Axiom.py
54
bot/Axiom.py
@@ -96,6 +96,17 @@ async def on_ready():
|
||||
print(f"Logged in as: {client.user}")
|
||||
print(f"Connected to: {len(client.guilds)} guilds")
|
||||
print(f"Connected to: {len(client.users)} users")
|
||||
shard_count = client.shard_count or 1
|
||||
shard_ids = list(client.shards.keys()) if client.shards else [0]
|
||||
print(f"Shards: {shard_count} (this process: {shard_ids})")
|
||||
print(f"Shard primary: {IS_SHARD_PRIMARY}")
|
||||
if client.latencies:
|
||||
for sid, lat in client.latencies:
|
||||
print(f" Shard {sid}: {round(lat * 1000)}ms")
|
||||
|
||||
if not IS_SHARD_PRIMARY:
|
||||
print("\033[33m◈ Non-primary shard process — skipping API-side sync tasks\033[0m")
|
||||
return
|
||||
|
||||
# Sync application emojis on startup
|
||||
await run_sync(TOKEN)
|
||||
@@ -112,17 +123,38 @@ async def on_ready():
|
||||
client.loop.create_task(update_stats())
|
||||
|
||||
|
||||
@client.event
|
||||
async def on_shard_connect(shard_id: int):
|
||||
print(f"\033[32m◈ Shard {shard_id}: connected\033[0m")
|
||||
|
||||
|
||||
@client.event
|
||||
async def on_shard_ready(shard_id: int):
|
||||
print(f"\033[32m◈ Shard {shard_id}: ready\033[0m")
|
||||
|
||||
|
||||
@client.event
|
||||
async def on_shard_disconnect(shard_id: int):
|
||||
print(f"\033[33m◈ Shard {shard_id}: disconnected\033[0m")
|
||||
|
||||
|
||||
@client.event
|
||||
async def on_shard_resumed(shard_id: int):
|
||||
print(f"\033[32m◈ Shard {shard_id}: resumed\033[0m")
|
||||
|
||||
|
||||
@client.event
|
||||
async def on_guild_join(guild: discord.Guild):
|
||||
# Only guild-mode needs per-server registration; global mode must not
|
||||
# copy commands into the guild or Discord shows duplicates (/afk twice).
|
||||
try:
|
||||
from utils.slash_sync import _sync_mode, sync_guild
|
||||
if _sync_mode() == "guild":
|
||||
synced = await sync_guild(client, guild, copy_global=True)
|
||||
print(f"◈ Slash sync for new guild {guild.id}: {len(synced)} command(s)")
|
||||
except Exception as e:
|
||||
print(f"Slash sync on guild join failed: {e}")
|
||||
if IS_SHARD_PRIMARY:
|
||||
try:
|
||||
from utils.slash_sync import _sync_mode, sync_guild
|
||||
if _sync_mode() == "guild":
|
||||
synced = await sync_guild(client, guild, copy_global=True)
|
||||
print(f"◈ Slash sync for new guild {guild.id}: {len(synced)} command(s)")
|
||||
except Exception as e:
|
||||
print(f"Slash sync on guild join failed: {e}")
|
||||
|
||||
if not LOG_CHANNEL_ID:
|
||||
return
|
||||
@@ -328,6 +360,9 @@ def run_api():
|
||||
uvicorn.run(fastapi_app, host=API_HOST, port=API_PORT, log_level="warning")
|
||||
|
||||
def keep_alive():
|
||||
if not IS_SHARD_PRIMARY:
|
||||
print(f"\033[33m◈ API Server: Skipped (non-primary shard process)\033[0m")
|
||||
return
|
||||
if not API_ENABLED:
|
||||
print(f"\033[33m◈ API Server: Disabled via API_ENABLED=false\033[0m")
|
||||
return
|
||||
@@ -341,7 +376,10 @@ keep_alive()
|
||||
|
||||
# --- Cloudflare Tunnel (HTTPS for API) — only when explicitly enabled ---
|
||||
from utils.tunnel import start_tunnel
|
||||
start_tunnel()
|
||||
if IS_SHARD_PRIMARY:
|
||||
start_tunnel()
|
||||
else:
|
||||
print("\033[33m◈ Cloudflare Tunnel: Skipped (non-primary shard process)\033[0m")
|
||||
|
||||
# --- Main Bot Execution ---
|
||||
async def main():
|
||||
|
||||
Reference in New Issue
Block a user