Possible fix for redis on linux. Setgame/SetStream and rotating statuses will now properly work across shards.

This commit is contained in:
Master Kwoth 2017-09-14 19:37:41 +02:00
parent 37412e4e73
commit 25258a0c61
4 changed files with 94 additions and 31 deletions

View File

@ -30,8 +30,9 @@ namespace NadekoBot.Modules.Administration
private readonly IImagesService _images; private readonly IImagesService _images;
private readonly MusicService _music; private readonly MusicService _music;
private readonly IBotConfigProvider _bc; 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) MusicService music, IImagesService images, IBotConfigProvider bc)
{ {
_db = db; _db = db;
@ -39,6 +40,7 @@ namespace NadekoBot.Modules.Administration
_images = images; _images = images;
_music = music; _music = music;
_bc = bc; _bc = bc;
_bot = bot;
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -349,7 +351,7 @@ namespace NadekoBot.Modules.Administration
[OwnerOnly] [OwnerOnly]
public async Task SetGame([Remainder] string game = null) 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); await ReplyConfirmLocalized("set_game").ConfigureAwait(false);
} }

View File

@ -7,6 +7,7 @@ using NadekoBot.Modules.Music.Services;
using NadekoBot.Services; using NadekoBot.Services;
using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database.Models;
using NLog; using NLog;
using System.Threading.Tasks;
namespace NadekoBot.Modules.Administration.Services namespace NadekoBot.Modules.Administration.Services
{ {
@ -16,6 +17,7 @@ namespace NadekoBot.Modules.Administration.Services
private readonly DiscordSocketClient _client; private readonly DiscordSocketClient _client;
private readonly MusicService _music; private readonly MusicService _music;
private readonly Logger _log; private readonly Logger _log;
private readonly IDataCache _cache;
private readonly Replacer _rep; private readonly Replacer _rep;
private readonly DbService _db; private readonly DbService _db;
private readonly IBotConfigProvider _bcp; private readonly IBotConfigProvider _bcp;
@ -27,50 +29,60 @@ namespace NadekoBot.Modules.Administration.Services
public int Index { get; set; } 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; _client = client;
_bcp = bcp; _bcp = bcp;
_music = music; _music = music;
_db = db; _db = db;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
_rep = new ReplacementBuilder() _cache = cache;
.WithClient(client)
.WithStats(client)
.WithMusic(music)
.Build();
_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; var state = (TimerState)objState;
if (!BotConfig.RotatingStatuses) if (!BotConfig.RotatingStatuses)
return; return;
if (state.Index >= BotConfig.RotatingStatusMessages.Count) if (state.Index >= BotConfig.RotatingStatusMessages.Count)
state.Index = 0; state.Index = 0;
if (!BotConfig.RotatingStatusMessages.Any()) if (!BotConfig.RotatingStatusMessages.Any())
return; return;
var status = BotConfig.RotatingStatusMessages[state.Index++].Status; var status = BotConfig.RotatingStatusMessages[state.Index++].Status;
if (string.IsNullOrWhiteSpace(status)) if (string.IsNullOrWhiteSpace(status))
return; 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) catch (Exception ex)
{ {
_log.Warn(ex); _log.Warn("Rotating playing status errored.\n" + ex);
} }
} }, new TimerState(), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
catch (Exception ex) }
{
_log.Warn("Rotating playing status errored.\n" + ex);
}
}, new TimerState(), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
} }
} }
} }

View File

@ -20,6 +20,8 @@ using NadekoBot.Common.ShardCom;
using NadekoBot.Common.TypeReaders; using NadekoBot.Common.TypeReaders;
using NadekoBot.Common.TypeReaders.Models; using NadekoBot.Common.TypeReaders.Models;
using NadekoBot.Services.Database; using NadekoBot.Services.Database;
using StackExchange.Redis;
using Newtonsoft.Json;
namespace NadekoBot namespace NadekoBot
{ {
@ -257,6 +259,7 @@ namespace NadekoBot
.ForEach(x => CommandService.RemoveModuleAsync(x)); .ForEach(x => CommandService.RemoveModuleAsync(x));
Ready.TrySetResult(true); Ready.TrySetResult(true);
HandleStatusChanges();
_log.Info($"Shard {Client.ShardId} ready."); _log.Info($"Shard {Client.ShardId} ready.");
//_log.Info(await stats.Print().ConfigureAwait(false)); //_log.Info(await stats.Print().ConfigureAwait(false));
} }
@ -319,5 +322,51 @@ namespace NadekoBot
} }
})).Start(); })).Start();
} }
private void HandleStatusChanges()
{
var sub = Services.GetService<IDataCache>().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<IDataCache>().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<IDataCache>().Redis.GetSubscriber();
return sub.PublishAsync("status.game_set", JsonConvert.SerializeObject(obj));
}
} }
} }

View File

@ -10,7 +10,7 @@ namespace NadekoBot.Services.Impl
public RedisCache() public RedisCache()
{ {
Redis = ConnectionMultiplexer.Connect("localhost"); Redis = ConnectionMultiplexer.Connect("127.0.0.1");
Redis.PreserveAsyncOrder = false; Redis.PreserveAsyncOrder = false;
_db = Redis.GetDatabase(); _db = Redis.GetDatabase();
} }