/// <summary> /// The resolve for. /// </summary> /// <param name="configuration"> /// The configuration. /// </param> /// <returns> /// The <see cref="Producer"/>. /// </returns> public Producer ResolveFor(ISenderConfiguration configuration) { Producer producer = this.TryResolverFor(configuration.Label); if (producer == null) { using (RabbitChannel channel = this._bus.OpenChannel()) { var topologyBuilder = new TopologyBuilder(channel); var builder = new RouteResolverBuilder(this._bus.Endpoint, topologyBuilder, configuration); Maybe <Func <IRouteResolverBuilder, IRouteResolver> > routeResolverBuilder = configuration.Options.GetRouteResolverBuilder(); Assumes.True(routeResolverBuilder.HasValue, "RouteResolverBuilder must be set for [{0}]", configuration.Label); IRouteResolver routeResolver = routeResolverBuilder.Value(builder); producer = new Producer(this._bus, configuration.Label, routeResolver, configuration.Options.IsConfirmationRequired()); producer.Failed += p => { { // lock (_producers) p.Dispose(); this._producers.Remove(p.Label); } }; // lock (_producers) this._producers.Add(configuration.Label, producer); } if (configuration.RequiresCallback) { producer.UseCallbackListener(this._bus.ListenerRegistry.ResolveFor(configuration.CallbackConfiguration)); } } return(producer); }
/// <summary> /// Builds a set of producers constructing one producer for each URL in the connection string /// </summary> private void BuildProducers() { var reuseConnectionProperty = this.senderOptions.GetReuseConnection(); var reuseConnection = reuseConnectionProperty.HasValue && reuseConnectionProperty.Value; this.logger.Trace( $"Building producers of [{this.Configuration.Label}]:\r\n\t{string.Join("\r\n\t", this.senderOptions.RabbitConnectionString.Select(url => $"Producer({this.Configuration.Label}): URL\t=>\t{url}"))}"); foreach (var url in this.senderOptions.RabbitConnectionString) { var source = new CancellationTokenSource(); var connection = this.connectionPool.Get(url, reuseConnection, source.Token); this.logger.Trace($"Using connection [{connection.Id}] at URL=[{url}] to resolve a producer"); var topologyBuilder = new TopologyBuilder(connection.OpenChannel()); var builder = new RouteResolverBuilder(this.bus.Endpoint, topologyBuilder, this.Configuration); var routeResolverBuilder = this.Configuration.Options.GetRouteResolverBuilder(); Assumes.True( routeResolverBuilder.HasValue, "RouteResolverBuilder must be set for [{0}]", this.Configuration.Label); var routeResolver = routeResolverBuilder.Value(builder); var producer = new Producer( this.bus.Endpoint, connection, this.Configuration.Label, routeResolver, this.Configuration.Options.IsConfirmationRequired()); producer.Failed += p => { // A failed producer will not be removed from the collection cause this failure should be treated as transient this.logger.Error($"Producer [{producer}] has failed"); }; if (this.Configuration.RequiresCallback) { var callbackConfiguration = this.Configuration.CallbackConfiguration; this.logger.Trace( $"A sender of [{this.Configuration.Label}] requires a callback configuration; registering a receiver of [{callbackConfiguration.Label}] with connection string [{callbackConfiguration.Options.GetConnectionString()}]"); var receiver = this.bus.RegisterReceiver(this.Configuration.CallbackConfiguration); this.logger.Trace( $"A new callback receiver of [{callbackConfiguration.Label}] with connection string [{callbackConfiguration.Options.GetConnectionString()}] has been successfully registered, getting one of its listeners with URL=[{producer.BrokerUrl}]..."); var listener = receiver.GetListener(l => l.BrokerUrl == producer.BrokerUrl); if (listener == null) { throw new BusConfigurationException( $"Unable to find a suitable listener for receiver {receiver}"); } this.logger.Trace( $"A listener at URL=[{listener.BrokerUrl}] belonging to callback receiver of [{callbackConfiguration.Label}] acquired"); producer.UseCallbackListener(listener); this.logger.Trace( $"A producer of [{producer.Label}] at URL=[{producer.BrokerUrl}] has registered a callback listener successfully"); } this.producers.Add(producer); this.logger.Trace( $"A producer of [{producer.Label}] at URL=[{producer.BrokerUrl}] has been added to the sender"); } }
private Producer BuildProducer(string url) { var reuseConnectionProperty = this.senderOptions.GetReuseConnection(); var reuseConnection = reuseConnectionProperty.HasValue && reuseConnectionProperty.Value; var source = new CancellationTokenSource(); var connection = this.connectionPool.Get(url, reuseConnection, source.Token); this.logger.Trace($"Using connection [{connection.Id}] at URL=[{url}] to resolve a producer"); using (var topologyBuilder = new TopologyBuilder(connection)) { var builder = new RouteResolverBuilder(this.bus.Endpoint, topologyBuilder, this.Configuration); var routeResolverBuilderFunc = this.Configuration.Options.GetRouteResolverBuilder(); Assumes.True( routeResolverBuilderFunc.HasValue, "RouteResolverBuilder must be set for [{0}]", this.Configuration.Label); var routeResolver = routeResolverBuilderFunc.Value(builder); var producer = new Producer( this.bus.Endpoint, connection, this.Configuration.Label, routeResolver, this.Configuration.Options.IsConfirmationRequired()); if (this.Configuration.RequiresCallback) { var callbackConfiguration = this.CreateCallbackReceiverConfiguration(url); var receiver = this.bus.RegisterReceiver(callbackConfiguration, true); this.logger.Trace( $"A sender of [{this.Configuration.Label}] requires a callback configuration; registering a receiver of [{callbackConfiguration.Label}] with connection string [{callbackConfiguration.Options.GetConnectionString()}]"); this.logger.Trace( $"A new callback receiver of [{callbackConfiguration.Label}] with connection string [{callbackConfiguration.Options.GetConnectionString()}] has been successfully registered, getting one of its listeners with URL=[{producer.BrokerUrl}]..."); var listener = receiver.GetListener(l => l.BrokerUrl == producer.BrokerUrl); if (listener == null) { throw new BusConfigurationException( $"Unable to find a suitable listener for receiver {receiver}"); } this.logger.Trace( $"A listener at URL=[{listener.BrokerUrl}] belonging to callback receiver of [{callbackConfiguration.Label}] acquired"); listener.StopOnChannelShutdown = true; producer.UseCallbackListener(listener); this.logger.Trace( $"A producer of [{producer.Label}] at URL=[{producer.BrokerUrl}] has registered a callback listener successfully"); } producer.StopOnChannelShutdown = true; producer.Stopped += (sender, args) => { this.OnProducerStopped(url, sender, args); }; return(producer); } }