Slow Event Processing and Memory usage issues with RabbitMQ and AutoFac

128 views Asked by At

I am trying to understand why my application has the following issues

  1. after running for an hour or so, memory usage is over 2GB
  2. 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

  1. Should the handler (in this case) have a public async Task and return something like _repository.UpdateAsync(contextT)?
  2. 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

0

There are 0 answers