/// <summary> /// Posts the specified request. 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> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public void Post <T>(T request) where T : class, IRequest { _logger.Value.InfoFormat("Decoupled invocation of request: {0} {1}", request.GetType(), request.Id); if (_messageStore == null) { throw new InvalidOperationException("No message store defined."); } if (_messageProducer == null) { throw new InvalidOperationException("No mesage 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); RetryAndBreakCircuit(() => { _messageStore.Add(message, _messageStoreTimeout); _messageProducer.Send(message); }); }
/// <summary> /// Adds a message into the message store, and returns the id of the saved message. /// Intended for use with the Outbox pattern: http://gistlabs.com/2014/05/the-outbox/ normally you include the /// call to DepositPostBox within the scope of the transaction to write corresponding entity state to your /// database, that you want to signal via the request to downstream consumers /// Pass deposited Guid to <see cref="ClearPostBox"/> /// </summary> /// <param name="request">The request to save to the message store</param> /// <typeparam name="T">The type of the request</typeparam> /// <returns></returns> public Guid DepositPost <T>(T request) where T : class, IRequest { _logger.Value.InfoFormat("Save request: {0} {1}", request.GetType(), request.Id); if (_messageStore == null) { throw new InvalidOperationException("No message store 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); RetryAndBreakCircuit(() => { _messageStore.Add(message, _messageStoreTimeout); }); return(message.Id); }
/// <summary> /// Posts the specified request. 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> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public void Post <T>(T request) where T : class, IRequest { _logger.InfoFormat("Decoupled invocation of request: {0}", request.Id); var messageMapper = _mapperRegistry.Get <T>(); if (messageMapper == null) { throw new ArgumentOutOfRangeException(string.Format("No message mapper registered for messages of type: {0}", typeof(T))); } var message = messageMapper.MapToMessage(request); RetryAndBreakCircuit(() => { _messageStore.Add(message, _messageStoreTimeout); _messageProducer.Send(message); }); }
/// <summary> /// Posts the specified request. 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> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public void Post <T>(T request) where T : class, IRequest { logger.InfoFormat("Decoupled invocation of request: {0}", request.Id); var messageMapper = mapperRegistry.Get <T>(); if (messageMapper == null) { throw new ArgumentOutOfRangeException(string.Format("No message mapper registered for messages of type: {0}", typeof(T))); } var message = messageMapper.MapToMessage(request); /* * NOTE: Don't rewrite with await, compiles but Policy does not call await on the lambda so becomes fire and forget, * see http://blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx */ RetryAndBreakCircuit(() => { messageStore.Add(message).Wait(); messagingGateway.Send(message).Wait(); }); }