Files
discordeno/website/docs/architecture.mdx

152 lines
9.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
sidebar_position: 2
---
import BrowserOnly from '@docusaurus/BrowserOnly';
# Architecture
## Overview
import FlowChart from '@site/src/components/architecture/FlowChart';
<BrowserOnly>{() => <FlowChart />}</BrowserOnly>
Discordeno is a library designed primarily for large-scale bots. Its recommended architecture is tailored to meet the needs of large-scale bot developers or those planning to build bots with the potential to scale significantly in the future. This approach ensures your code is future-proof and ready to handle the demands of a growing bot.
It operates through three main components/processes: **Gateway**, **Bot**, and **Rest**. Each plays a distinct role in managing the functionality and interaction with Discord's API:
1. **Gateway**
- Manages WebSocket communication with Discord.
- Handles connection establishment, restarts, heartbeats, and message transmission over WebSocket.
- Forwards any relevant events to the Bot process.
2. **Bot**
- Processes and converts all events received from the Gateway process.
- Executes your code in response to events like message creation.
- If you need to take any action on Discord, those requests are sent to the Rest manager.
3. **Rest**
- Handles all HTTP requests sent to Discord.
- Manages proxying and rate-limiting to ensure compliance with Discords API constraints.
## Gateway Process
import FlowChart2 from '@site/src/components/architecture/FlowChart2';
<BrowserOnly>{() => <FlowChart2 />}</BrowserOnly>
The Gateway process consists of two parts: the **Gateway Manager** and the **Shard**. The Gateway Manager oversees all the Gateway Shards.
#### Gateway Manager
- **Shard Management**: The Gateway Manager spawns the appropriate number of shards based on data retrieved from Discord's `getGatewayBot` endpoint. Users can override this by directly providing their own `gatewayBot` value.
- **Rate-Limiting Control**: It ensures shards identify in a sequence that adheres to Discord's session start limit, preventing rate-limiting issues.
- **Automatic Resharding**: By default, the manager queries the `getGatewayBot` endpoint every 8 hours and reshard if the shard count changes. This is a very complex topic, and we will dedicate an entire section in our guides to understanding why "re-sharding" is important and how it works.
#### Gateway Shard
- **WebSocket Connection**: The Gateway Shard establishes and maintains a WebSocket connection with Discord.
- **Event Handling**: It passes any incoming event to the `handleMessage` method. This method filters out WebSocket-related events (e.g., `hello`, `resume`, `heartbeat`, and `ready`) and forwards only relevant events to the bot.
- **Customizability**: Every aspect of Discordeno is able to be customized and overridden. However, doing so is not recommended unless you fully understand the implications, as it is critical for maintaining the connection.
- **Event Processing**: After processing an event, the shard forwards it either:
- Directly within the same process
- Through the REST API
- Via a message queue
- Another user-defined mechanism, depending on customization.
## Bot Process
import FlowChart3 from '@site/src/components/architecture/FlowChart3';
<BrowserOnly>{() => <FlowChart3 />}</BrowserOnly>
This is a simplified version of functions used inside of the bot process, showing only the handlers, transformers and event related to channel event
### Bot
The Bot process is the core of Discordeno's event handling system. It processes events received from the Gateway, applies necessary transformations, and triggers user-defined logic. While the process may seem complex at first, its modular design ensures flexibility and efficiency for developers.
When an event arrives from the Gateway, the Bot process executes the following steps:
1. **Run `bot.events.raw` function.**
2. **Run `bot.events.dispatchRequirements` function.**
3. **Pass the data to the appropriate handler.**
4. **Transform and customize the data.**
5. **Call the respective event function to execute your code.**
Lets break this process down further:
#### `bot.events.raw`
- This event is triggered whenever a raw event is received from the Gateway.
- It contains the unprocessed data directly from Discord, providing an opportunity to analyze or log metrics for Gateway events.
- If your bot requires Gateway event metrics, this is the ideal place to implement them.
#### Lazy Loading/Caching With `bot.events.dispatchRequirements`
Lazy loading, or lazy caching, in Discordeno is a feature that allows bot developers to remove unused data from the cache, optimizing memory usage. Imagine your bot is in 100,000 servers. How many of those servers are actively generating events at any given time? Testing shows that only 1020% of servers are typically active, meaning 8090% of cached data is unused. 80,000 to 90,0000 servers were unused for any hour of the day. Lazy loading solves this problem by dynamically managing cache usage based on activity. Heres how it works:
1. **When an Event is Received**:
- If the event contains a `guild id`, Discordeno checks if the guild is in the cache.
- **If the guild is cached**, the event proceeds through the normal processing route.
- **If the guild is NOT cached**, Discordeno fetches the guild, its channels, and any other required data.
- Once the necessary data is cached, the event is passed to the bot's event handler.
> **Key Point**: Your code will always have the necessary data cached for an event, ensuring seamless logic execution without requiring manual checks.
2. **When a Guild Becomes Inactive**:
- If a guild doesnt send any events (e.g., `MESSAGE_CREATE`, `MEMBER_UPDATE`) for a set period (default: 1 hour, customizable), it should be considered as **inactive**.
- At this point, the guild and its related data can safely be removed from the cache.
- This prevents wasting memory on guilds that arent generating events, significantly reducing overall cache usage.
3. **When a Guild Becomes Active Again**:
- If a previously inactive guild sends an event (e.g., a member sends a message), Discordeno fetches and caches the required data for the guild.
- The event is then processed as usual, with all necessary data in place.
### Real-World Impact
Lazy loading allows bots to maintain efficient cache usage, especially for large-scale deployments. Removing unused data from cache can save enormous amounts of memory, especially for bots in many servers. Data is cached only when needed, ensuring memory is used effectively without impacting bot performance.
For example, imagine 90% of your bot's guilds are inactive overnight. Lazy loading offloads their data, freeing memory. As users become active again, events trigger the cache to reload dynamically. Lazy loading ensures your bot is scalable, resource-efficient, and ready for handling massive server counts without sacrificing performance.
:::warning
Be cautious when applying lazy loading to certain events, as excessive get guild requests at once can lead to Cloudflare bans. Discord may occasionally send a large number of events — for example when when they mass ban users — which can trigger a flood of `GUILD_MEMBER_REMOVE` events. If each of these results in a get guild request, it can lead to a Cloudflare ban.
:::
### Handlers
Once lazy loading finishes, the event is passed to a handler, where the data undergoes transformations and customizations. Upon completion, the actual event function is called.
#### Transformers
- **Purpose**: Converts data between Discord's format and Discordeno's format.
- **Example**: Discord represents `channel.id` as a `string`, but in Discordeno, its converted to a `bigint`.
- **Bidirectional**: Transformers handle both directions (e.g., Gateway data → Discordeno format, and vice versa for REST).
- **Seamless Processing**: Ensures consistent data structures across your bot's code.
#### Customizers
- **Purpose**: Allows developers to modify, add, or remove properties or methods of Discord data structures.
- **Flexibility**: Allows any custom logic to be inserted and ran on each item for example if you wanted to do something whenever you received a "Guild".
### Seamless Integration
The Bot process is tightly integrated with the **Gateway** and **Rest** processes to ensure smooth operation:
- **From Gateway**: Receives events and processes them.
- **To Rest**: Sends API requests when necessary for additional data or updates.
This modular approach ensures your bot is highly scalable, efficient, and ready for large-scale deployment.
## Rest Process
import FlowChart4 from '@site/src/components/architecture/FlowChart4';
<BrowserOnly>{() => <FlowChart4 />}</BrowserOnly>
When running multiple processes or workers for your bot, its important to handle REST API requests through a single point. Without a centralized system, each process has its own rate limit handling, which can lead to desynchronized calculations, sending too many invalid requests, and potentially resulting in a Cloudflare ban.
To avoid this, route all your bots and gateway's REST requests through one central process by using the `rest.proxy` option. This lets the rest process handle rate limit properly and prevent you from getting Cloudflare bans.
For more details on how to implement this, you can check [here](./bigbot/step-2-rest.md).