public async Task <bool> FallbackAsync(string key, CancellationToken token) { var msg = new LinkPublishMessage <RedisInvalidationMessage>( new RedisInvalidationMessage(key), new LinkMessageProperties { DeliveryMode = LinkDeliveryMode.Persistent } ); await _producer.PublishAsync(msg).ConfigureAwait(false); return(true); }
public async Task PublishAsync(Response <TResponse> message, CancellationToken token = default(CancellationToken)) { var log = Log.With("@message", message); log.Trace($"{nameof(PublishAsync)} enter"); try { var publisher = Utils.CreateProducer(Link, Schema.ResponseExchange, Schema.ContentType, false, ConfirmsMode()); var props = new LinkMessageProperties { CorrelationId = message.CorrelationId }; var serializer = Link.PayloadManager; var answer = new LinkPublishMessage <byte[]>(message.IsFail ? serializer.Serialize(Schema.ContentType, new RpcFail { Kind = message.Error.GetType().FullName, Message = message.Error.Message }, props, Schema.Service.Types) : serializer.Serialize(Schema.ContentType, message.Result, props, Schema.Service.Types), props, new LinkPublishProperties { RoutingKey = message.ReplyTo }); await publisher.PublishAsync(answer, token); log.Trace($"{nameof(PublishAsync)} success"); } catch (Exception ex) { if (ex.IsCancellation()) { log.Info($"{nameof(PublishAsync)} cancelled"); } else { log.Error($"{nameof(PublishAsync)} error", ex); } throw; } }
public async Task PublishAsync(Request <TRequest> message, CancellationToken token = default(CancellationToken)) { var log = Log.With("@message", message); log.Trace($"{nameof(PublishAsync)} enter"); try { var props = new LinkMessageProperties { CorrelationId = message.CorrelationId, ReplyTo = QueueName(), Expiration = MessageTtl(), DeliveryMode = Persisent() ? LinkDeliveryMode.Persistent : LinkDeliveryMode.Transient }; var serialized = Link.PayloadManager.Serialize(ContentType, message, props, Schema.Service.Types); var msg = new LinkPublishMessage <byte[]>(serialized, props, new LinkPublishProperties { RoutingKey = Schema.Exchange.Type == ExchangeKind.Fanout ? null : Schema.RoutingKey }); var publisher = Utils.CreateProducer(Link, Schema.Exchange, Schema.ContentType, ExchangePassive(), ConfirmsMode(), NamedProducer()); await publisher.PublishAsync(msg, token); log.Trace($"{nameof(PublishAsync)} success"); } catch (Exception ex) { if (ex.IsCancellation()) { log.Info($"{nameof(PublishAsync)} cancelled"); } else { log.Error($"{nameof(PublishAsync)} error", ex); } throw; } }
public IDisposable Process(Func <TArg, CancellationToken, Task <TResult> > processor) { Log.Trace($"{nameof(Process)} enter"); try { var queue = Schema.RequestQueue; var consumerBuilder = Utils.CreateConsumerBuilder(Link, Schema.Exchange, false, false, queue.Name, false, null, null, false, PrefetchCount(), new QueueParameters().Durable(queue.Durable).AutoDelete(queue.AutoDelete), new[] { Schema.RoutingKey }, true); var publisher = Utils.CreateProducer(Link, Schema.ResponseExchange, Schema.ContentType, false, false); consumerBuilder = consumerBuilder.Handler(async msg => { var log = Log.With("@msg", msg); log.Trace("Call receiving"); try { var data = (TArg)Link.PayloadManager.Deserialize <TArg>(msg, Schema.Service.Types); var tsk = processor(data, msg.Cancellation); try { var props = new LinkMessageProperties { CorrelationId = msg.Properties.CorrelationId }; var result = await tsk; var answer = new LinkPublishMessage <byte[]>( Link.PayloadManager.Serialize(Schema.ContentType, result, props, Schema.Service.Types), props, new LinkPublishProperties { RoutingKey = msg.Properties.ReplyTo }); await publisher.PublishAsync(answer, msg.Cancellation); log.With("@result", result).Trace("Call executed"); } catch (Exception ex) { if (tsk.IsCanceled) { return(LinkConsumerAckStrategy.Requeue); } var props = new LinkMessageProperties { CorrelationId = msg.Properties.CorrelationId }; var answer = new LinkPublishMessage <byte[]>(Link.PayloadManager.Serialize( Schema.ContentType, new RpcFail { Kind = ex.GetType().FullName, Message = ex.Message }, props, Schema.Service.Types), props, new LinkPublishProperties { RoutingKey = msg.Properties.ReplyTo }); await publisher.PublishAsync(answer, msg.Cancellation); log.Trace("Call executed with exception", ex); } return(LinkConsumerAckStrategy.Ack); } catch (Exception ex) { if (ex.IsCancellation()) { log.Info("Cancelled"); } else { log.Error("Error receiving", ex); } throw; } }); var consumer = consumerBuilder.Build(); Log.Trace($"{nameof(Process)} success"); return(consumer); } catch (Exception ex) { Log.Error($"{nameof(Process)} error", ex); throw; } }
private async Task <TResult> Call(TArg arg, CancellationToken token, TimeSpan timeout) { var log = Log.With("@message", arg); log.Trace($"{nameof(Call)} enter"); try { CancellationTokenSource source = null; TimeSpan?messageTtl = null; try { if (!token.CanBeCanceled) { source = new CancellationTokenSource(timeout); token = source.Token; messageTtl = timeout; } var queueName = $"{Schema.Service.Owner}.{Schema.ResponseExchange}.{Guid.NewGuid():D}"; var consumer = Link.GetOrAddConsumer(Schema.ResponseExchange.Name ?? "", () => new RpcConsumer(Link, Utils.CreateConsumerBuilder(Link, Schema.ResponseExchange, true, false, queueName, false, null, null, false, PrefetchCount(), new QueueParameters().Expires(ResponseQueueExpires()), new[] { queueName }, true), queueName)); await consumer.WaitReadyAsync(token); var props = new LinkMessageProperties { CorrelationId = Guid.NewGuid().ToString("D"), ReplyTo = queueName }; if (messageTtl != null) { props.Expiration = messageTtl.Value; } var waiter = consumer.WaitFor <TResult>(props.CorrelationId, token, Schema.Service); var producer = Utils.CreateProducer(Link, Schema.Exchange, Schema.ContentType, true); var request = new LinkPublishMessage <byte[]>( Link.PayloadManager.Serialize(Schema.ContentType, arg, props, Schema.Service.Types), props, new LinkPublishProperties { RoutingKey = Schema.RoutingKey }); await producer.PublishAsync(request, token); var result = await waiter; log.With("@result", result).Trace($"{nameof(Call)} executed"); return(result); } finally { source?.Dispose(); } } catch (Exception ex) { if (ex.IsCancellation()) { log.Info($"{nameof(Call)} cancelled"); } else { log.Error($"{nameof(Call)} error", ex); } throw; } }