Skip to content

Commit 9f80483

Browse files
cache methodinfos
1 parent 217acac commit 9f80483

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/TeamCloud.Orchestrator/Command/CommandHandler.cs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
*/
55

66
using System;
7+
using System.Collections.Concurrent;
8+
using System.Reflection;
79
using System.Threading.Tasks;
10+
using Jose;
811
using Microsoft.Azure.WebJobs;
912
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
1013
using Microsoft.Extensions.Logging;
14+
using Microsoft.VisualStudio.Services.Common;
1115
using TeamCloud.Model.Commands.Core;
1216

1317
namespace TeamCloud.Orchestrator.Command;
@@ -20,6 +24,21 @@ public abstract class CommandHandler<TCommand> : CommandHandler, ICommandHandler
2024

2125
public abstract class CommandHandler : ICommandHandler
2226
{
27+
private static readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, MethodInfo>> HandleMethodCache = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, MethodInfo>>();
28+
29+
private MethodInfo GetHandleMethod(ICommand command) => HandleMethodCache
30+
.GetOrAdd(GetType(), handlerType => new ConcurrentDictionary<Type, MethodInfo>())
31+
.GetOrAdd(command.GetType(), commandType =>
32+
{
33+
var handlerInterface = typeof(ICommandHandler<>)
34+
.MakeGenericType(commandType);
35+
36+
if (handlerInterface.IsAssignableFrom(GetType()))
37+
return handlerInterface.GetMethod(nameof(HandleAsync), new Type[] { command.GetType(), typeof(IAsyncCollector<ICommand>), typeof(IDurableOrchestrationContext), typeof(ILogger) });
38+
39+
return null;
40+
});
41+
2342
public const string ProcessorQueue = "command-processor";
2443
public const string MonitorQueue = "command-monitor";
2544

@@ -30,9 +49,7 @@ public virtual bool CanHandle(ICommand command)
3049
if (command is null)
3150
throw new ArgumentNullException(nameof(command));
3251

33-
return typeof(ICommandHandler<>)
34-
.MakeGenericType(command.GetType())
35-
.IsAssignableFrom(GetType());
52+
return GetHandleMethod(command) is not null;
3653
}
3754

3855
public virtual Task<ICommandResult> HandleAsync(ICommand command, IAsyncCollector<ICommand> commandQueue, IDurableOrchestrationContext orchestrationContext, ILogger log)
@@ -42,11 +59,7 @@ public virtual Task<ICommandResult> HandleAsync(ICommand command, IAsyncCollecto
4259

4360
if (CanHandle(command))
4461
{
45-
var handleMethod = typeof(ICommandHandler<>)
46-
.MakeGenericType(command.GetType())
47-
.GetMethod(nameof(HandleAsync), new Type[] { command.GetType(), typeof(IAsyncCollector<ICommand>), typeof(IDurableOrchestrationContext), typeof(ILogger) });
48-
49-
return (Task<ICommandResult>)handleMethod
62+
return (Task<ICommandResult>)GetHandleMethod(command)
5063
.Invoke(this, new object[] { command, commandQueue, orchestrationContext, log });
5164
}
5265

0 commit comments

Comments
 (0)