Global custom reactions now use redis pub/sub

This commit is contained in:
Master Kwoth 2017-09-13 03:12:40 +02:00
parent 438f68cde7
commit a2c4695557
5 changed files with 51 additions and 11 deletions

View File

@ -58,8 +58,7 @@ namespace NadekoBot.Modules.CustomReactions
if (channel == null)
{
Array.Resize(ref _service.GlobalReactions, _service.GlobalReactions.Length + 1);
_service.GlobalReactions[_service.GlobalReactions.Length - 1] = cr;
await _service.AddGcr(cr).ConfigureAwait(false);
}
else
{
@ -237,8 +236,7 @@ namespace NadekoBot.Modules.CustomReactions
if ((toDelete.GuildId == null || toDelete.GuildId == 0) && Context.Guild == null)
{
uow.CustomReactions.Remove(toDelete);
//todo 91 i can dramatically improve performance of this, if Ids are ordered.
_service.GlobalReactions = _service.GlobalReactions.Where(cr => cr?.Id != toDelete.Id).ToArray();
await _service.DelGcr(toDelete.Id);
success = true;
}
else if ((toDelete.GuildId != null && toDelete.GuildId != 0) && Context.Guild.Id == toDelete.GuildId)

View File

@ -15,6 +15,7 @@ using NadekoBot.Modules.CustomReactions.Extensions;
using NadekoBot.Modules.Permissions.Common;
using NadekoBot.Modules.Permissions.Services;
using NadekoBot.Services.Impl;
using Newtonsoft.Json;
namespace NadekoBot.Modules.CustomReactions.Services
{
@ -32,9 +33,11 @@ namespace NadekoBot.Modules.CustomReactions.Services
private readonly CommandHandler _cmd;
private readonly IBotConfigProvider _bc;
private readonly NadekoStrings _strings;
private readonly IDataCache _cache;
public CustomReactionsService(PermissionService perms, DbService db, NadekoStrings strings,
DiscordSocketClient client, CommandHandler cmd, IBotConfigProvider bc, IUnitOfWork uow)
DiscordSocketClient client, CommandHandler cmd, IBotConfigProvider bc, IUnitOfWork uow,
IDataCache cache)
{
_log = LogManager.GetCurrentClassLogger();
_db = db;
@ -43,10 +46,42 @@ namespace NadekoBot.Modules.CustomReactions.Services
_cmd = cmd;
_bc = bc;
_strings = strings;
_cache = cache;
var sub = _cache.Redis.GetSubscriber();
sub.Subscribe("gcr.added", (ch, msg) =>
{
Array.Resize(ref GlobalReactions, GlobalReactions.Length + 1);
GlobalReactions[GlobalReactions.Length - 1] = JsonConvert.DeserializeObject<CustomReaction>(msg);
}, StackExchange.Redis.CommandFlags.FireAndForget);
sub.Subscribe("gcr.deleted", (ch, msg) =>
{
var id = int.Parse(msg);
GlobalReactions = GlobalReactions.Where(cr => cr?.Id != id).ToArray();
}, StackExchange.Redis.CommandFlags.FireAndForget);
var items = uow.CustomReactions.GetAll();
GuildReactions = new ConcurrentDictionary<ulong, CustomReaction[]>(items.Where(g => g.GuildId != null && g.GuildId != 0).GroupBy(k => k.GuildId.Value).ToDictionary(g => g.Key, g => g.ToArray()));
GlobalReactions = items.Where(g => g.GuildId == null || g.GuildId == 0).ToArray();
foreach (var item in items)
{
_log.Info(item.Id);
_log.Info(item.Trigger);
_log.Info(item.GuildId);
}
}
public Task AddGcr(CustomReaction cr)
{
var sub = _cache.Redis.GetSubscriber();
return sub.PublishAsync("gcr.added", JsonConvert.SerializeObject(cr));
}
public Task DelGcr(int id)
{
var sub = _cache.Redis.GetSubscriber();
return sub.PublishAsync("gcr.deleted", id);
}
public void ClearStats() => ReactionStats.Clear();

View File

@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations.Schema;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.RegularExpressions;
namespace NadekoBot.Services.Database.Models
@ -6,7 +7,9 @@ namespace NadekoBot.Services.Database.Models
public class CustomReaction : DbEntity
{
public ulong? GuildId { get; set; }
[NotMapped]
[JsonIgnore]
public Regex Regex { get; set; }
public string Response { get; set; }
public string Trigger { get; set; }
@ -16,6 +19,7 @@ namespace NadekoBot.Services.Database.Models
public bool AutoDeleteTrigger { get; set; }
public bool DmResponse { get; set; }
[JsonIgnore]
public bool IsGlobal => !GuildId.HasValue;
public bool ContainsAnywhere { get; set; }

View File

@ -1,4 +1,5 @@
using System;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,6 +9,7 @@ namespace NadekoBot.Services
{
public interface IDataCache
{
ConnectionMultiplexer Redis { get; }
Task<(bool Success, byte[] Data)> TryGetImageDataAsync(string key);
Task SetImageDataAsync(string key, byte[] data);
}

View File

@ -5,13 +5,14 @@ namespace NadekoBot.Services.Impl
{
public class RedisCache : IDataCache
{
private readonly ConnectionMultiplexer _redis;
public ConnectionMultiplexer Redis { get; }
private readonly IDatabase _db;
public RedisCache()
{
_redis = ConnectionMultiplexer.Connect("localhost");
_db = _redis.GetDatabase();
Redis = ConnectionMultiplexer.Connect("localhost");
Redis.PreserveAsyncOrder = false;
_db = Redis.GetDatabase();
}
public async Task<(bool Success, byte[] Data)> TryGetImageDataAsync(string key)