1
Fork 0
mirror of https://gitlab.com/Kwoth/nadekobot.git synced 2024-10-02 20:13:13 +00:00

IPubSub subs will now use valuetask, as almost no subscriptions actually await anything

This commit is contained in:
Kwoth 2021-05-19 12:14:29 +02:00
parent de3d9ecbe3
commit 0ec70646f8
6 changed files with 33 additions and 29 deletions

View file

@ -17,7 +17,7 @@ namespace Nadeko.Tests
{ {
Assert.AreEqual(expected, data); Assert.AreEqual(expected, data);
Assert.Pass(); Assert.Pass();
return Task.CompletedTask; return default;
}); });
await pubsub.Pub(key, expected); await pubsub.Pub(key, expected);
Assert.Fail("Event not registered"); Assert.Fail("Event not registered");
@ -33,9 +33,9 @@ namespace Nadeko.Tests
{ {
Assert.AreEqual(expected, data); Assert.AreEqual(expected, data);
Assert.Pass(); Assert.Pass();
return Task.CompletedTask; return default;
}); });
await pubsub.Unsub(key, _ => Task.CompletedTask); await pubsub.Unsub(key, _ => default);
await pubsub.Pub(key, expected); await pubsub.Pub(key, expected);
Assert.Fail("Event not registered"); Assert.Fail("Event not registered");
} }
@ -50,13 +50,13 @@ namespace Nadeko.Tests
{ {
Assert.AreEqual(expected, data); Assert.AreEqual(expected, data);
Assert.Pass(); Assert.Pass();
return Task.CompletedTask; return default;
}); });
await pubsub.Unsub(key, data => await pubsub.Unsub(key, data =>
{ {
Assert.AreEqual(expected, data); Assert.AreEqual(expected, data);
Assert.Pass(); Assert.Pass();
return Task.CompletedTask; return default;
}); });
await pubsub.Pub(key, expected); await pubsub.Pub(key, expected);
Assert.Fail("Event not registered"); Assert.Fail("Event not registered");
@ -68,10 +68,10 @@ namespace Nadeko.Tests
TypedKey<int> key = "test_key"; TypedKey<int> key = "test_key";
var pubsub = new EventPubSub(); var pubsub = new EventPubSub();
Task Action(int data) ValueTask Action(int data)
{ {
Assert.Fail("Event is raised when it shouldn't be"); Assert.Fail("Event is raised when it shouldn't be");
return Task.CompletedTask; return default;
} }
await pubsub.Sub(key, Action); await pubsub.Sub(key, Action);
@ -88,11 +88,11 @@ namespace Nadeko.Tests
var localData = new byte[1]; var localData = new byte[1];
Task Action(byte[] data) ValueTask Action(byte[] data)
{ {
Assert.AreEqual(localData, data); Assert.AreEqual(localData, data);
Assert.Pass(); Assert.Pass();
return Task.CompletedTask; return default;
} }
await pubsub.Sub(key, Action); await pubsub.Sub(key, Action);
@ -110,18 +110,18 @@ namespace Nadeko.Tests
var localData = new object(); var localData = new object();
int successCounter = 0; int successCounter = 0;
Task Action1(object data) ValueTask Action1(object data)
{ {
Assert.AreEqual(localData, data); Assert.AreEqual(localData, data);
successCounter+=10; successCounter+=10;
return Task.CompletedTask; return default;
} }
Task Action2(object data) ValueTask Action2(object data)
{ {
Assert.AreEqual(localData, data); Assert.AreEqual(localData, data);
successCounter++; successCounter++;
return Task.CompletedTask; return default;
} }
await pubsub.Sub(key, Action1); // + 10 \ await pubsub.Sub(key, Action1); // + 10 \

View file

