Skip to content

bot

Tux Discord bot core implementation.

This module defines the main Tux bot class, which extends discord.py's Bot and provides comprehensive lifecycle management including setup orchestration, cog loading, database integration, error handling, telemetry, and graceful resource cleanup.

Classes:

  • Tux

    Main bot class for Tux, extending discord.py's commands.Bot.

Classes

Tux

Python
Tux(*args: Any, **kwargs: Any)

Bases: Bot

Main bot class for Tux, extending discord.py's commands.Bot.

This class orchestrates the complete bot lifecycle including database connections, cog loading, Sentry telemetry, background task monitoring, and graceful shutdown procedures.

Attributes:

  • is_shutting_down (bool) –

    Flag indicating if shutdown is in progress (prevents duplicate shutdown).

  • setup_complete (bool) –

    Flag indicating if initial setup has completed successfully.

  • start_time (float | None) –

    Unix timestamp when bot became ready, used for uptime calculations.

  • setup_task (Task[None] | None) –

    Background task that handles async initialization.

  • task_monitor (TaskMonitor) –

    Manages background tasks and ensures proper cleanup.

  • db_service (DatabaseService) –

    Database connection manager and query executor.

  • sentry_manager (SentryManager) –

    Error tracking and telemetry manager.

  • prefix_manager (Any | None) –

    Cache manager for guild-specific command prefixes.

  • emoji_manager (EmojiManager) –

    Custom emoji resolver for the bot.

  • console (Console) –

    Rich console for formatted terminal output.

  • uptime (float) –

    Unix timestamp when bot instance was created.

Initialize the Tux bot and schedule async setup.

Parameters:

  • *args (Any, default: () ) –

    Positional arguments passed to discord.py's Bot.init.

  • **kwargs (Any, default: {} ) –

    Keyword arguments passed to discord.py's Bot.init.

Notes

The actual bot setup happens asynchronously in the setup task to avoid blocking initialization. The setup task is created after a brief delay to ensure the event loop is ready.

Methods:

  • create_setup_task

    Create the async setup task in the proper event loop context.

  • setup

    Perform one-time bot setup and initialization.

  • setup_hook

    Discord.py lifecycle hook called before connecting to Discord.

  • get_prefix_cache_stats

    Get prefix cache statistics for monitoring.

  • on_disconnect

    Discord.py event handler for disconnect events.

  • shutdown

    Gracefully shut down the bot and clean up all resources.

Attributes

db property

Get the database coordinator for accessing database controllers.

Returns:

Notes

This property provides convenient access to database operations via controllers like bot.db.guild_config.get_guild_config().

The coordinator is cached to avoid creating new instances on every access.

Functions

create_setup_task
Python
create_setup_task() -> None

Create the async setup task in the proper event loop context.

Notes

Called by call_soon to ensure we're in the event loop's execution context. Prevents RuntimeError when creating tasks too early.

setup async
Python
setup() -> None

Perform one-time bot setup and initialization.

This method delegates to BotSetupOrchestrator which handles: - Database connection and validation - Cog loading - Cache initialization (prefixes, etc.) - Background task startup

Raises:

  • RuntimeError

    If database setup fails (wrapped from connection errors).

Notes

Uses lazy import of BotSetupOrchestrator to avoid circular dependencies. All setup operations are traced with Sentry spans for monitoring.

setup_hook async
Python
setup_hook() -> None

Discord.py lifecycle hook called before connecting to Discord.

This hook initializes the emoji manager and checks setup task status. It also schedules post-ready startup tasks.

Notes

This is a discord.py callback that runs after init but before the bot connects to Discord. It's a good place for async initialization that doesn't require being connected to Discord yet.

_post_ready_startup async
Python
_post_ready_startup() -> None

Execute post-ready startup tasks after bot is fully connected.

This method waits for both Discord READY and internal setup completion, then performs final initialization steps like logging the banner, instrumenting commands for Sentry, and recording bot statistics.

Notes

Execution order: 1. Wait for Discord READY event 2. Wait for internal bot setup (database, cogs) 3. Record start time 4. Display startup banner 5. Instrument commands for Sentry tracing 6. Record initial bot statistics

get_prefix_cache_stats
Python
get_prefix_cache_stats() -> dict[str, int]

Get prefix cache statistics for monitoring.

Returns:

  • dict[str, int]

    Dictionary containing prefix cache metrics (cached_prefixes, cache_loaded, default_prefix).

Notes

Returns zero values if prefix manager is not initialized yet. Used for monitoring cache hit rates and performance.

_record_bot_stats
Python
_record_bot_stats() -> None

Record basic bot statistics to Sentry context for monitoring.

Captures guild count, user count, channel count, and uptime. This data is attached to all Sentry events for debugging context.

Notes

Only records stats if Sentry is initialized. Safe to call repeatedly.

on_disconnect async
Python
on_disconnect() -> None

Discord.py event handler for disconnect events.

Called when the bot loses connection to Discord. This can happen due to network issues, Discord outages, or intentional reconnection.

Notes

Logs a warning and reports to Sentry for monitoring. Disconnects are normal and discord.py will automatically attempt to reconnect.

_wait_for_setup async
Python
_wait_for_setup() -> None

Wait for the setup task to complete if still running.

If setup fails, triggers bot shutdown to prevent running in a partially initialized state.

Notes

Any exceptions from the setup task are logged and captured, then the bot shuts down.

shutdown async
Python
shutdown() -> None

Gracefully shut down the bot and clean up all resources.

Performs shutdown in three phases: 1. Cancel setup task if still running 2. Clean up background tasks 3. Close Discord, database, and HTTP connections

Notes

This method is idempotent - calling it multiple times is safe. All phases are traced with Sentry for monitoring shutdown performance.

_handle_setup_task async
Python
_handle_setup_task() -> None

Cancel and wait for the setup task if still running.

This prevents the setup task from continuing to run during shutdown, which could cause errors or resource leaks.

Notes

Cancellation is graceful - we suppress CancelledError and wait for the task to fully terminate.

_cleanup_tasks async
Python
_cleanup_tasks() -> None

Clean up all background tasks managed by the task monitor.

Delegates to TaskMonitor which handles canceling and awaiting all background tasks (periodic tasks, cleanup tasks, etc.).

_close_connections async
Python
_close_connections() -> None

Close all external connections (Discord, database, HTTP client).

Each connection type is closed independently with error handling to ensure one failure doesn't prevent others from closing properly.

Notes

Closing order: 1. Discord gateway/WebSocket connection 2. Database connection pool 3. HTTP client session

All errors are logged and reported to Sentry but don't prevent other resources from being cleaned up.

_log_startup_banner async
Python
_log_startup_banner() -> None

Display the startup banner with bot information.

Creates and prints a formatted banner showing bot name, version, guild count, user count, and configured prefix.

Notes

This is called once after the bot is fully ready. The banner is printed to stderr (console) for visibility in logs.

Functions