I am trying to understand why my application has the following issues
- after running for an hour or so, memory usage is over 2GB
- after running for an hour or so event processing slows from ~100m/s to ~6-10m/s
I am using Dotnet 5 with Autofac. Here is the method that is fired by the Consumer_Received event
private async Task ProcessEvent(string eventName, string message)
{
if (_subsManager.HasSubscriptionsForEvent(eventName))
{
await using var scope = _autofac.BeginLifetimeScope(AUTOFAC_SCOPE_NAME);
var subscriptions = _subsManager.GetHandlersForEvent(eventName);
foreach (var subscription in subscriptions)
{
var handler = scope.ResolveOptional(subscription.HandlerType);
if (handler == null) continue;
var eventType = _subsManager.GetEventTypeByName(eventName);
var integrationEvent = JsonConvert.DeserializeObject(message, eventType);
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
await Task.Yield();
await ((Task) concreteType.GetMethod("Handle")?
.Invoke(handler, new[] {integrationEvent}))
.ConfigureAwait(false);
}
}
}
This is the event
public class MPTEvent
{
public string M {get;set;}
public string Number {get;set;}
public string Type {get;set;}
public bool T {get;set;}
public bool A {get;set;}
public bool LB {get;set;}
}
The above method is fired for EVERY event stored inside the Queue. i have several "INotification" handlers that process the events (IE. Handle), here is an example of one (Edited for brievety)
public async Task Handle(MPTEvent tEvent)
{
try
{
// try to get the tag and device
var contextD = await _repository.GetByNumber(tEvent.M);
if (contextD == null)
{
_logger.LogError("Detailed Error Message");
return;
}
var contextT = await _repository.GetByNumber(tEvent.Number);
if (contextT == null)
{
_logger.LogWarning("Detailed Warning Message");
return;
}
if (tEvent.T == 1 && tEvent.A == 0 && tEvent.LB == 0)
{
contextT?.TriggerTEvent(contextD, tEvent.R, tEvent.CreatedDate);
}
await _repository.UpdateAsync(contextT);
}
catch (Exception ex)
{
_logger.LogCritical(ex, "Detailed Exception Message");
}
}
The above handler is fired more than any others and i believe is partly where the biggest issue resides, the questions i have are
- Should the handler (in this case) have a public async Task and return something like _repository.UpdateAsync(contextT)?
- would it be smart to replace the _repository.UpdateAsync and _repository.AddAsync with mediator commands?
I am relatively new to Autofac/DI/rabbitMq so any advice is greatly appreciated