Fixed some NRT warnings in pub/sub mechanism

This commit is contained in:
Kwoth
2021-12-29 06:59:41 +01:00
parent 82000c97a4
commit 6eee161b6b
5 changed files with 44 additions and 34 deletions

View File

@@ -2,12 +2,13 @@ namespace NadekoBot.Common;
public class EventPubSub : IPubSub public class EventPubSub : IPubSub
{ {
private readonly Dictionary<string, Dictionary<Delegate, List<Func<object?, ValueTask>>>> _actions = new(); private readonly Dictionary<string, Dictionary<Delegate, List<Func<object, ValueTask>>>> _actions = new();
private readonly object _locker = new(); private readonly object _locker = new();
public Task Sub<TData>(in TypedKey<TData> key, Func<TData?, ValueTask> action) public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
where TData: notnull
{ {
Func<object?, ValueTask> localAction = obj => action((TData?)obj); Func<object, ValueTask> localAction = obj => action((TData)obj);
lock (_locker) lock (_locker)
{ {
if (!_actions.TryGetValue(key.Key, out var keyActions)) if (!_actions.TryGetValue(key.Key, out var keyActions))
@@ -29,6 +30,7 @@ public class EventPubSub : IPubSub
} }
public Task Pub<TData>(in TypedKey<TData> key, TData data) public Task Pub<TData>(in TypedKey<TData> key, TData data)
where TData: notnull
{ {
lock (_locker) lock (_locker)
{ {

View File

@@ -2,6 +2,8 @@ namespace NadekoBot.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?, ValueTask> action); where TData: notnull;
public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
where TData: notnull;
} }

View File

@@ -16,13 +16,15 @@ public sealed class RedisPubSub : IPubSub
} }
public Task Pub<TData>(in TypedKey<TData> key, TData data) public Task Pub<TData>(in TypedKey<TData> key, TData data)
where TData : notnull
{ {
var serialized = _serializer.Serialize(data); var serialized = _serializer.Serialize(data);
return _multi.GetSubscriber() return _multi.GetSubscriber()
.PublishAsync($"{_creds.RedisKey()}:{key.Key}", serialized, CommandFlags.FireAndForget); .PublishAsync($"{_creds.RedisKey()}:{key.Key}", serialized, CommandFlags.FireAndForget);
} }
public Task Sub<TData>(in TypedKey<TData> key, Func<TData?, ValueTask> action) public Task Sub<TData>(in TypedKey<TData> key, Func<TData, ValueTask> action)
where TData : notnull
{ {
var eventName = key.Key; var eventName = key.Key;
@@ -31,7 +33,11 @@ public sealed class RedisPubSub : IPubSub
try try
{ {
var dataObj = _serializer.Deserialize<TData>(data); var dataObj = _serializer.Deserialize<TData>(data);
await action(dataObj); if(dataObj is not null)
await action(dataObj);
else
Log.Warning("Publishing event {EventName} with a null value. This is not allowed",
eventName);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -2,25 +2,25 @@ var pid = Environment.ProcessId;
var shardId = 0; var shardId = 0;
int? totalShards = null; // 0 to read from creds.yml int? totalShards = null; // 0 to read from creds.yml
// if (args.Length > 0) if (args.Length > 0 && args[0] != "run")
// { {
// if (!int.TryParse(args[0], out shardId)) if (!int.TryParse(args[0], out shardId))
// { {
// Console.Error.WriteLine("Invalid first argument (shard id): {0}", args[0]); Console.Error.WriteLine("Invalid first argument (shard id): {0}", args[0]);
// return; return;
// } }
//
// if (args.Length > 1) if (args.Length > 1)
// { {
// if (!int.TryParse(args[1], out var shardCount)) if (!int.TryParse(args[1], out var shardCount))
// { {
// Console.Error.WriteLine("Invalid second argument (total shards): {0}", args[1]); Console.Error.WriteLine("Invalid second argument (total shards): {0}", args[1]);
// return; return;
// } }
//
// totalShards = shardCount; totalShards = shardCount;
// } }
// } }
LogSetup.SetupLogger(shardId); LogSetup.SetupLogger(shardId);
Log.Information("Pid: {ProcessId}", pid); Log.Information("Pid: {ProcessId}", pid);

View File

@@ -27,7 +27,7 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
private readonly Dictionary<string, Func<TSettings, string, bool>> _propSetters = new(); private readonly Dictionary<string, Func<TSettings, string, bool>> _propSetters = new();
private readonly Dictionary<string, Func<object>> _propSelectors = new(); private readonly Dictionary<string, Func<object>> _propSelectors = new();
private readonly Dictionary<string, Func<object, string>> _propPrinters = new(); private readonly Dictionary<string, Func<object, string>> _propPrinters = new();
private readonly Dictionary<string, string> _propComments = new(); private readonly Dictionary<string, string?> _propComments = new();
/// <summary> /// <summary>
/// Initialized an instance of <see cref="ConfigServiceBase{TSettings}" /> /// Initialized an instance of <see cref="ConfigServiceBase{TSettings}" />
@@ -106,12 +106,12 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
Expression<Func<TSettings, TProp>> selector, Expression<Func<TSettings, TProp>> selector,
SettingParser<TProp> parser, SettingParser<TProp> parser,
Func<TProp, string> printer, Func<TProp, string> printer,
Func<TProp, bool> checker = null) Func<TProp, bool>? checker = null)
{ {
checker ??= _ => true; checker ??= _ => true;
key = key.ToLowerInvariant(); key = key.ToLowerInvariant();
_propPrinters[key] = obj => printer((TProp)obj); _propPrinters[key] = obj => printer((TProp)obj);
_propSelectors[key] = () => selector.Compile()(data); _propSelectors[key] = () => selector.Compile()(data)!;
_propSetters[key] = Magic(selector, parser, checker); _propSetters[key] = Magic(selector, parser, checker);
_propComments[key] = ((MemberExpression)selector.Body).Member.GetCustomAttribute<CommentAttribute>()?.Comment; _propComments[key] = ((MemberExpression)selector.Body).Member.GetCustomAttribute<CommentAttribute>()?.Comment;
} }
@@ -146,26 +146,26 @@ public abstract class ConfigServiceBase<TSettings> : IConfigService
foreach (var memberExpression in expressions.AsEnumerable().Reverse()) foreach (var memberExpression in expressions.AsEnumerable().Reverse())
{ {
var localProp = (PropertyInfo)memberExpression.Member; var localProp = (PropertyInfo)memberExpression.Member;
targetObject = localProp.GetValue(targetObject); targetObject = localProp.GetValue(targetObject)!;
} }
prop!.SetValue(targetObject, value, null); prop.SetValue(targetObject, value, null);
return true; return true;
}; };
public IReadOnlyList<string> GetSettableProps() public IReadOnlyList<string> GetSettableProps()
=> _propSetters.Keys.ToList(); => _propSetters.Keys.ToList();
public string GetSetting(string prop) public string? GetSetting(string prop)
{ {
prop = prop.ToLowerInvariant(); prop = prop.ToLowerInvariant();
if (!_propSelectors.TryGetValue(prop, out var selector) || !_propPrinters.TryGetValue(prop, out var printer)) if (!_propSelectors.TryGetValue(prop, out var selector) || !_propPrinters.TryGetValue(prop, out var printer))
return default; return null;
return printer(selector()); return printer(selector());
} }
public string GetComment(string prop) public string? GetComment(string prop)
{ {
if (_propComments.TryGetValue(prop, out var comment)) if (_propComments.TryGetValue(prop, out var comment))
return comment; return comment;