2017-10-26 09:31:44 +00:00
|
|
|
|
using NadekoBot.Extensions;
|
|
|
|
|
using StackExchange.Redis;
|
|
|
|
|
using System;
|
2017-09-12 20:27:51 +00:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
2017-10-13 04:14:54 +00:00
|
|
|
|
namespace NadekoBot.Core.Services.Impl
|
2017-09-12 20:27:51 +00:00
|
|
|
|
{
|
|
|
|
|
public class RedisCache : IDataCache
|
|
|
|
|
{
|
2017-09-13 01:12:40 +00:00
|
|
|
|
public ConnectionMultiplexer Redis { get; }
|
2017-11-05 12:28:08 +00:00
|
|
|
|
|
|
|
|
|
public IImageCache LocalImages { get; }
|
2017-11-06 09:01:38 +00:00
|
|
|
|
public ILocalDataCache LocalData { get; }
|
2017-11-05 12:28:08 +00:00
|
|
|
|
|
2017-09-12 20:27:51 +00:00
|
|
|
|
private readonly IDatabase _db;
|
2017-10-26 09:31:44 +00:00
|
|
|
|
private readonly string _redisKey;
|
2017-09-12 20:27:51 +00:00
|
|
|
|
|
2017-10-26 09:31:44 +00:00
|
|
|
|
public RedisCache(IBotCredentials creds)
|
2017-09-12 20:27:51 +00:00
|
|
|
|
{
|
2017-09-14 17:37:41 +00:00
|
|
|
|
Redis = ConnectionMultiplexer.Connect("127.0.0.1");
|
2017-09-13 01:12:40 +00:00
|
|
|
|
Redis.PreserveAsyncOrder = false;
|
2017-11-05 12:28:08 +00:00
|
|
|
|
LocalImages = new RedisImagesCache(Redis, creds);
|
2017-11-06 09:01:38 +00:00
|
|
|
|
LocalData = new RedisLocalDataCache(Redis, creds);
|
2017-09-13 01:12:40 +00:00
|
|
|
|
_db = Redis.GetDatabase();
|
2017-10-26 09:31:44 +00:00
|
|
|
|
_redisKey = creds.RedisKey();
|
2017-09-12 20:27:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-10-09 22:04:02 +00:00
|
|
|
|
// things here so far don't need the bot id
|
|
|
|
|
// because it's a good thing if different bots
|
|
|
|
|
// which are hosted on the same PC
|
|
|
|
|
// can re-use the same image/anime data
|
2017-09-12 20:27:51 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
2017-09-15 00:42:51 +00:00
|
|
|
|
|
|
|
|
|
public async Task<(bool Success, string Data)> TryGetAnimeDataAsync(string key)
|
|
|
|
|
{
|
|
|
|
|
string x = await _db.StringGetAsync("anime_" + key);
|
|
|
|
|
return (x != null, x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task SetAnimeDataAsync(string key, string data)
|
|
|
|
|
{
|
|
|
|
|
return _db.StringSetAsync("anime_" + key, data);
|
|
|
|
|
}
|
2017-10-26 09:31:44 +00:00
|
|
|
|
|
2017-11-02 17:22:17 +00:00
|
|
|
|
public async Task<(bool Success, string Data)> TryGetNovelDataAsync(string key)
|
|
|
|
|
{
|
|
|
|
|
string x = await _db.StringGetAsync("novel_" + key);
|
|
|
|
|
return (x != null, x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task SetNovelDataAsync(string key, string data)
|
|
|
|
|
{
|
|
|
|
|
return _db.StringSetAsync("novel_" + key, data);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-26 09:31:44 +00:00
|
|
|
|
private readonly object timelyLock = new object();
|
|
|
|
|
public TimeSpan? AddTimelyClaim(ulong id, int period)
|
|
|
|
|
{
|
2017-10-26 11:03:53 +00:00
|
|
|
|
if (period == 0)
|
|
|
|
|
return null;
|
2017-10-26 09:31:44 +00:00
|
|
|
|
lock (timelyLock)
|
|
|
|
|
{
|
|
|
|
|
var time = TimeSpan.FromHours(period);
|
|
|
|
|
if ((bool?)_db.StringGet($"{_redisKey}_timelyclaim_{id}") == null)
|
|
|
|
|
{
|
2017-11-06 09:20:24 +00:00
|
|
|
|
_db.StringSet($"{_redisKey}_timelyclaim_{id}", true, time);
|
2017-10-26 11:03:53 +00:00
|
|
|
|
return null;
|
2017-10-26 09:31:44 +00:00
|
|
|
|
}
|
|
|
|
|
return _db.KeyTimeToLive($"{_redisKey}_timelyclaim_{id}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-26 11:03:53 +00:00
|
|
|
|
|
|
|
|
|
public void RemoveAllTimelyClaims()
|
|
|
|
|
{
|
|
|
|
|
var server = Redis.GetServer("127.0.0.1", 6379);
|
|
|
|
|
foreach (var k in server.Keys(pattern: $"{_redisKey}_timelyclaim_*"))
|
|
|
|
|
{
|
|
|
|
|
_db.KeyDelete(k, CommandFlags.FireAndForget);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-03 11:35:27 +00:00
|
|
|
|
|
|
|
|
|
public bool TryAddAffinityCooldown(ulong userId, out TimeSpan? time)
|
|
|
|
|
{
|
|
|
|
|
time = _db.KeyTimeToLive($"{_redisKey}_affinity_{userId}");
|
|
|
|
|
if (time == null)
|
|
|
|
|
{
|
|
|
|
|
time = TimeSpan.FromMinutes(30);
|
2017-11-06 09:20:24 +00:00
|
|
|
|
_db.StringSet($"{_redisKey}_affinity_{userId}", true, time);
|
2017-11-03 11:35:27 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2017-11-03 11:46:51 +00:00
|
|
|
|
|
|
|
|
|
public bool TryAddDivorceCooldown(ulong userId, out TimeSpan? time)
|
|
|
|
|
{
|
|
|
|
|
time = _db.KeyTimeToLive($"{_redisKey}_divorce_{userId}");
|
|
|
|
|
if (time == null)
|
|
|
|
|
{
|
|
|
|
|
time = TimeSpan.FromHours(6);
|
2017-11-06 09:20:24 +00:00
|
|
|
|
_db.StringSet($"{_redisKey}_divorce_{userId}", true, time);
|
2017-11-03 11:46:51 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2017-09-12 20:27:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|