Ejemplo n.º 1
0
        public ISubscription SubscribeAsync <T>(Func <T, TMessageContext, Task> subscribeMethod, SubscriptionConfiguration config)
        {
            var routingKey = _config.RouteWithGlobalId
                                ? $"{config.RoutingKey}.#"
                                : config.RoutingKey;

            var topologyTask = _topologyProvider.BindQueueAsync(config.Queue, config.Exchange, routingKey);
            var channelTask  = _channelFactory.CreateChannelAsync();

            var subscriberTask = Task
                                 .WhenAll(topologyTask, channelTask)
                                 .ContinueWith(t =>
            {
                var consumer            = _consumerFactory.CreateConsumer(config, channelTask.Result);
                consumer.OnMessageAsync = (o, args) => _errorHandling.ExecuteAsync(() =>
                {
                    var body    = _serializer.Deserialize <T>(args.Body);
                    var context = _contextProvider.ExtractContext(args.BasicProperties.Headers[PropertyHeaders.Context]);
                    _contextEnhancer.WireUpContextFeatures(context, consumer, args);
                    return(subscribeMethod(body, context));
                }, exception => _errorHandling.OnSubscriberExceptionAsync(consumer, config, args, exception));
                consumer.Model.BasicConsume(config.Queue.FullQueueName, config.NoAck, consumer);
                _logger.LogDebug($"Setting up a consumer on channel '{channelTask.Result.ChannelNumber}' for queue {config.Queue.QueueName} with NoAck set to {config.NoAck}.");
                return(new Subscription(consumer, config.Queue.QueueName));
            });

            Task.WaitAll(subscriberTask);
            _subscriptions.Add(subscriberTask.Result);
            return(subscriberTask.Result);
        }
Ejemplo n.º 2
0
        public ISubscription RespondAsync <TRequest, TResponse>(Func <TRequest, TMessageContext, Task <TResponse> > onMessage, ResponderConfiguration cfg)
        {
            var routingKey   = _config.RouteWithGlobalId ? $"{cfg.RoutingKey}.#" : cfg.RoutingKey;
            var topologyTask = _topologyProvider.BindQueueAsync(cfg.Queue, cfg.Exchange, routingKey);
            var channelTask  = _channelFactory.CreateChannelAsync();

            var respondTask = Task.WhenAll(topologyTask, channelTask)
                              .ContinueWith(t =>
            {
                if (topologyTask.IsFaulted)
                {
                    throw topologyTask.Exception ?? new Exception("Topology Task Fauled");
                }
                var consumer            = _consumerFactory.CreateConsumer(cfg, channelTask.Result);
                consumer.OnMessageAsync = (o, args) => _errorHandling.ExecuteAsync(() =>
                {
                    var body    = _serializer.Deserialize <TRequest>(args.Body);
                    var context = _contextProvider.ExtractContext(args.BasicProperties.Headers[PropertyHeaders.Context]);
                    _contextEnhancer.WireUpContextFeatures(context, consumer, args);

                    return(onMessage(body, context)
                           .ContinueWith(tResponse =>
                    {
                        if (tResponse.IsFaulted)
                        {
                            throw tResponse.Exception ?? new Exception();
                        }
                        if (consumer.AcknowledgedTags.Contains(args.DeliveryTag))
                        {
                            return;
                        }
                        if (tResponse.Result == null)
                        {
                            return;
                        }
                        _logger.LogDebug($"Sending response to request with correlation '{args.BasicProperties.CorrelationId}'.");
                        consumer.Model.BasicPublish(
                            exchange: string.Empty,
                            routingKey: args.BasicProperties.ReplyTo,
                            basicProperties: _propertyProvider.GetProperties <TResponse>(p => p.CorrelationId = args.BasicProperties.CorrelationId),
                            body: _serializer.Serialize(tResponse.Result)
                            );
                    }));
                }, exception => _errorHandling.OnResponseHandlerExceptionAsync(consumer, cfg, args, exception));
                consumer.Model.BasicConsume(cfg.Queue.QueueName, cfg.NoAck, consumer);
                return(new Subscription(consumer, cfg.Queue.QueueName));
            });

            Task.WaitAll(respondTask);
            _subscriptions.Add(respondTask.Result);
            return(respondTask.Result);
        }