示例#1
0
        /// <summary>
        /// Posts the specified request with async/await support. The message is placed on a task queue and into a message store for reposting in the event of failure.
        /// You will need to configure a service that reads from the task queue to process the message
        /// Paramore.Brighter.ServiceActivator provides an endpoint for use in a windows service that reads from a queue
        /// and then Sends or Publishes the message to a <see cref="CommandProcessor"/> within that service. The decision to <see cref="Send{T}"/> or <see cref="Publish{T}"/> is based on the
        /// mapper. Your mapper can map to a <see cref="Message"/> with either a <see cref="T:MessageType.MT_COMMAND"/> , which results in a <see cref="Send{T}(T)"/> or a
        /// <see cref="T:MessageType.MT_EVENT"/> which results in a <see cref="Publish{T}(T)"/>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="request">The request.</param>
        /// <param name="continueOnCapturedContext">Should we use the calling thread's synchronization context when continuing or a default thread synchronization context. Defaults to false</param>
        /// <param name="cancellationToken">Allows the sender to cancel the request pipeline. Optional</param>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        /// <returns>awaitable <see cref="Task"/>.</returns>
        public async Task PostAsync <T>(T request, bool continueOnCapturedContext = false, CancellationToken cancellationToken = default(CancellationToken)) where T : class, IRequest
        {
            _logger.Value.InfoFormat("Async decoupled invocation of request: {0} {1}", request.GetType(), request.Id);

            if (_asyncMessageStore == null)
            {
                throw new InvalidOperationException("No async message store defined.");
            }
            if (_asyncMessageProducer == null)
            {
                throw new InvalidOperationException("No async message producer defined.");
            }

            var messageMapper = _mapperRegistry.Get <T>();

            if (messageMapper == null)
            {
                throw new ArgumentOutOfRangeException($"No message mapper registered for messages of type: {typeof(T)}");
            }

            var message = messageMapper.MapToMessage(request);

            await RetryAndBreakCircuitAsync(async ct =>
            {
                await _asyncMessageStore.AddAsync(message, _messageStoreTimeout, ct).ConfigureAwait(continueOnCapturedContext);
                await _asyncMessageProducer.SendAsync(message).ConfigureAwait(continueOnCapturedContext);
            }, continueOnCapturedContext, cancellationToken).ConfigureAwait(continueOnCapturedContext);
        }
示例#2
0
        /// <summary>
        /// Flushes the message box message given by <param name="posts"> to the broker.
        /// Intended for use with the Outbox pattern: http://gistlabs.com/2014/05/the-outbox/ <see cref="DepositPostBoxAsync"/>
        /// </summary>
        /// <param name="posts">The posts to flush</param>
        public async Task ClearOutboxAsync(IEnumerable <Guid> posts, bool continueOnCapturedContext = false, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (_asyncOutbox == null)
            {
                throw new InvalidOperationException("No async outbox defined.");
            }
            if (_asyncMessageProducer == null)
            {
                throw new InvalidOperationException("No async message producer defined.");
            }

            foreach (var messageId in posts)
            {
                var message = await _asyncOutbox.GetAsync(messageId, _outboxTimeout, cancellationToken);

                if (message == null)
                {
                    throw new NullReferenceException($"Message with Id {messageId} not found in the Outbox");
                }

                _logger.Value.InfoFormat("Decoupled invocation of message: Topic:{0} Id:{1}", message.Header.Topic, messageId.ToString());

                await RetryAndBreakCircuitAsync(
                    async ct => await _asyncMessageProducer.SendAsync(message).ConfigureAwait(continueOnCapturedContext),
                    continueOnCapturedContext, cancellationToken).ConfigureAwait(continueOnCapturedContext);
            }
        }