Using redis to cache avatar images, reduced xp image size.
This commit is contained in:
parent
90b698f18e
commit
46f9de01d6
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26430.12
|
VisualStudioVersion = 15.0.26730.3
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}"
|
||||||
EndProject
|
EndProject
|
||||||
@ -33,4 +33,7 @@ Global
|
|||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{45EC1473-C678-4857-A544-07DFE0D0B478} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
{45EC1473-C678-4857-A544-07DFE0D0B478} = {04929013-5BAB-42B0-B9B2-8F2BB8F16AF2}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {5F3F555C-855F-4BE8-B526-D062D3E8ACA4}
|
||||||
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -36,6 +36,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
private readonly IImagesService _images;
|
private readonly IImagesService _images;
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
private readonly NadekoStrings _strings;
|
private readonly NadekoStrings _strings;
|
||||||
|
private readonly IDataCache _cache;
|
||||||
private readonly FontCollection _fonts = new FontCollection();
|
private readonly FontCollection _fonts = new FontCollection();
|
||||||
public const int XP_REQUIRED_LVL_1 = 36;
|
public const int XP_REQUIRED_LVL_1 = 36;
|
||||||
|
|
||||||
@ -54,9 +55,6 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
private readonly ConcurrentQueue<UserCacheItem> _addMessageXp
|
private readonly ConcurrentQueue<UserCacheItem> _addMessageXp
|
||||||
= new ConcurrentQueue<UserCacheItem>();
|
= new ConcurrentQueue<UserCacheItem>();
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, byte[]> _imageStreams
|
|
||||||
= new ConcurrentDictionary<string, byte[]>();
|
|
||||||
|
|
||||||
private readonly Timer updateXpTimer;
|
private readonly Timer updateXpTimer;
|
||||||
private readonly HttpClient http = new HttpClient();
|
private readonly HttpClient http = new HttpClient();
|
||||||
private FontFamily _usernameFontFamily;
|
private FontFamily _usernameFontFamily;
|
||||||
@ -69,7 +67,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
|
|
||||||
public XpService(CommandHandler cmd, IBotConfigProvider bc,
|
public XpService(CommandHandler cmd, IBotConfigProvider bc,
|
||||||
IEnumerable<GuildConfig> allGuildConfigs, IImagesService images,
|
IEnumerable<GuildConfig> allGuildConfigs, IImagesService images,
|
||||||
DbService db, NadekoStrings strings)
|
DbService db, NadekoStrings strings, IDataCache cache)
|
||||||
{
|
{
|
||||||
_db = db;
|
_db = db;
|
||||||
_cmd = cmd;
|
_cmd = cmd;
|
||||||
@ -77,6 +75,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
_images = images;
|
_images = images;
|
||||||
_log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
_strings = strings;
|
_strings = strings;
|
||||||
|
_cache = cache;
|
||||||
|
|
||||||
//load settings
|
//load settings
|
||||||
allGuildConfigs = allGuildConfigs.Where(x => x.XpSettings != null);
|
allGuildConfigs = allGuildConfigs.Where(x => x.XpSettings != null);
|
||||||
@ -665,20 +664,20 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
{
|
{
|
||||||
var avatarUrl = stats.User.RealAvatarUrl();
|
var avatarUrl = stats.User.RealAvatarUrl();
|
||||||
|
|
||||||
byte[] s;
|
var (succ, data) = await _cache.TryGetImageDataAsync(avatarUrl);
|
||||||
if (!_imageStreams.TryGetValue(avatarUrl, out s))
|
if (!succ)
|
||||||
{
|
{
|
||||||
using (var temp = await http.GetStreamAsync(avatarUrl))
|
using (var temp = await http.GetStreamAsync(avatarUrl))
|
||||||
{
|
{
|
||||||
var tempDraw = Image.Load(temp);
|
var tempDraw = Image.Load(temp);
|
||||||
tempDraw = tempDraw.Resize(69, 70);
|
tempDraw = tempDraw.Resize(69, 70);
|
||||||
ApplyRoundedCorners(tempDraw, 35);
|
ApplyRoundedCorners(tempDraw, 35);
|
||||||
s = tempDraw.ToStream().ToArray();
|
data = tempDraw.ToStream().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
_imageStreams.AddOrUpdate(avatarUrl, s, (k, v) => s);
|
await _cache.SetImageDataAsync(avatarUrl, data);
|
||||||
}
|
}
|
||||||
var toDraw = Image.Load(s);
|
var toDraw = Image.Load(data);
|
||||||
|
|
||||||
|
|
||||||
img.DrawImage(toDraw,
|
img.DrawImage(toDraw,
|
||||||
@ -699,20 +698,20 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
var imgUrl = stats.User.Club.ImageUrl;
|
var imgUrl = stats.User.Club.ImageUrl;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
byte[] s;
|
var (succ, data) = await _cache.TryGetImageDataAsync(imgUrl);
|
||||||
if (!_imageStreams.TryGetValue(imgUrl, out s))
|
if (!succ)
|
||||||
{
|
{
|
||||||
using (var temp = await http.GetStreamAsync(imgUrl))
|
using (var temp = await http.GetStreamAsync(imgUrl))
|
||||||
{
|
{
|
||||||
var tempDraw = Image.Load(temp);
|
var tempDraw = Image.Load(temp);
|
||||||
tempDraw = tempDraw.Resize(45, 45);
|
tempDraw = tempDraw.Resize(45, 45);
|
||||||
ApplyRoundedCorners(tempDraw, 22.5f);
|
ApplyRoundedCorners(tempDraw, 22.5f);
|
||||||
s = tempDraw.ToStream().ToArray();
|
data = tempDraw.ToStream().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
_imageStreams.AddOrUpdate(imgUrl, s, (k, v) => s);
|
await _cache.SetImageDataAsync(imgUrl, data);
|
||||||
}
|
}
|
||||||
var toDraw = Image.Load(s);
|
var toDraw = Image.Load(data);
|
||||||
|
|
||||||
img.DrawImage(toDraw,
|
img.DrawImage(toDraw,
|
||||||
1,
|
1,
|
||||||
@ -724,7 +723,7 @@ namespace NadekoBot.Modules.Xp.Services
|
|||||||
_log.Warn(ex);
|
_log.Warn(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
img.Resize(432, 211);
|
||||||
var arr = img.ToStream().ToArray();
|
var arr = img.ToStream().ToArray();
|
||||||
|
|
||||||
//_log.Info("{0:F2} KB", arr.Length * 1.0f / 1.KB());
|
//_log.Info("{0:F2} KB", arr.Length * 1.0f / 1.KB());
|
||||||
|
@ -26,12 +26,16 @@ namespace NadekoBot.Modules.Xp
|
|||||||
public async Task Experience([Remainder]IUser user = null)
|
public async Task Experience([Remainder]IUser user = null)
|
||||||
{
|
{
|
||||||
user = user ?? Context.User;
|
user = user ?? Context.User;
|
||||||
|
var sw = Stopwatch.StartNew();
|
||||||
await Context.Channel.TriggerTypingAsync();
|
await Context.Channel.TriggerTypingAsync();
|
||||||
var img = await _service.GenerateImageAsync((IGuildUser)user);
|
var img = await _service.GenerateImageAsync((IGuildUser)user);
|
||||||
|
sw.Stop();
|
||||||
|
_log.Info("Generating finished in {0:F2}s", sw.Elapsed.TotalSeconds);
|
||||||
|
sw.Restart();
|
||||||
await Context.Channel.SendFileAsync(img.ToStream(), $"{user.Id}_xp.png")
|
await Context.Channel.SendFileAsync(img.ToStream(), $"{user.Id}_xp.png")
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
sw.Stop();
|
||||||
|
_log.Info("Sending finished in {0:F2}s", sw.Elapsed.TotalSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
@ -139,6 +139,7 @@ namespace NadekoBot
|
|||||||
.AddManual<IEnumerable<GuildConfig>>(AllGuildConfigs) //todo wrap this
|
.AddManual<IEnumerable<GuildConfig>>(AllGuildConfigs) //todo wrap this
|
||||||
.AddManual<NadekoBot>(this)
|
.AddManual<NadekoBot>(this)
|
||||||
.AddManual<IUnitOfWork>(uow)
|
.AddManual<IUnitOfWork>(uow)
|
||||||
|
.AddManual<IDataCache>(new RedisCache())
|
||||||
.LoadFrom(Assembly.GetEntryAssembly())
|
.LoadFrom(Assembly.GetEntryAssembly())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<FileVersion>1.0.0.0</FileVersion>
|
<FileVersion>1.0.0.0</FileVersion>
|
||||||
<ApplicationIcon>nadeko_icon.ico</ApplicationIcon>
|
<ApplicationIcon>nadeko_icon.ico</ApplicationIcon>
|
||||||
<RuntimeIdentifiers>win7-x64<!--;ubuntu.14.04-x64;osx.10.10-x64 --></RuntimeIdentifiers>
|
<RuntimeIdentifiers>win7-x64<!--;ubuntu.14.04-x64;osx.10.10-x64 --></RuntimeIdentifiers>
|
||||||
|
<Configurations>Debug;Release;global_nadeko</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Version)' == '' ">
|
<PropertyGroup Condition=" '$(Version)' == '' ">
|
||||||
@ -78,6 +79,7 @@
|
|||||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
|
||||||
<PackageReference Include="NLog" Version="5.0.0-beta03" />
|
<PackageReference Include="NLog" Version="5.0.0-beta03" />
|
||||||
<PackageReference Include="NYoutubeDL" Version="0.4.4" />
|
<PackageReference Include="NYoutubeDL" Version="0.4.4" />
|
||||||
|
<PackageReference Include="StackExchange.Redis" Version="1.2.6" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.4.0-preview1-25305-02" />
|
<PackageReference Include="System.ValueTuple" Version="4.4.0-preview1-25305-02" />
|
||||||
<PackageReference Include="System.Xml.XPath" Version="4.3.0" />
|
<PackageReference Include="System.Xml.XPath" Version="4.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -95,6 +97,10 @@
|
|||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='global_nadeko|AnyCPU'">
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
|
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
|
||||||
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0" />
|
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0" />
|
||||||
|
14
src/NadekoBot/Services/IDataCache.cs
Normal file
14
src/NadekoBot/Services/IDataCache.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Services
|
||||||
|
{
|
||||||
|
public interface IDataCache
|
||||||
|
{
|
||||||
|
Task<(bool Success, byte[] Data)> TryGetImageDataAsync(string key);
|
||||||
|
Task SetImageDataAsync(string key, byte[] data);
|
||||||
|
}
|
||||||
|
}
|
28
src/NadekoBot/Services/Impl/RedisCache.cs
Normal file
28
src/NadekoBot/Services/Impl/RedisCache.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using StackExchange.Redis;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Services.Impl
|
||||||
|
{
|
||||||
|
public class RedisCache : IDataCache
|
||||||
|
{
|
||||||
|
private readonly ConnectionMultiplexer _redis;
|
||||||
|
private readonly IDatabase _db;
|
||||||
|
|
||||||
|
public RedisCache()
|
||||||
|
{
|
||||||
|
_redis = ConnectionMultiplexer.Connect("localhost");
|
||||||
|
_db = _redis.GetDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(bool Success, byte[] Data)> TryGetImageDataAsync(string key)
|
||||||
|
{
|
||||||
|
byte[] x = await _db.StringGetAsync("image_" + key);
|
||||||
|
return (x != null, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task SetImageDataAsync(string key, byte[] data)
|
||||||
|
{
|
||||||
|
return _db.StringSetAsync("image_" + key, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user