Skip to content

Commit

Permalink
feat: Add Priority in HuTaoMediator
Browse files Browse the repository at this point in the history
  • Loading branch information
sabihoshi committed Jul 20, 2022
1 parent 07216cd commit fce393e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions HuTao.Services/Core/Listeners/CommandHandlingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public CommandHandlingService(
_services = services;
}

[Priority(0)]
public async Task Handle(MessageReceivedNotification notification, CancellationToken cancellationToken)
{
var rawMessage = notification.Message;
Expand Down
34 changes: 32 additions & 2 deletions HuTao.Services/Core/Listeners/HuTaoMediator.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Discord.Commands;
using MediatR;
using Serilog;

Expand All @@ -19,11 +22,13 @@ protected override Task PublishCore(
{
_ = Task.Run(async () =>
{
foreach (var handler in handlers)
var priorities = handlers.Select(h => (Handler: h, GetOrderAttribute(h)?.Priority));
var ordered = priorities.OrderBy(h => !h.Priority.HasValue).ThenBy(h => h.Priority);
foreach (var handler in ordered)
{
try
{
await handler(notification, cancellationToken);
await handler.Handler(notification, cancellationToken);
}
catch (Exception ex) when (ex is not (OutOfMemoryException or StackOverflowException))
{
Expand All @@ -42,4 +47,29 @@ protected override Task PublishCore(

return Task.CompletedTask;
}

private static PriorityAttribute? GetOrderAttribute(Func<INotification, CancellationToken, Task> x)
{
var handlerFieldInfo = x.Target?.GetType().GetField("x");
if (handlerFieldInfo is not { FieldType.IsGenericType: true, FieldType.GenericTypeArguments.Length: 1 })
return null;

var type = handlerFieldInfo.GetValue(x.Target)?.GetType();
var methods = type?.GetMethods(BindingFlags.Instance | BindingFlags.Public);
var method = methods?.FirstOrDefault(m =>
{
if (m is not { Name: "Handle" } || m.ReturnType != typeof(Task)) return false;

var parameters = m.GetParameters();
if (parameters.Length != 2) return false;

var first = parameters[0];
var second = parameters[1];

return first.ParameterType == handlerFieldInfo.FieldType.GenericTypeArguments[0]
&& second.ParameterType == typeof(CancellationToken);
});

return method?.GetCustomAttribute<PriorityAttribute>();
}
}

0 comments on commit fce393e

Please sign in to comment.