/// <summary> /// Sends a message to the specified destination. /// </summary> /// <param name="m">The message to send.</param> /// <param name="destination">The address of the destination to send the message to.</param> public void Send(TransportMessage m, string destination) { System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); MQMessage queueMessage = Convert(m); try { var failover = WmqTransportFailover.GetInstance(); // Delay sending to the failover queue if it's still processing and the user has configured a wait time. if (failover.IsFailoverEnabled && failover.Processing && failover.FailoverWaitTime > 0) { Thread.Sleep(failover.FailoverWaitTime); } // Attempt to send message if failover feature is not enabled // else confirm there is not already a known issue sending // to the primary destination queue. // If the primary queue is online and we are still processing it, // put message on failover queue anyway to preserve order. if (!IsFailoverEnabled || (IsFailoverEnabled && WmqTransportFailover.IsPrimaryQueueOnline && !WmqTransportFailover.IsProcessing)) { Send(queueMessage, destination); } else // Is Failover feature is enabled and an issue has already been // identified sending to the primary destination queue { WmqTransportFailover.Failover(m, destination); } m.Id = encoding.GetString(queueMessage.MessageId); } catch (Exception ex) { logger.Error("Error sending message to " + destination, ex); if (IsFailoverEnabled) { WmqTransportFailover.Failover(m, destination); } else { throw; } } }
/// <summary> /// Starts the transport. /// </summary> public void Start() { InitializeQueueManager(receiveResourceManager); InitializeInputQueue(receiveResourceManager); InitializeQueueManager(sendResourceManager); InitializeInputQueue(sendResourceManager); //CheckConfiguration(); //CreateQueuesIfNecessary(); if (this.purgeOnStartup) { PurgeInputQueue(); } IEnumerable <IMessageModule> mods = Builder.BuildAll <IMessageModule>(); if (mods != null) { this.modules.AddRange(mods); } for (int i = 0; i < this._numberOfWorkerThreads; i++) { this.AddWorkerThread().Start(); } if (IsFailoverEnabled) { WmqTransportFailover.Inititialize(IsTransactional, messageSerializer, ChannelInfo , FailoverQueueName, FailoverRetryInterval, FailoverWaitInterval); if (_failoverProcessingOnStartup == FailoverProcessing.Process) { WmqTransportFailover.Process(); } else if (_failoverProcessingOnStartup == FailoverProcessing.Purge) { WmqTransportFailover.Purge(); } } }
public static WmqTransportFailover GetInstance() { //The approach below ensures that only one instance is created and only //when the instance is needed. Also, the uniqueInstance variable is //declared to be volatile to ensure that assignment to the instance variable //completes before the instance variable can be accessed. Lastly, //this approach uses a syncRoot instance to lock on, rather than //locking on the type itself, to avoid deadlocks. if (uniqueInstance == null) { lock (syncRoot) { if (uniqueInstance == null) { uniqueInstance = new WmqTransportFailover(); } } } return(uniqueInstance); }