From 010f05c5659145a9ee377faf609ebfb88813c5de Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Mon, 14 Aug 2023 21:07:15 +0200 Subject: [PATCH] feat: init all packetHandler once & reuse --- Server/Services/PacketDistributorService.cs | 47 +++++++++++++-------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/Server/Services/PacketDistributorService.cs b/Server/Services/PacketDistributorService.cs index 0285469..a1747cc 100644 --- a/Server/Services/PacketDistributorService.cs +++ b/Server/Services/PacketDistributorService.cs @@ -1,13 +1,14 @@ namespace Server.Services; using System.Collections.Concurrent; +using System.Collections.Immutable; using System.Reflection; +using DotNext.Collections.Generic; using MassTransit.Internals; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.VisualBasic.CompilerServices; -using Newtonsoft.Json; using PacketHandlers; using Packets; using static DotNext.Metaprogramming.CodeGenerator; @@ -17,8 +18,12 @@ public class PacketDistributorService : IHostedService { private readonly ConcurrentQueue concurrentQueue; private readonly ILogger logger; - private readonly Dictionary packetHandlers; - private readonly Dictionary> deserializationMap; + private readonly ConcurrentDictionary packetHandlersInstantiation; + + private readonly + ImmutableDictionary> deserializationMap; + private readonly IServiceProvider serviceProvider; public PacketDistributorService(ILogger logger, IServiceProvider serviceProvider) @@ -26,29 +31,38 @@ public class PacketDistributorService : IHostedService this.concurrentQueue = new ConcurrentQueue(); this.logger = logger; this.serviceProvider = serviceProvider; - this.packetHandlers = new Dictionary(); - this.deserializationMap = new Dictionary>(); + var tempDeserializationMap = + new Dictionary>(); var executingAssembly = Assembly.GetExecutingAssembly(); var packetsTypes = this.GetPacketsWithId(executingAssembly); - this.packetHandlers = this.GetAllPacketHandlersWithId(executingAssembly); - + var packetHandlers = this.GetAllPacketHandlersWithId(executingAssembly); + this.packetHandlersInstantiation = new ConcurrentDictionary(); + packetHandlers.ForEach(x => + { + var packetHandler = + ActivatorUtilities.GetServiceOrCreateInstance(this.serviceProvider, + x.Value); + this.packetHandlersInstantiation.TryAdd(x.Key, packetHandler); + }); foreach (var packetsType in packetsTypes) { var lambda = Lambda>(fun => { - var arg = fun[0]; + var argPacketData = fun[0]; var newPacket = packetsType.Value.New(); var packetVariable = DeclareVariable(packetsType.Value, "packet"); Assign(packetVariable, newPacket); - Call(packetVariable, nameof(IPacket.Deserialize), arg); + Call(packetVariable, nameof(IPacket.Deserialize), argPacketData); Return(packetVariable); }).Compile(); logger.LogInformation("Packet creation function created for {Opcode}", packetsType.Key); - this.deserializationMap.Add(packetsType.Key, lambda); + tempDeserializationMap.Add(packetsType.Key, lambda); } + + this.deserializationMap = tempDeserializationMap.ToImmutableDictionary(); } public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask; @@ -81,7 +95,8 @@ public class PacketDistributorService : IHostedService t is { IsClass: true, IsAbstract: false } && t .GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketHandler<>))).ToDictionary(type => - type.GetInterfaces().First(t =>t is { IsGenericType: true} && t.GetGenericTypeDefinition() == typeof(IPacketHandler<>)) + type.GetInterfaces().First(t => + t is { IsGenericType: true } && t.GetGenericTypeDefinition() == typeof(IPacketHandler<>)) .GetGenericArguments().First().GetCustomAttribute()!.Code); if (packetHandlersWithId is not { Count: 0 }) @@ -126,12 +141,10 @@ public class PacketDistributorService : IHostedService } var packet = this.deserializationMap[item.OperationCode](item.MessageBody); - var packetHandler = - ActivatorUtilities.GetServiceOrCreateInstance(this.serviceProvider, - this.packetHandlers[item.OperationCode]); - packetHandler.GetType().GetMethod("HandleAsync") - ?.Invoke(packetHandler, new object[] { packet, item.Session }); - this.logger.LogDebug("Packet data {PacketData}", JsonConvert.SerializeObject(packet)); + this.packetHandlersInstantiation[item.OperationCode].GetType().GetMethod("HandleAsync") + ?.Invoke(this.packetHandlersInstantiation[item.OperationCode], new object[] { packet, item.Session }); + + //this.logger.LogDebug("Packet data {PacketData}", JsonConvert.SerializeObject(packet)); this.logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} has finished", item.Session.Id, item.OperationCode);