private async void RunListener(string route, CancellationToken cancellationToken) { try { _unprocessedMessagesResender.Start(route, _messagingConfiguration.ResendInterval, cancellationToken); while (true) { try { await _listeningAgent.Listen(route, cancellationToken); } catch (TaskCanceledException) { _messagingLogger.Info($"{route} cancelled listener"); return; } catch (Exception e) { _messagingLogger.Error(e, $"error on listening in {route}, trying againg"); } await Task.Delay(500, cancellationToken); } } catch (Exception e) { _messagingLogger.Error(e, $"error on starting listening in {route}, listener is stopped"); } }
public async void Start(string route, TimeSpan resendInterval, CancellationToken cancellationToken) { try { await RepeatEvery(() => Resend(route, cancellationToken), resendInterval); } catch (Exception e) { _messagingLogger.Error(e, $"{route} error on UnprocessedMessagesResender.Start"); } }
public async void Process(string route, string messageId, string topic, string payload, bool resend, CancellationToken cancellationToken) { var sw = Stopwatch.StartNew(); try { using (var scope = _instanceResolver.CreateLifeTimeScope()) { var type = _messageTypesCache.Get(topic); var message = JsonConvert.DeserializeObject(payload, type); var handlerType = _messageHandlersCache.Get(topic); var handlerInstance = (IHandler)scope.ServiceProvider.GetService(handlerType); await handlerInstance.Handle(route, messageId, message, resend, cancellationToken); } } catch (Exception e) { _messagingLogger.Error(e); } finally { _messagingLogger.Debug($"{messageId} processed in {sw.ElapsedMilliseconds}"); } }
public async Task Listen(string route, CancellationToken cancellationToken) { var notReadFilter = Builders <Envelope> .Filter.Eq(x => x.IsRead, false); var collection = _mongoAgent.GetEnvelops(route); try { while (true) { var messages = await(await collection.FindAsync(notReadFilter, null, cancellationToken)).ToListAsync(cancellationToken); { foreach (var message in messages) { var readMessage = await _messageStatusManager.TrySetReadAt(route, message.Id, cancellationToken); if (readMessage != null) { var resend = readMessage.OriginalId != IdGenerator.Empty; _messageProcessor.Process(route, readMessage.Id, readMessage.Topic, readMessage.Payload, resend, cancellationToken); } } } if (!messages.Any()) { await Task.Delay(100, cancellationToken); } } } catch (MongoCommandException mongoCommandException) { if (mongoCommandException.Code == 96) { _messagingLogger.Error(mongoCommandException, $"{route} reader processes messages slower than they occur"); } else { _messagingLogger.Error(mongoCommandException, $"{route}"); } } }
//TODO: Make this generic method for core project? private string GetQueueName() { var attribute = (QueueNameAttribute)Attribute.GetCustomAttribute(typeof(TEvent), typeof(QueueNameAttribute)); if (attribute == null) { _logger.Error("Failed to get queue name"); throw new NullReferenceException(nameof(attribute)); } return(attribute.Name); }