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); }
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); }