feat: shard status update, delete old messages when they expire

This commit is contained in:
sam 2024-10-13 17:08:32 +02:00
parent 8e030acaf3
commit 32732d74d0
9 changed files with 302 additions and 17 deletions

View file

@ -19,7 +19,8 @@ public class ShardedGatewayClient(
Config config
) : IDisposable
{
private int _shardCount = config.Discord.ShardCount ?? 0;
public int TotalShards { get; private set; } = config.Discord.ShardCount ?? 0;
private readonly ILogger _logger = logger.ForContext<ShardedGatewayClient>();
private readonly ConcurrentDictionary<int, DiscordGatewayClient> _gatewayClients = new();
@ -33,6 +34,9 @@ public class ShardedGatewayClient(
GatewayConnectionStatus
> GetConnectionStatus = client => (GatewayConnectionStatus)Field.GetValue(client)!;
public static bool IsConnected(DiscordGatewayClient client) =>
GetConnectionStatus(client) == GatewayConnectionStatus.Connected;
public IReadOnlyDictionary<int, DiscordGatewayClient> Shards => _gatewayClients;
public async Task<Result> RunAsync(CancellationToken ct = default)
@ -46,19 +50,19 @@ public class ShardedGatewayClient(
if (gatewayResult.Entity.Shards.IsDefined(out var discordShardCount))
{
if (_shardCount < discordShardCount && _shardCount != 0)
if (TotalShards < discordShardCount && TotalShards != 0)
_logger.Warning(
"Discord recommends {DiscordShardCount} for this bot, but only {ConfigShardCount} shards are requested. This may cause issues later",
discordShardCount,
_shardCount
TotalShards
);
if (_shardCount == 0)
_shardCount = discordShardCount;
if (TotalShards == 0)
TotalShards = discordShardCount;
}
var clients = Enumerable
.Range(0, _shardCount)
.Range(0, TotalShards)
.Select(s =>
{
var client = ActivatorUtilities.CreateInstance<DiscordGatewayClient>(
@ -74,7 +78,7 @@ public class ShardedGatewayClient(
for (var shardIndex = 0; shardIndex < clients.Length; shardIndex++)
{
_logger.Debug("Starting shard {ShardId}/{ShardCount}", shardIndex, _shardCount);
_logger.Debug("Starting shard {ShardId}/{ShardCount}", shardIndex, TotalShards);
var client = clients[shardIndex];
var res = client.RunAsync(ct);
@ -93,13 +97,13 @@ public class ShardedGatewayClient(
return res.Result;
}
_logger.Information("Started shard {ShardId}/{ShardCount}", shardIndex, _shardCount);
_logger.Information("Started shard {ShardId}/{ShardCount}", shardIndex, TotalShards);
}
return await await Task.WhenAny(tasks);
}
public int ShardIdFor(ulong guildId) => (int)((guildId >> 22) % (ulong)_shardCount);
public int ShardIdFor(ulong guildId) => (int)((guildId >> 22) % (ulong)TotalShards);
public DiscordGatewayClient ClientFor(Snowflake guildId) => ClientFor(guildId.Value);
@ -112,6 +116,7 @@ public class ShardedGatewayClient(
public void Dispose()
{
GC.SuppressFinalize(this);
foreach (var client in _gatewayClients.Values)
client.Dispose();
}
@ -123,7 +128,7 @@ public class ShardedGatewayClient(
{
var ret = new DiscordGatewayClientOptions
{
ShardIdentification = new ShardIdentification(shardId, _shardCount),
ShardIdentification = new ShardIdentification(shardId, TotalShards),
Intents = options.Intents,
Presence = options.Presence,
ConnectionProperties = options.ConnectionProperties,