From 25258a0c6174f16eea3c60203468b493bd1b93dc Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Thu, 14 Sep 2017 19:37:41 +0200 Subject: [PATCH] Possible fix for redis on linux. Setgame/SetStream and rotating statuses will now properly work across shards. --- .../Modules/Administration/SelfCommands.cs | 6 +- .../Services/PlayingRotateService.cs | 68 +++++++++++-------- src/NadekoBot/NadekoBot.cs | 49 +++++++++++++ src/NadekoBot/Services/Impl/RedisCache.cs | 2 +- 4 files changed, 94 insertions(+), 31 deletions(-) diff --git a/src/NadekoBot/Modules/Administration/SelfCommands.cs b/src/NadekoBot/Modules/Administration/SelfCommands.cs index 622e1b6b..32d902df 100644 --- a/src/NadekoBot/Modules/Administration/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/SelfCommands.cs @@ -30,8 +30,9 @@ namespace NadekoBot.Modules.Administration private readonly IImagesService _images; private readonly MusicService _music; private readonly IBotConfigProvider _bc; + private readonly NadekoBot _bot; - public SelfCommands(DbService db, DiscordSocketClient client, + public SelfCommands(DbService db, NadekoBot bot, DiscordSocketClient client, MusicService music, IImagesService images, IBotConfigProvider bc) { _db = db; @@ -39,6 +40,7 @@ namespace NadekoBot.Modules.Administration _images = images; _music = music; _bc = bc; + _bot = bot; } [NadekoCommand, Usage, Description, Aliases] @@ -349,7 +351,7 @@ namespace NadekoBot.Modules.Administration [OwnerOnly] public async Task SetGame([Remainder] string game = null) { - await _client.SetGameAsync(game).ConfigureAwait(false); + await _bot.SetGameAsync(game).ConfigureAwait(false); await ReplyConfirmLocalized("set_game").ConfigureAwait(false); } diff --git a/src/NadekoBot/Modules/Administration/Services/PlayingRotateService.cs b/src/NadekoBot/Modules/Administration/Services/PlayingRotateService.cs index 9786d085..d0cd5eef 100644 --- a/src/NadekoBot/Modules/Administration/Services/PlayingRotateService.cs +++ b/src/NadekoBot/Modules/Administration/Services/PlayingRotateService.cs @@ -7,6 +7,7 @@ using NadekoBot.Modules.Music.Services; using NadekoBot.Services; using NadekoBot.Services.Database.Models; using NLog; +using System.Threading.Tasks; namespace NadekoBot.Modules.Administration.Services { @@ -16,6 +17,7 @@ namespace NadekoBot.Modules.Administration.Services private readonly DiscordSocketClient _client; private readonly MusicService _music; private readonly Logger _log; + private readonly IDataCache _cache; private readonly Replacer _rep; private readonly DbService _db; private readonly IBotConfigProvider _bcp; @@ -27,50 +29,60 @@ namespace NadekoBot.Modules.Administration.Services public int Index { get; set; } } - public PlayingRotateService(DiscordSocketClient client, IBotConfigProvider bcp, MusicService music, DbService db) + public PlayingRotateService(DiscordSocketClient client, IBotConfigProvider bcp, + MusicService music, DbService db, IDataCache cache, NadekoBot bot) { _client = client; _bcp = bcp; _music = music; _db = db; _log = LogManager.GetCurrentClassLogger(); - _rep = new ReplacementBuilder() - .WithClient(client) - .WithStats(client) - .WithMusic(music) - .Build(); + _cache = cache; - _t = new Timer(async (objState) => + if (client.ShardId == 0) { - try + + _rep = new ReplacementBuilder() + .WithClient(client) + .WithStats(client) + .WithMusic(music) + .Build(); + + _t = new Timer(async (objState) => { - bcp.Reload(); + try + { + bcp.Reload(); - var state = (TimerState)objState; - if (!BotConfig.RotatingStatuses) - return; - if (state.Index >= BotConfig.RotatingStatusMessages.Count) - state.Index = 0; + var state = (TimerState)objState; + if (!BotConfig.RotatingStatuses) + return; + if (state.Index >= BotConfig.RotatingStatusMessages.Count) + state.Index = 0; - if (!BotConfig.RotatingStatusMessages.Any()) - return; - var status = BotConfig.RotatingStatusMessages[state.Index++].Status; - if (string.IsNullOrWhiteSpace(status)) - return; + if (!BotConfig.RotatingStatusMessages.Any()) + return; + var status = BotConfig.RotatingStatusMessages[state.Index++].Status; + if (string.IsNullOrWhiteSpace(status)) + return; - status = _rep.Replace(status); + status = _rep.Replace(status); - try { await client.SetGameAsync(status).ConfigureAwait(false); } + try + { + await bot.SetGameAsync(status).ConfigureAwait(false); + } + catch (Exception ex) + { + _log.Warn(ex); + } + } catch (Exception ex) { - _log.Warn(ex); + _log.Warn("Rotating playing status errored.\n" + ex); } - } - catch (Exception ex) - { - _log.Warn("Rotating playing status errored.\n" + ex); - } - }, new TimerState(), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); + }, new TimerState(), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); + } } } } diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs index a85da294..5fd01eba 100644 --- a/src/NadekoBot/NadekoBot.cs +++ b/src/NadekoBot/NadekoBot.cs @@ -20,6 +20,8 @@ using NadekoBot.Common.ShardCom; using NadekoBot.Common.TypeReaders; using NadekoBot.Common.TypeReaders.Models; using NadekoBot.Services.Database; +using StackExchange.Redis; +using Newtonsoft.Json; namespace NadekoBot { @@ -257,6 +259,7 @@ namespace NadekoBot .ForEach(x => CommandService.RemoveModuleAsync(x)); Ready.TrySetResult(true); + HandleStatusChanges(); _log.Info($"Shard {Client.ShardId} ready."); //_log.Info(await stats.Print().ConfigureAwait(false)); } @@ -319,5 +322,51 @@ namespace NadekoBot } })).Start(); } + + private void HandleStatusChanges() + { + var sub = Services.GetService().Redis.GetSubscriber(); + sub.Subscribe("status.game_set", async (ch, game) => + { + try + { + var obj = new { Name = default(string) }; + obj = JsonConvert.DeserializeAnonymousType(game, obj); + await Client.SetGameAsync(obj.Name).ConfigureAwait(false); + } + catch (Exception ex) + { + _log.Warn(ex); + } + }, CommandFlags.FireAndForget); + + sub.Subscribe("status.stream_set", async (ch, streamData) => + { + try + { + var obj = new { Name = "", Url = "" }; + obj = JsonConvert.DeserializeAnonymousType(streamData, obj); + await Client.SetGameAsync(obj.Name, obj.Url, StreamType.Twitch).ConfigureAwait(false); + } + catch (Exception ex) + { + _log.Warn(ex); + } + }, CommandFlags.FireAndForget); + } + + public Task SetGameAsync(string game) + { + var obj = new { Name = game }; + var sub = Services.GetService().Redis.GetSubscriber(); + return sub.PublishAsync("status.game_set", JsonConvert.SerializeObject(obj)); + } + + public Task SetStreamAsync(string name, string url) + { + var obj = new { Name = name, Url = url }; + var sub = Services.GetService().Redis.GetSubscriber(); + return sub.PublishAsync("status.game_set", JsonConvert.SerializeObject(obj)); + } } } diff --git a/src/NadekoBot/Services/Impl/RedisCache.cs b/src/NadekoBot/Services/Impl/RedisCache.cs index 5e54979d..716b46ea 100644 --- a/src/NadekoBot/Services/Impl/RedisCache.cs +++ b/src/NadekoBot/Services/Impl/RedisCache.cs @@ -10,7 +10,7 @@ namespace NadekoBot.Services.Impl public RedisCache() { - Redis = ConnectionMultiplexer.Connect("localhost"); + Redis = ConnectionMultiplexer.Connect("127.0.0.1"); Redis.PreserveAsyncOrder = false; _db = Redis.GetDatabase(); }