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);
        }
Example #2
0
        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;
            }
        }
Example #3
0
        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;
            }
        }
Example #4
0
        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;
            }
        }
Example #5
0
        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;
            }
        }