@ -7,26 +7,26 @@ namespace NadekoBot.Core.Common
{ {
public class EventPubSub : IPubSub public class EventPubSub : IPubSub
{ {
private readonly Dictionary<string, Dictionary<Delegate, List<Func<object, Task>>>> _actions private readonly Dictionary<string, Dictionary<Delegate, List<Func<object, ValueTask>>>> _actions
= new Dictionary<string, Dictionary<Delegate, List<Func<object, Task>>>>(); = new Dictionary<string, Dictionary<Delegate, List<Func<object, ValueTask>>>>();
private readonly object locker = new object(); private readonly object locker = new object();
public Task Sub<TData>(in TypedKey<TData> key, Func<TData, Task> action) public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
{ {
Func<object, Task> localAction = obj => action((TData) obj); Func<object, ValueTask> localAction = obj => action((TData) obj);
lock(locker) lock(locker)
{ {
Dictionary<Delegate, List<Func<object, Task>>> keyActions; Dictionary<Delegate, List<Func<object, ValueTask>>> keyActions;
if (!_actions.TryGetValue(key.Key, out keyActions)) if (!_actions.TryGetValue(key.Key, out keyActions))
{ {
keyActions = new Dictionary<Delegate, List<Func<object, Task>>>(); keyActions = new Dictionary<Delegate, List<Func<object, ValueTask>>>();
_actions[key.Key] = keyActions; _actions[key.Key] = keyActions;
} }
List<Func<object, Task>> sameActions; List<Func<object, ValueTask>> sameActions;
if (!keyActions.TryGetValue(action, out sameActions)) if (!keyActions.TryGetValue(action, out sameActions))
{ {
sameActions = new List<Func<object, Task>>(); sameActions = new List<Func<object, ValueTask>>();
keyActions[action] = sameActions; keyActions[action] = sameActions;
} }
@ -42,16 +42,19 @@ namespace NadekoBot.Core.Common
{ {
if(_actions.TryGetValue(key.Key, out var actions)) if(_actions.TryGetValue(key.Key, out var actions))
{ {
// if this class ever gets used, this needs to be properly implemented
// 1. ignore all valuetasks which are completed
// 2. return task.whenall all other tasks
return Task.WhenAll(actions return Task.WhenAll(actions
.SelectMany(kvp => kvp.Value) .SelectMany(kvp => kvp.Value)
.Select(action => action(data))); .Select(action => action(data).AsTask()));
} }
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
public Task Unsub<TData>(in TypedKey<TData> key, Func<TData, Task> action) public Task Unsub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
{ {
lock (locker) lock (locker)
{ {
@ -88,4 +91,5 @@ namespace NadekoBot.Core.Common
} }
} }
} }
} }

View file

@ -6,6 +6,6 @@ namespace NadekoBot.Core.Common
public interface IPubSub public interface IPubSub
{ {
public Task Pub<TData>(in TypedKey<TData> key, TData data); public Task Pub<TData>(in TypedKey<TData> key, TData data);
public Task Sub<TData>(in TypedKey<TData> key, Func<TData, Task> action); public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action);
} }
} }

View file

@ -28,7 +28,7 @@ namespace NadekoBot.Core.Common
return _multi.GetSubscriber().PublishAsync($"{_creds.RedisKey()}:{key.Key}", serialized, CommandFlags.FireAndForget); return _multi.GetSubscriber().PublishAsync($"{_creds.RedisKey()}:{key.Key}", serialized, CommandFlags.FireAndForget);
} }
public Task Sub<TData>(in TypedKey<TData> key, Func<TData, Task> action) public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
{ {
var eventName = key.Key; var eventName = key.Key;
return _multi.GetSubscriber().SubscribeAsync($"{_creds.RedisKey()}:{eventName}", async (ch, data) => return _multi.GetSubscriber().SubscribeAsync($"{_creds.RedisKey()}:{eventName}", async (ch, data) =>

View file

@ -30,10 +30,10 @@ namespace NadekoBot.Modules.Permissions.Services
_pubSub.Sub(blPubKey, OnReload); _pubSub.Sub(blPubKey, OnReload);
} }
private Task OnReload(BlacklistEntry[] blacklist) private ValueTask OnReload(BlacklistEntry[] blacklist)
{ {
_blacklist = blacklist; _blacklist = blacklist;
return Task.CompletedTask; return default;
} }
public async Task<bool> RunBehavior(DiscordSocketClient _, IGuild guild, IUserMessage usrMsg) public async Task<bool> RunBehavior(DiscordSocketClient _, IGuild guild, IUserMessage usrMsg)

View file

@ -52,11 +52,11 @@ namespace NadekoBot.Core.Services
_pubSub.Pub(_changeKey, _data); _pubSub.Pub(_changeKey, _data);
} }
private Task OnChangePublished(TSettings newData) private ValueTask OnChangePublished(TSettings newData)
{ {
_data = newData; _data = newData;
OnStateUpdate(); OnStateUpdate();
return Task.CompletedTask; return default;
} }
private TSettings CreateCopy() private TSettings CreateCopy()