refactor: handler invocation performance
All checks were successful
Build, Package and Push Images / preprocess (push) Successful in 2s
Build, Package and Push Images / build (push) Successful in 29s
Build, Package and Push Images / sbom-scan (push) Successful in 38s
Build, Package and Push Images / sonarqube (push) Successful in 1m21s
Build, Package and Push Images / container-build (push) Successful in 1m21s
Build, Package and Push Images / container-sbom-scan (push) Successful in 33s

This commit is contained in:
Timothy Schenk 2023-11-22 14:55:46 +01:00
parent b3de52c6d8
commit a547d6ebbf
3 changed files with 37 additions and 10 deletions

View file

@ -41,7 +41,7 @@ internal static partial class PacketLoggerMessages
Message = "No PacketHandlers have been found")]
public static partial void NoPacketHandlersFound(this ILogger logger);
[LoggerMessage(EventId = 8, Level = LogLevel.Information,
[LoggerMessage(EventId = 8, Level = LogLevel.Trace,
Message = "Packet data {PacketData}")]
public static partial void PacketData(this ILogger logger, string packetData);

View file

@ -7,8 +7,24 @@ using Wonderking.Packets;
namespace Server.PacketHandlers;
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
public interface IPacketHandler<in T> where T : IPacket
public interface IPacketHandler<in T> : IPacketHandler where T : IPacket
{
[UsedImplicitly]
public Task HandleAsync(T packet, TcpSession session);
async Task<bool> IPacketHandler.TryHandleAsync(IPacket packet, TcpSession session)
{
if (packet is T tPacket)
{
await HandleAsync(tPacket, session);
return true;
}
return false;
}
}
public interface IPacketHandler
{
Task<bool> TryHandleAsync(IPacket packet, TcpSession session);
}

View file

@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection;
using DotNext.Collections.Generic;
using DotNext.Linq.Expressions;
@ -32,13 +33,15 @@ public class PacketDistributorService : IHostedService
private ImmutableDictionary<OperationCode,
Func<byte[], IPacket>> _deserializationMap;
private ConcurrentDictionary<OperationCode, object> _packetHandlersInstantiation;
private ConcurrentDictionary<OperationCode, IPacketHandler> _packetHandlersInstantiation;
private readonly ActivitySource _activitySource;
public PacketDistributorService(ILogger<PacketDistributorService> logger, IServiceProvider serviceProvider)
{
_concurrentQueue = new ConcurrentQueue<RawPacket>();
_logger = logger;
_serviceProvider = serviceProvider;
_activitySource = new ActivitySource(nameof(Server));
}
public Task StartAsync(CancellationToken cancellationToken)
@ -49,13 +52,13 @@ public class PacketDistributorService : IHostedService
var wonderkingAssembly = Assembly.GetAssembly(typeof(IPacket));
var packetsTypes = GetPacketsWithId(wonderkingAssembly);
var packetHandlers = GetAllPacketHandlersWithId(Assembly.GetExecutingAssembly());
_packetHandlersInstantiation = new ConcurrentDictionary<OperationCode, object>();
_packetHandlersInstantiation = new ConcurrentDictionary<OperationCode, IPacketHandler>();
packetHandlers.ForEach(x =>
{
var packetHandler =
ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider,
x.Value);
_packetHandlersInstantiation.TryAdd(x.Key, packetHandler);
_packetHandlersInstantiation.TryAdd(x.Key, packetHandler as IPacketHandler);
});
foreach (var packetsType in packetsTypes)
{
@ -152,6 +155,7 @@ public class PacketDistributorService : IHostedService
private void InvokePacketHandler(RawPacket item)
{
IPacket packet;
_logger.PacketDequeued(item.Session.Id, item.OperationCode);
if (!_deserializationMap.TryGetValue(item.OperationCode, out var value))
{
@ -159,12 +163,19 @@ public class PacketDistributorService : IHostedService
return;
}
var packet = value(item.MessageBody);
_logger.PacketData(JsonConvert.SerializeObject(packet));
_packetHandlersInstantiation[item.OperationCode].GetType()
.GetMethod(nameof(IPacketHandler<IPacket>.HandleAsync))
?.Invoke(_packetHandlersInstantiation[item.OperationCode], new object[] { packet, item.Session });
using (var packetParsingActivity = _activitySource.StartActivity("PacketParsing"))
{
packetParsingActivity?.SetTag("PacketId", item.OperationCode);
packet = value(item.MessageBody);
}
using (var packetHandlerActivity = _activitySource.StartActivity("PacketHandler"))
{
packetHandlerActivity?.SetTag("PacketId", item.OperationCode);
_ = _packetHandlersInstantiation[item.OperationCode].TryHandleAsync(packet, item.Session);
}
_logger.PacketData(JsonConvert.SerializeObject(packet));
_logger.PacketFinished(item.Session.Id, item.OperationCode);
}
}