local image caching to redis done?

This commit is contained in:
Master Kwoth 2017-11-05 13:28:08 +01:00
parent 4b7b44f0d4
commit 607decfbcc
17 changed files with 267 additions and 121 deletions

View File

@ -29,19 +29,18 @@ namespace NadekoBot.Modules.Administration
private static readonly object _locker = new object();
private readonly DiscordSocketClient _client;
private readonly IImagesService _images;
private readonly IImageCache _images;
private readonly IBotConfigProvider _bc;
private readonly NadekoBot _bot;
private readonly IBotCredentials _creds;
private readonly IDataCache _cache;
public SelfCommands(DbService db, NadekoBot bot, DiscordSocketClient client,
IImagesService images, IBotConfigProvider bc,
IBotCredentials creds, IDataCache cache)
IBotConfigProvider bc, IBotCredentials creds, IDataCache cache)
{
_db = db;
_client = client;
_images = images;
_images = cache.LocalImages;
_bc = bc;
_bot = bot;
_creds = creds;

View File

@ -30,11 +30,11 @@ namespace NadekoBot.Modules.Administration.Services
private readonly IBotCredentials _creds;
private ImmutableArray<AsyncLazy<IDMChannel>> ownerChannels = new ImmutableArray<AsyncLazy<IDMChannel>>();
private readonly IBotConfigProvider _bc;
private readonly IImagesService _imgs;
private readonly IImageCache _imgs;
public SelfService(DiscordSocketClient client, NadekoBot bot, CommandHandler cmdHandler, DbService db,
IBotConfigProvider bc, ILocalization localization, NadekoStrings strings, IBotCredentials creds,
IDataCache cache, IImagesService imgs)
IDataCache cache)
{
_redis = cache.Redis;
_bot = bot;
@ -46,7 +46,7 @@ namespace NadekoBot.Modules.Administration.Services
_client = client;
_creds = creds;
_bc = bc;
_imgs = imgs;
_imgs = cache.LocalImages;
var sub = _redis.GetSubscriber();
sub.Subscribe(_creds.RedisKey() + "_reload_images",

View File

@ -24,11 +24,11 @@ namespace NadekoBot.Modules.Gambling
private static readonly Regex fudgeRegex = new Regex(@"^(?<n1>\d+)d(?:F|f)$", RegexOptions.Compiled);
private static readonly char[] _fateRolls = { '-', ' ', '+' };
private readonly IImagesService _images;
private readonly IImageCache _images;
public DriceRollCommands(IImagesService images)
public DriceRollCommands(IDataCache data)
{
_images = images;
_images = data.LocalImages;
}
@ -141,10 +141,8 @@ namespace NadekoBot.Modules.Gambling
private async Task InternallDndRoll(string arg, bool ordered)
{
Match match;
int n1;
int n2;
if ((match = fudgeRegex.Match(arg)).Length != 0 &&
int.TryParse(match.Groups["n1"].ToString(), out n1) &&
int.TryParse(match.Groups["n1"].ToString(), out int n1) &&
n1 > 0 && n1 < 500)
{
var rng = new NadekoRandom();
@ -164,13 +162,14 @@ namespace NadekoBot.Modules.Gambling
{
var rng = new NadekoRandom();
if (int.TryParse(match.Groups["n1"].ToString(), out n1) &&
int.TryParse(match.Groups["n2"].ToString(), out n2) &&
int.TryParse(match.Groups["n2"].ToString(), out int n2) &&
n1 <= 50 && n2 <= 100000 && n1 > 0 && n2 > 0)
{
var add = 0;
var sub = 0;
int.TryParse(match.Groups["add"].Value, out add);
int.TryParse(match.Groups["sub"].Value, out sub);
if (!int.TryParse(match.Groups["add"].Value, out int add) ||
!int.TryParse(match.Groups["sub"].Value, out int sub))
{
return;
}
var arr = new int[n1];
for (int i = 0; i < n1; i++)

View File

@ -17,15 +17,15 @@ namespace NadekoBot.Modules.Gambling
[Group]
public class FlipCoinCommands : NadekoSubmodule
{
private readonly IImagesService _images;
private readonly IImageCache _images;
private readonly IBotConfigProvider _bc;
private readonly CurrencyService _cs;
private static readonly NadekoRandom rng = new NadekoRandom();
public FlipCoinCommands(IImagesService images, CurrencyService cs, IBotConfigProvider bc)
public FlipCoinCommands(IDataCache data, CurrencyService cs, IBotConfigProvider bc)
{
_images = images;
_images = data.LocalImages;
_bc = bc;
_cs = cs;
}

View File

@ -32,12 +32,12 @@ namespace NadekoBot.Modules.Gambling
//https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg
//thanks to judge for helping me with this
private readonly IImagesService _images;
private readonly IImageCache _images;
private readonly CurrencyService _cs;
public SlotCommands(IImagesService images, IBotConfigProvider bc, CurrencyService cs)
public SlotCommands(IDataCache data, IBotConfigProvider bc, CurrencyService cs)
{
_images = images;
_images = data.LocalImages;
_bc = bc;
_cs = cs;
}

View File

@ -14,6 +14,7 @@ namespace NadekoBot.Modules.Games.Common
public class GirlRating
{
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
private readonly IImageCache _images;
public double Crazy { get; }
public double Hot { get; }
@ -21,8 +22,9 @@ namespace NadekoBot.Modules.Games.Common
public string Advice { get; }
public AsyncLazy<string> Url { get; }
public GirlRating(IImagesService _images, double crazy, double hot, int roll, string advice)
public GirlRating(IImageCache images, double crazy, double hot, int roll, string advice)
{
_images = images;
Crazy = crazy;
Hot = hot;
Roll = roll;
@ -45,7 +47,7 @@ namespace NadekoBot.Modules.Games.Common
using (var pointMs = new MemoryStream(_images.RategirlDot.ToArray(), false))
using (var pointImg = Image.Load(pointMs))
{
img.DrawImage(pointImg, 100, default(Size), new Point(pointx - 10, pointy - 10));
img.DrawImage(pointImg, 100, default, new Point(pointx - 10, pointy - 10));
}
string url;

View File

@ -19,11 +19,11 @@ namespace NadekoBot.Modules.Games
//todo update docs
public partial class Games : NadekoTopLevelModule<GamesService>
{
private readonly IImagesService _images;
private readonly IImageCache _images;
public Games(IImagesService images)
public Games(IDataCache data)
{
_images = images;
_images = data.LocalImages;
}
//#if GLOBAL_NADEKO
// [NadekoCommand, Usage, Description, Aliases]

View File

@ -9,6 +9,7 @@ using System.Linq;
using System.Threading.Tasks;
using NadekoBot.Common.Attributes;
using NadekoBot.Modules.Games.Services;
using System;
namespace NadekoBot.Modules.Games
{
@ -88,12 +89,18 @@ namespace NadekoBot.Modules.Games
else
msgToSend += " " + GetText("pick_sn", Prefix);
using (var toSend = imgData.Data.ToStream())
using (var toSend = imgData.ToStream())
{
msg = await Context.Channel.SendFileAsync(toSend, imgData.Name, msgToSend).ConfigureAwait(false);
msg = await Context.Channel.SendFileAsync(toSend, "plant.png", msgToSend, options: new RequestOptions()
{
RetryMode = RetryMode.AlwaysRetry
}).ConfigureAwait(false);
}
}
catch { }
catch (Exception ex)
{
_log.Warn(ex);
}
var msgs = new IUserMessage[amount];
msgs[0] = msg;

View File

@ -35,7 +35,7 @@ namespace NadekoBot.Modules.Games.Services
private readonly Timer _t;
private readonly CommandHandler _cmd;
private readonly NadekoStrings _strings;
private readonly IImagesService _images;
private readonly IImageCache _images;
private readonly Logger _log;
private readonly NadekoRandom _rng;
private readonly CurrencyService _cs;
@ -57,13 +57,13 @@ namespace NadekoBot.Modules.Games.Services
public ConcurrentDictionary<ulong, Nunchi> NunchiGames { get; } = new ConcurrentDictionary<ulong, Common.Nunchi.Nunchi>();
public GamesService(CommandHandler cmd, IBotConfigProvider bc, NadekoBot bot,
NadekoStrings strings, IImagesService images, CommandHandler cmdHandler,
NadekoStrings strings, IDataCache data, CommandHandler cmdHandler,
CurrencyService cs)
{
_bc = bc;
_cmd = cmd;
_strings = strings;
_images = images;
_images = data.LocalImages;
_cmdHandler = cmdHandler;
_log = LogManager.GetCurrentClassLogger();
_rng = new NadekoRandom();
@ -144,10 +144,11 @@ namespace NadekoBot.Modules.Games.Services
private ConcurrentDictionary<ulong, object> _locks { get; } = new ConcurrentDictionary<ulong, object>();
public ConcurrentHashSet<ulong> HalloweenAwardedUsers { get; } = new ConcurrentHashSet<ulong>();
public (string Name, ImmutableArray<byte> Data) GetRandomCurrencyImage()
public byte[] GetRandomCurrencyImage()
{
var rng = new NadekoRandom();
return _images.Currency[rng.Next(0, _images.Currency.Length)];
var cur = _images.Currency;
return cur[rng.Next(0, cur.Length)];
}
private string GetText(ITextChannel ch, string key, params object[] rep)
@ -195,11 +196,11 @@ namespace NadekoBot.Modules.Games.Services
: GetText(channel, "curgen_pl", dropAmount, _bc.BotConfig.CurrencySign)
+ " " + GetText(channel, "pick_pl", prefix);
var file = GetRandomCurrencyImage();
using (var fileStream = file.Data.ToStream())
using (var fileStream = file.ToStream())
{
var sent = await channel.SendFileAsync(
fileStream,
file.Name,
"drop.png",
toSend).ConfigureAwait(false);
msgs[0] = sent;

View File

@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Searches.Services
private readonly IGoogleApiService _google;
private readonly DbService _db;
private readonly Logger _log;
private readonly IImagesService _imgs;
private readonly IImageCache _imgs;
private readonly IDataCache _cache;
private readonly FontProvider _fonts;
private readonly HttpClient http;
@ -60,7 +60,7 @@ namespace NadekoBot.Modules.Searches.Services
private readonly ConcurrentDictionary<ulong, HashSet<string>> _blacklistedTags = new ConcurrentDictionary<ulong, HashSet<string>>();
public SearchesService(DiscordSocketClient client, IGoogleApiService google,
DbService db, NadekoBot bot, IImagesService imgs, IDataCache cache,
DbService db, NadekoBot bot, IDataCache cache,
FontProvider fonts)
{
Http = new HttpClient();
@ -69,7 +69,7 @@ namespace NadekoBot.Modules.Searches.Services
_google = google;
_db = db;
_log = LogManager.GetCurrentClassLogger();
_imgs = imgs;
_imgs = cache.LocalImages;
_cache = cache;
_fonts = fonts;
http = new HttpClient();

View File

@ -19,8 +19,6 @@ using SixLabors.Fonts;
using System.IO;
using SixLabors.Primitives;
using System.Net.Http;
using SixLabors.Shapes;
using System.Numerics;
using ImageSharp.Drawing.Pens;
using ImageSharp.Drawing.Brushes;
@ -33,7 +31,7 @@ namespace NadekoBot.Modules.Xp.Services
private readonly DbService _db;
private readonly CommandHandler _cmd;
private readonly IBotConfigProvider _bc;
private readonly IImagesService _images;
private readonly IImageCache _images;
private readonly Logger _log;
private readonly NadekoStrings _strings;
private readonly IDataCache _cache;
@ -61,14 +59,13 @@ namespace NadekoBot.Modules.Xp.Services
private readonly HttpClient http = new HttpClient();
public XpService(CommandHandler cmd, IBotConfigProvider bc,
NadekoBot bot, IImagesService images,
DbService db, NadekoStrings strings, IDataCache cache,
NadekoBot bot, DbService db, NadekoStrings strings, IDataCache cache,
FontProvider fonts)
{
_db = db;
_cmd = cmd;
_bc = bc;
_images = images;
_images = cache.LocalImages;
_log = LogManager.GetCurrentClassLogger();
_strings = strings;
_cache = cache;

View File

@ -7,6 +7,8 @@ namespace NadekoBot.Core.Services
public interface IDataCache
{
ConnectionMultiplexer Redis { get; }
IImageCache LocalImages { get; }
Task<(bool Success, byte[] Data)> TryGetImageDataAsync(string key);
Task<(bool Success, string Data)> TryGetAnimeDataAsync(string key);
Task<(bool Success, string Data)> TryGetNovelDataAsync(string key);

View File

@ -0,0 +1,27 @@
using System.Collections.Immutable;
namespace NadekoBot.Core.Services
{
public interface IImageCache
{
byte[] Heads { get; }
byte[] Tails { get; }
byte[][] Currency { get; }
byte[][] Dice { get; }
byte[] SlotBackground { get; }
byte[][] SlotEmojis { get; }
byte[][] SlotNumbers { get; }
byte[] WifeMatrix { get; }
byte[] RategirlDot { get; }
byte[] XpCard { get; }
byte[] Rip { get; }
byte[] FlowerCircle { get; }
void Reload();
}
}

View File

@ -1,27 +0,0 @@
using System.Collections.Immutable;
namespace NadekoBot.Core.Services
{
public interface IImagesService : INService
{
ImmutableArray<byte> Heads { get; }
ImmutableArray<byte> Tails { get; }
ImmutableArray<(string, ImmutableArray<byte>)> Currency { get; }
ImmutableArray<ImmutableArray<byte>> Dice { get; }
ImmutableArray<byte> SlotBackground { get; }
ImmutableArray<ImmutableArray<byte>> SlotEmojis { get; }
ImmutableArray<ImmutableArray<byte>> SlotNumbers { get; }
ImmutableArray<byte> WifeMatrix { get; }
ImmutableArray<byte> RategirlDot { get; }
ImmutableArray<byte> XpCard { get; }
ImmutableArray<byte> Rip { get; }
ImmutableArray<byte> FlowerCircle { get; }
void Reload();
}
}

View File

@ -1,17 +1,22 @@
using NLog;
using NadekoBot.Extensions;
using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
namespace NadekoBot.Core.Services.Impl
{
//todo move everything to redis
public class ImagesService : IImagesService
public class RedisImagesCache : IImageCache
{
private readonly IDataCache _cache;
private readonly ConnectionMultiplexer _con;
private readonly IBotCredentials _creds;
private readonly Logger _log;
private IDatabase _db => _con.GetDatabase();
private const string _basePath = "data/images/";
private const string _headsPath = _basePath + "coins/heads.png";
@ -32,71 +37,189 @@ namespace NadekoBot.Core.Services.Impl
private const string _ripPath = _basePath + "rip/rip.png";
private const string _ripFlowersPath = _basePath + "rip/rose_overlay.png";
public ImmutableArray<byte> Heads { get; private set; }
public ImmutableArray<byte> Tails { get; private set; }
public ImmutableArray<(string, ImmutableArray<byte>)> Currency { get; private set; }
public ImmutableArray<ImmutableArray<byte>> Dice { get; private set; }
public ImmutableArray<byte> SlotBackground { get; private set; }
public ImmutableArray<ImmutableArray<byte>> SlotNumbers { get; private set; }
public ImmutableArray<ImmutableArray<byte>> SlotEmojis { get; private set; }
public ImmutableArray<byte> WifeMatrix { get; private set; }
public ImmutableArray<byte> RategirlDot { get; private set; }
public ImmutableArray<byte> XpCard { get; private set; }
public ImmutableArray<byte> Rip { get; private set; }
public ImmutableArray<byte> FlowerCircle { get; private set; }
public ImagesService(IDataCache cache, int shardId)
public byte[] Heads
{
_cache = cache;
_log = LogManager.GetCurrentClassLogger();
if (shardId == 0)
get
{
this.Reload();
return Get<byte[]>("heads");
}
set
{
Set("heads", value);
}
}
public byte[] Tails
{
get
{
return Get<byte[]>("tails");
}
set
{
Set("tails", value);
}
}
public byte[][] Currency
{
get
{
return Get<byte[][]>("currency");
}
set
{
Set("currency", value);
}
}
public byte[][] Dice
{
get
{
return Get<byte[][]>("dice");
}
set
{
Set("dice", value);
}
}
public byte[] SlotBackground
{
get
{
return Get<byte[]>("slot_background");
}
set
{
Set("slot_background", value);
}
}
public byte[][] SlotNumbers
{
get
{
return Get<byte[][]>("slotnumbers");
}
set
{
Set("slotnumbers", value);
}
}
public byte[][] SlotEmojis
{
get
{
return Get<byte[][]>("slotemojis");
}
set
{
Set("slotemojis", value);
}
}
public byte[] WifeMatrix
{
get
{
return Get<byte[]>("wife_matrix");
}
set
{
Set("wife_matrix", value);
}
}
public byte[] RategirlDot
{
get
{
return Get<byte[]>("rategirl_dot");
}
set
{
Set("rategirl_dot", value);
}
}
public byte[] XpCard
{
get
{
return Get<byte[]>("xp_card");
}
set
{
Set("xp_card", value);
}
}
public byte[] Rip
{
get
{
return Get<byte[]>("rip");
}
set
{
Set("rip", value);
}
}
public byte[] FlowerCircle
{
get
{
return Get<byte[]>("flower_circle");
}
set
{
Set("flower_circle", value);
}
}
public RedisImagesCache(ConnectionMultiplexer con, IBotCredentials creds)
{
_con = con;
_creds = creds;
_log = LogManager.GetCurrentClassLogger();
}
public void Reload()
{
try
{
Heads = File.ReadAllBytes(_headsPath).ToImmutableArray();
Tails = File.ReadAllBytes(_tailsPath).ToImmutableArray();
Heads = File.ReadAllBytes(_headsPath);
Tails = File.ReadAllBytes(_tailsPath);
Currency = Directory.GetFiles(_currencyImagesPath)
.Select(x => (Path.GetFileName(x), File.ReadAllBytes(x).ToImmutableArray()))
.ToImmutableArray();
.Select(x => File.ReadAllBytes(x))
.ToArray();
Dice = Directory.GetFiles(_diceImagesPath)
.OrderBy(x => int.Parse(Path.GetFileNameWithoutExtension(x)))
.Select(x => File.ReadAllBytes(x).ToImmutableArray())
.ToImmutableArray();
.Select(x => File.ReadAllBytes(x))
.ToArray();
SlotBackground = File.ReadAllBytes(_slotBackgroundPath).ToImmutableArray();
SlotBackground = File.ReadAllBytes(_slotBackgroundPath);
SlotNumbers = Directory.GetFiles(_slotNumbersPath)
.OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f)))
.Select(x => File.ReadAllBytes(x).ToImmutableArray())
.ToImmutableArray();
.Select(x => File.ReadAllBytes(x))
.ToArray();
SlotEmojis = Directory.GetFiles(_slotEmojisPath)
.OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f)))
.Select(x => File.ReadAllBytes(x).ToImmutableArray())
.ToImmutableArray();
.Select(x => File.ReadAllBytes(x))
.ToArray();
WifeMatrix = File.ReadAllBytes(_wifeMatrixPath).ToImmutableArray();
RategirlDot = File.ReadAllBytes(_rategirlDot).ToImmutableArray();
WifeMatrix = File.ReadAllBytes(_wifeMatrixPath);
RategirlDot = File.ReadAllBytes(_rategirlDot);
XpCard = File.ReadAllBytes(_xpCardPath).ToImmutableArray();
XpCard = File.ReadAllBytes(_xpCardPath);
Rip = File.ReadAllBytes(_ripPath).ToImmutableArray();
FlowerCircle = File.ReadAllBytes(_ripFlowersPath).ToImmutableArray();
Rip = File.ReadAllBytes(_ripPath);
FlowerCircle = File.ReadAllBytes(_ripFlowersPath);
}
catch (Exception ex)
{
@ -104,5 +227,15 @@ namespace NadekoBot.Core.Services.Impl
throw;
}
}
private T Get<T>(string key) where T : class
{
return JsonConvert.DeserializeObject<T>(_db.StringGet($"{_creds.RedisKey()}_localimg_{key}"));
}
private void Set(string key, object obj)
{
_db.StringSet($"{_creds.RedisKey()}_localimg_{key}", JsonConvert.SerializeObject(obj));
}
}
}

View File

@ -9,6 +9,9 @@ namespace NadekoBot.Core.Services.Impl
public class RedisCache : IDataCache
{
public ConnectionMultiplexer Redis { get; }
public IImageCache LocalImages { get; }
private readonly IDatabase _db;
private readonly string _redisKey;
@ -16,6 +19,7 @@ namespace NadekoBot.Core.Services.Impl
{
Redis = ConnectionMultiplexer.Connect("127.0.0.1");
Redis.PreserveAsyncOrder = false;
LocalImages = new RedisImagesCache(Redis, creds);
_db = Redis.GetDatabase();
_redisKey = creds.RedisKey();
}

View File

@ -72,6 +72,8 @@ namespace NadekoBot.Core.Services
_key = _creds.RedisKey();
_redis = ConnectionMultiplexer.Connect("127.0.0.1");
new RedisImagesCache(_redis, _creds).Reload(); //reload images into redis
//setup initial shard statuses
_defaultShardState = new ShardComMessage()
{