/// <summary> /// Handles the specified message. /// </summary> /// <param name="messageId">The message identifier.</param> /// <param name="timeOut">The time out.</param> /// <param name="queueWait">The queue wait.</param> /// <returns></returns> /// <exception cref="System.TimeoutException"></exception> public IReceivedMessage <TReceivedMessage> Handle(IMessageId messageId, TimeSpan timeOut, IQueueWait queueWait) { Guard.NotNull(() => messageId, messageId); Guard.NotNull(() => queueWait, queueWait); //use a message context, and talk to the transport directly //we are not going to use the consumer queue, because we are going to re-use the calling thread for all of the work below using (var context = _messageContextFactory.Create()) { var recMessage = _receiveMessagesFactory.Create(); //set message Id on the context, so that the transport knows we want a particular message context.Set(_configurationReceive.HeaderNames.StandardHeaders.RpcContext, _rpcContextFactory.Create(messageId, timeOut)); //use a stop watch to determine when we have timed out var sw = new Stopwatch(); sw.Start(); while (true) { var messageRec = recMessage.ReceiveMessage(context); if (messageRec != null) { _commitMessage.Commit(context); return((IReceivedMessage <TReceivedMessage>)_messageHandler.GenerateMessage(messageRec)); } if (sw.ElapsedMilliseconds >= timeOut.TotalMilliseconds) { throw new TimeoutException(); } queueWait.Wait(); } } }
/// <summary> /// Tries the process the new incoming message. /// </summary> private void TryProcessIncomingMessage() { using (var context = _messageContextFactory.Create()) { try { DoTry(context); } catch (OperationCanceledException) { _rollbackMessage.Rollback(context); } // ReSharper disable once UncatchableException catch (ThreadAbortException) { _rollbackMessage.Rollback(context); } catch (PoisonMessageException exception) { _receivePoisonMessage.Handle(context, exception); } catch (ReceiveMessageException e) { //an exception occurred trying to get the message from the transport _log.ErrorException("An error has occurred while receiving a message from the transport", e, null); _seriousExceptionProcessBackOffHelper.Value.Wait(); } catch { _rollbackMessage.Rollback(context); throw; } } }
/// <summary> /// Tries the process a new incoming message. /// </summary> /// <returns></returns> private async Task TryProcessIncomingMessageAsync() { using (var context = _messageContextFactory.Create()) { try { await DoTryAsync(context).ConfigureAwait(false); } catch (OperationCanceledException) { _rollbackMessage.Rollback(context); } // ReSharper disable once UncatchableException catch (ThreadAbortException) { _rollbackMessage.Rollback(context); } catch (PoisonMessageException exception) { _receivePoisonMessage.Handle(context, exception); } catch (ReceiveMessageException e) //an exception occurred trying to get the message from the transport { _log.LogError($"An error has occurred while receiving a message from the transport{System.Environment.NewLine}{e}"); _seriousExceptionProcessBackOffHelper.Value.Wait(); } catch { _rollbackMessage.Rollback(context); throw; } } }
public async ValueTask OnMessageCreate(IDiscordMessage message) { var @event = new MessageReceivedEvent(message); await _eventManager.CallAsync(@event); if (@event.IsCancelled || string.IsNullOrEmpty(message.Content)) { return; } var scope = _provider.CreateScope(); var features = new FeatureCollection(); var responseFeature = new MessageResponseFeature(); features.Set <IServiceProvidersFeature>(new ServiceProvidersFeature(scope.ServiceProvider)); features.Set <IUserFeature>(new UserFeature(message.Author)); features.Set <IMessageResponseFeature>(responseFeature); features.Set <IMessageRequestFeature>(new MessageRequestFeature { GuildId = message.GuildId, ChannelId = message.ChannelId, MessageId = message.Id, Message = message.Content }); var context = _messageContextFactory.Create(features); try { CultureInfo.CurrentCulture = _localizer.DefaultCulture; _contextAccessor.Context = context; await _application(context); await _contextDispatcher.DispatchAsync(context); } catch (Exception e) { _logger.LogError(e, "An exception occured while processing the message '{Content}' from {User}.", message.Content, message.Author.Username); if (_debugOptions.ThrowOnMessageException) { throw; } } finally { scope.Dispose(); _messageContextFactory.Dispose(context); } }
public async Task DispatchAsync(Func <MessageContext, Task> func, FeatureCollection features = null) { var context = _factory.Create(features ?? new FeatureCollection()); try { await func(context); await DispatchAsync(context); } finally { _factory.Dispose(context); } }
private async Task ProcessAsyncCore <TM>(TM message, CancellationToken cancellationToken) where TM : IMessage { var messageContext = _messageContextFactory.Create(message); _logger.LogInformation("processing message {MessageId} with type {MessageType} on client {ClientGroup}/{ClientId} ...", message.Id, typeof(TM).FullName, messageContext.SystemInfo.ClientGroup, messageContext.SystemInfo.ClientId); try { await _sagasRunner.RunAsync(messageContext, cancellationToken); await _messageHandlersRunner.RunAsync(messageContext, cancellationToken); } catch (AggregateException ex) { _logger.LogError(ex, "an error has occurred while processing message {MessageId} with type {MessageType} on client {ClientGroup}/{ClientId} : {Exception}", message.Id, typeof(TM).FullName, messageContext.SystemInfo.ClientGroup, messageContext.SystemInfo.ClientId, ex.Message); throw; } _logger.LogInformation("message {MessageId} with type {MessageType} processed on client {ClientGroup}/{ClientId}", message.Id, typeof(TM).FullName, messageContext.SystemInfo.ClientGroup, messageContext.SystemInfo.ClientId); }
private async Task ProcessAsyncCore <TM>(TM message, CancellationToken cancellationToken) where TM : IMessage { var messageContext = _messageContextFactory.Create(message); await _sagasRunner.RunAsync(messageContext, cancellationToken); }