diff --git a/PluralKit.Bot/Commands/Misc.cs b/PluralKit.Bot/Commands/Misc.cs index 5845cd51..452cd748 100644 --- a/PluralKit.Bot/Commands/Misc.cs +++ b/PluralKit.Bot/Commands/Misc.cs @@ -91,14 +91,14 @@ public class Misc var counts = await _repo.GetStats(); var shards = await _shards.GetShards(); - var shardInfo = shards.Where(s => s.ShardId == ctx.ShardId).First(); + var shardInfo = shards.Where(s => s.ShardId == ctx.ShardId).FirstOrDefault(); // todo: if we're running multiple processes, it is not useful to get the CPU/RAM usage of just the current one var process = Process.GetCurrentProcess(); var memoryUsage = process.WorkingSet64; var now = SystemClock.Instance.GetCurrentInstant().ToUnixTimeSeconds(); - var shardUptime = Duration.FromSeconds(now - shardInfo.LastConnection); + var shardUptime = Duration.FromSeconds(now - shardInfo?.LastConnection ?? 0); var shardTotal = shards.Count(); int shardClusterTotal = ctx.Cluster.Shards.Count; @@ -110,11 +110,11 @@ public class Misc + (isCluster ? $" {shardClusterTotal} in this cluster," : "") + $" {shardUpTotal} are up)" , true)) .Field(new Embed.Field("Shard uptime", - $"{shardUptime.FormatDuration()} ({shardInfo.DisconnectionCount} disconnections)", true)) + $"{shardUptime.FormatDuration()} ({shardInfo?.DisconnectionCount} disconnections)", true)) .Field(new Embed.Field("CPU usage", $"{_cpu.LastCpuMeasure:P1}", true)) .Field(new Embed.Field("Memory usage", $"{memoryUsage / 1024 / 1024} MiB", true)) .Field(new Embed.Field("Latency", - $"API: {apiLatency.TotalMilliseconds:F0} ms, shard: {shardInfo.Latency} ms", + $"API: {apiLatency.TotalMilliseconds:F0} ms, shard: {shardInfo?.Latency} ms", true)); embed.Field(new("Total numbers", $" {counts.SystemCount:N0} systems," diff --git a/PluralKit.Bot/Init.cs b/PluralKit.Bot/Init.cs index 58699111..7e96f6d5 100644 --- a/PluralKit.Bot/Init.cs +++ b/PluralKit.Bot/Init.cs @@ -42,12 +42,14 @@ public class Init opts.DisableTaskUnobservedTaskExceptionCapture(); }); - // initialize Redis - var coreConfig = services.Resolve(); - var redis = services.Resolve(); - await redis.InitAsync(coreConfig); - var config = services.Resolve(); + var coreConfig = services.Resolve(); + + // initialize Redis + var redis = services.Resolve(); + if (config.UseRedisRatelimiter) + await redis.InitAsync(coreConfig); + if (config.Cluster == null) { // "Connect to the database" (ie. set off database migrations and ensure state) @@ -55,7 +57,8 @@ public class Init await services.Resolve().ApplyMigrations(); // Clear shard status from Redis - await redis.Connection.GetDatabase().KeyDeleteAsync("pluralkit:shardstatus"); + if (redis.Connection != null) + await redis.Connection.GetDatabase().KeyDeleteAsync("pluralkit:shardstatus"); } // Init the bot instance itself, register handlers and such to the client before beginning to connect diff --git a/PluralKit.Bot/Services/ShardInfoService.cs b/PluralKit.Bot/Services/ShardInfoService.cs index 3f7c86ac..8487ec97 100644 --- a/PluralKit.Bot/Services/ShardInfoService.cs +++ b/PluralKit.Bot/Services/ShardInfoService.cs @@ -37,6 +37,8 @@ public class ShardInfoService public async Task> GetShards() { + if (_redis.Connection == null) + return new ShardState[] { }; var db = _redis.Connection.GetDatabase(); var redisInfo = await db.HashGetAllAsync("pluralkit:shardstatus"); return redisInfo.Select(x => Proto.Unmarshal(x.Value)); @@ -48,6 +50,12 @@ public class ShardInfoService async Task Inner() { + if (_redis.Connection == null) + { + _logger.Warning("Redis is disabled, shard connection status will be unavailable."); + return; + } + var db = _redis.Connection.GetDatabase(); var redisInfo = await db.HashGetAsync("pluralkit::shardstatus", shard.ShardId); diff --git a/PluralKit.Core/Services/RedisService.cs b/PluralKit.Core/Services/RedisService.cs index c608cfed..22544514 100644 --- a/PluralKit.Core/Services/RedisService.cs +++ b/PluralKit.Core/Services/RedisService.cs @@ -4,7 +4,7 @@ namespace PluralKit.Core; public class RedisService { - public ConnectionMultiplexer Connection { get; set; } + public ConnectionMultiplexer? Connection { get; set; } public async Task InitAsync(CoreConfig config) {