Skip to content

Commit

Permalink
Improve the sharding guide (#80)
Browse files Browse the repository at this point in the history
* Improve the sharding guide

* Explain when to shard more clearly
  • Loading branch information
KubaZ2 authored Nov 28, 2024
1 parent d1b2197 commit 1aec162
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 17 deletions.
6 changes: 3 additions & 3 deletions Documentation/guides/basic-concepts/Sharding/Program.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using NetCord;
using NetCord.Gateway;

ShardedGatewayClient shardedGatewayClient = new(new BotToken("Token from Discord Developer Portal"));
ShardedGatewayClient client = new(new BotToken("Token from Discord Developer Portal"));

shardedGatewayClient.Log += (client, message) =>
client.Log += (client, message) =>
{
Console.WriteLine($"#{client.Shard.GetValueOrDefault().Id}\t{message}");
return default;
};

await shardedGatewayClient.StartAsync();
await client.StartAsync();
await Task.Delay(-1);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using NetCord;
using NetCord.Gateway;

namespace MyBot;

internal class RegisteringHandlers
{
public static async Task RegisterHandlersAsync()
{
ShardedGatewayClient client = new(new BotToken("Token from Discord Developer Portal"));

client.Log += (client, message) =>
{
Console.WriteLine($"#{client.Shard.GetValueOrDefault().Id}\t{message}");
return default;
};

client.MessageUpdate += async (client, message) =>
{
await message.ReplyAsync("Message updated!");
};

await client.StartAsync();
await Task.Delay(-1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using NetCord.Gateway;
using NetCord.Hosting.Gateway;

namespace MyBot;

[GatewayEvent(nameof(GatewayClient.MessageUpdate))]
public class MessageUpdateHandler : IShardedGatewayEventHandler<Message>
{
public async ValueTask HandleAsync(GatewayClient client, Message message)
{
await message.ReplyAsync("Message updated!");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Microsoft.Extensions.Hosting;

using NetCord.Gateway;
using NetCord.Hosting.Gateway;

namespace MyBot;

internal class RegisteringHandlers
{
public static async Task RegisterHandlersAsync(string[] args)
{
var builder = Host.CreateApplicationBuilder(args);

builder.Services
.AddDiscordShardedGateway(options =>
{
options.Intents = GatewayIntents.GuildMessages
| GatewayIntents.DirectMessages
| GatewayIntents.MessageContent;
})
.AddShardedGatewayEventHandlers(typeof(Program).Assembly);

var host = builder.Build()
.UseShardedGatewayEventHandlers();

await host.RunAsync();
}
}
45 changes: 32 additions & 13 deletions Documentation/guides/basic-concepts/sharding.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,44 @@
# Sharding
---
uid: sharding
omitAppTitle: true
title: Scale Your C# Discord Bot with Sharding in NetCord
description: Implement sharding for your C# Discord bot with NetCord to improve scalability and performance by distributing tasks across multiple gateway connections.
---

## When to shard?
# Sharding

Sharding is required when your bot is in more than 2500 guilds.
Sharding allows your bot to split its responsibilities across multiple gateway connections. In NetCord, this is managed by the @NetCord.Gateway.ShardedGatewayClient, which acts as a controller for multiple instances of @NetCord.Gateway.GatewayClient. Each shard, represented by a @NetCord.Gateway.GatewayClient, handles a specific subset of guilds.

## What is sharding?
## When to Shard

Sharding is splitting your bot into multiple @"NetCord.Gateway.GatewayClient"s. Each shard, represented as a @NetCord.Gateway.GatewayClient instance, will be responsible for a certain number of guilds.
Sharding becomes necessary when your bot exceeds 2,500 guilds. However, it's recommended to implement sharding earlier, typically when targeting 1,000+ guilds, to ensure smoother scaling and performance.

## How to shard?
## How to Shard

## [.NET Generic Host](#tab/generic-host)
### [.NET Generic Host](#tab/generic-host)

To start sharding with the .NET Generic Host, instead of calling @NetCord.Hosting.Gateway.GatewayClientServiceCollectionExtensions.AddDiscordGateway(Microsoft.Extensions.DependencyInjection.IServiceCollection), you need to call @NetCord.Hosting.Gateway.ShardedGatewayClientServiceCollectionExtensions.AddDiscordShardedGateway(Microsoft.Extensions.DependencyInjection.IServiceCollection). Example:
When using the .NET Generic Host, you can add the @NetCord.Gateway.ShardedGatewayClient by calling @NetCord.Hosting.Gateway.ShardedGatewayClientServiceCollectionExtensions.AddDiscordShardedGateway*.
[!code-cs[Program.cs](ShardingHosting/Program.cs)]

Also note that you need to use @NetCord.Hosting.Gateway.IShardedGatewayEventHandler or @NetCord.Hosting.Gateway.IShardedGatewayEventHandler`1 instead of @NetCord.Hosting.Gateway.IGatewayEventHandler or @NetCord.Hosting.Gateway.IGatewayEventHandler`1 for event handlers. You also need to use @NetCord.Hosting.Gateway.GatewayEventHandlerServiceCollectionExtensions.AddShardedGatewayEventHandlers(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Reflection.Assembly) to add event handlers and @NetCord.Hosting.Gateway.GatewayEventHandlerHostExtensions.UseShardedGatewayEventHandlers(Microsoft.Extensions.Hosting.IHost) to bind them.

## [Bare Bones](#tab/bare-bones)
### [Bare Bones](#tab/bare-bones)

To start sharding, you need to create an instance of @NetCord.Gateway.ShardedGatewayClient. Its usage is very similar to @NetCord.Gateway.GatewayClient. Example:
For a bare-bones setup, you need to manually create an instance of @NetCord.Gateway.ShardedGatewayClient. Its API is very similar to @NetCord.Gateway.GatewayClient. Here's an example:
[!code-cs[Program.cs](Sharding/Program.cs)]

As you can see, the only difference in usage is that each event has an additional parameter, which is the @NetCord.Gateway.GatewayClient the event has been received from. Also note that events can be invoked concurrently from different shards.
***

## How to Register Events

### [.NET Generic Host](#tab/generic-host)

To register event handlers with sharding in the .NET Generic Host, use @NetCord.Hosting.Gateway.GatewayEventHandlerServiceCollectionExtensions.AddShardedGatewayEventHandlers* to add all event handlers in an assembly and then call @NetCord.Hosting.Gateway.GatewayEventHandlerServiceCollectionExtensions.AddShardedGatewayEventHandlers* to bind these handlers to the sharded client.

[!code-cs[Program.cs](ShardingHosting/RegisteringHandlers.cs?highlight=10,13#L12-L26)]

When creating event handlers, implement @NetCord.Hosting.Gateway.IShardedGatewayEventHandler or @NetCord.Hosting.Gateway.IShardedGatewayEventHandler`1. Note the additional parameter representing the @NetCord.Gateway.GatewayClient that received the event.
[!code-cs[Program.cs](ShardingHosting/MessageUpdateHandler.cs)]

### [Bare Bones](#tab/bare-bones)

For bare-bones setups, adding event handlers is straightforward. Each handler has an additional parameter for the @NetCord.Gateway.GatewayClient that received the event.
[!code-cs[Program.cs](Sharding/RegisteringHandlers.cs#L18-L21)]
2 changes: 1 addition & 1 deletion Documentation/guides/events/first-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ When you run this code, when someone reacts to a message, the bot will notify ev
Other events work similar to these. You can play with them if you want!

> [!NOTE]
> When using @NetCord.Gateway.ShardedGatewayClient, you need to implement @NetCord.Hosting.Gateway.IShardedGatewayEventHandler or @NetCord.Hosting.Gateway.IShardedGatewayEventHandler`1 instead. You also need to use @NetCord.Hosting.Gateway.GatewayEventHandlerServiceCollectionExtensions.AddShardedGatewayEventHandlers(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Reflection.Assembly) to add event handlers and @NetCord.Hosting.Gateway.GatewayEventHandlerHostExtensions.UseShardedGatewayEventHandlers(Microsoft.Extensions.Hosting.IHost) to bind them instead.
> When using @NetCord.Gateway.ShardedGatewayClient, you need to implement @NetCord.Hosting.Gateway.IShardedGatewayEventHandler or @NetCord.Hosting.Gateway.IShardedGatewayEventHandler`1 instead. You also need to use @NetCord.Hosting.Gateway.GatewayEventHandlerServiceCollectionExtensions.AddShardedGatewayEventHandlers* to add event handlers and @NetCord.Hosting.Gateway.GatewayEventHandlerHostExtensions.UseShardedGatewayEventHandlers* to bind them instead. See @sharding?text=Sharding for more information.
## [Bare Bones](#tab/bare-bones)

Expand Down

0 comments on commit 1aec162

Please sign in to comment.