forked from EllieBotDevs/elliebot
Toastie
487c7865cb
Fixed the check for updates service Version upped to 5.1.12. Updated CHANGELOG.md
131 lines
No EOL
3.8 KiB
C#
131 lines
No EOL
3.8 KiB
C#
#nullable disable
|
|
using Grpc.Core;
|
|
using Grpc.Net.Client;
|
|
using EllieBot.Common.ModuleBehaviors;
|
|
using EllieBot.Coordinator;
|
|
|
|
namespace EllieBot.Services;
|
|
|
|
public class RemoteGrpcCoordinator : ICoordinator, IReadyExecutor
|
|
{
|
|
private readonly Coordinator.Coordinator.CoordinatorClient _coordClient;
|
|
private readonly DiscordSocketClient _client;
|
|
|
|
public RemoteGrpcCoordinator(IBotCreds creds, DiscordSocketClient client)
|
|
{
|
|
var coordUrl = string.IsNullOrWhiteSpace(creds.CoordinatorUrl) ? "http://localhost:3442" : creds.CoordinatorUrl;
|
|
|
|
var channel = GrpcChannel.ForAddress(coordUrl);
|
|
_coordClient = new(channel);
|
|
_client = client;
|
|
}
|
|
|
|
public bool RestartBot()
|
|
{
|
|
_coordClient.RestartAllShards(new());
|
|
|
|
return true;
|
|
}
|
|
|
|
public void Die(bool graceful)
|
|
=> _coordClient.Die(new()
|
|
{
|
|
Graceful = graceful
|
|
});
|
|
|
|
public bool RestartShard(int shardId)
|
|
{
|
|
_coordClient.RestartShard(new()
|
|
{
|
|
ShardId = shardId
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
public IList<ShardStatus> GetAllShardStatuses()
|
|
{
|
|
var res = _coordClient.GetAllStatuses(new());
|
|
|
|
return res.Statuses.ToArray()
|
|
.Map(s => new ShardStatus
|
|
{
|
|
ConnectionState = FromCoordConnState(s.State),
|
|
GuildCount = s.GuildCount,
|
|
ShardId = s.ShardId,
|
|
LastUpdate = s.LastUpdate.ToDateTime()
|
|
});
|
|
}
|
|
|
|
public int GetGuildCount()
|
|
{
|
|
var res = _coordClient.GetAllStatuses(new());
|
|
|
|
return res.Statuses.Sum(x => x.GuildCount);
|
|
}
|
|
|
|
public async Task Reload()
|
|
=> await _coordClient.ReloadAsync(new());
|
|
|
|
public Task OnReadyAsync()
|
|
{
|
|
Task.Run(async () =>
|
|
{
|
|
var gracefulImminent = false;
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
var reply = await _coordClient.HeartbeatAsync(new()
|
|
{
|
|
State = ToCoordConnState(_client.ConnectionState),
|
|
GuildCount =
|
|
_client.ConnectionState == ConnectionState.Connected ? _client.Guilds.Count : 0,
|
|
ShardId = _client.ShardId
|
|
},
|
|
deadline: DateTime.UtcNow + TimeSpan.FromSeconds(10));
|
|
gracefulImminent = reply.GracefulImminent;
|
|
}
|
|
catch (RpcException ex)
|
|
{
|
|
if (!gracefulImminent)
|
|
{
|
|
Log.Warning(ex, "Hearbeat failed and graceful shutdown was not expected: {Message}",
|
|
ex.Message);
|
|
break;
|
|
}
|
|
|
|
Log.Information("Coordinator is restarting gracefully. Waiting...");
|
|
await Task.Delay(30_000);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex, "Unexpected heartbeat exception: {Message}", ex.Message);
|
|
break;
|
|
}
|
|
|
|
await Task.Delay(7500);
|
|
}
|
|
|
|
Environment.Exit(5);
|
|
});
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private ConnState ToCoordConnState(ConnectionState state)
|
|
=> state switch
|
|
{
|
|
ConnectionState.Connecting => ConnState.Connecting,
|
|
ConnectionState.Connected => ConnState.Connected,
|
|
_ => ConnState.Disconnected
|
|
};
|
|
|
|
private ConnectionState FromCoordConnState(ConnState state)
|
|
=> state switch
|
|
{
|
|
ConnState.Connecting => ConnectionState.Connecting,
|
|
ConnState.Connected => ConnectionState.Connected,
|
|
_ => ConnectionState.Disconnected
|
|
};
|
|
} |