private bool HandledMaxRetries(TransportMessage message) { string messageId = message.Id; failuresPerMessageLocker.EnterReadLock(); if (failuresPerMessage.ContainsKey(messageId) && (failuresPerMessage[messageId] >= maxRetries)) { failuresPerMessageLocker.ExitReadLock(); failuresPerMessageLocker.EnterWriteLock(); var ex = exceptionsForMessages[messageId]; FailureManager.ProcessingAlwaysFailsForMessage(message, ex); failuresPerMessage.Remove(messageId); exceptionsForMessages.Remove(messageId); failuresPerMessageLocker.ExitWriteLock(); return(true); } failuresPerMessageLocker.ExitReadLock(); return(false); }
void ITransport.Start(Address address) { MessageReceiver.Init(address, IsTransactional); var returnAddressForFailures = address; //figure out if this transport is the one feeding messages into the unicastbus if (returnAddressForFailures.Queue.ToLower().EndsWith(".worker") || address == Address.Local) //this is a hack until we can refactor the SLR to be a feature. "Worker" is there to catch the local worker in the distributor { //GetMasterNodeAddress returns Address.Local if no masternode is defined so we can safely call this for all endpoints returnAddressForFailures = Configure.Instance.GetMasterNodeAddress(); if (address != returnAddressForFailures) { Logger.InfoFormat("Worker started, failures will be redirected to {0}", returnAddressForFailures); } } FailureManager.Init(returnAddressForFailures); Logger.DebugFormat("Going to start [{0}] receiving thread/s for Address [{1}].", numberOfWorkerThreads, address); for (int i = 0; i < numberOfWorkerThreads; i++) { AddWorkerThread().Start(); } }
void ITransport.Start(Address address) { MessageReceiver.Init(address, IsTransactional); FailureManager.Init(address); Logger.DebugFormat("Going to start [{0}] receiving thread/s for Address [{1}].", numberOfWorkerThreads, address); for (int i = 0; i < numberOfWorkerThreads; i++) { AddWorkerThread().Start(); } }
void ITransport.Start(Address address) { MessageReceiver.Init(address, IsTransactional); FailureManager.Init(address); for (int i = 0; i < numberOfWorkerThreads; i++) { AddWorkerThread().Start(); } }
void InvokeFaultManager(TransportMessage message, Exception exception) { try { FailureManager.ProcessingAlwaysFailsForMessage(message, exception); } catch (Exception ex) { Logger.FatalFormat("Fault manager failed to process the failed message {0}", ex, message); Configure.Instance.OnCriticalError(); } }
/// <summary> /// Starts the transport listening for messages on the given local address. /// </summary> public void Start(Address address) { if (isStarted) { throw new InvalidOperationException("The transport is already started"); } receiveAddress = address; var returnAddressForFailures = address; var workerRunsOnThisEndpoint = settings.GetOrDefault <bool>("Worker.Enabled"); if (workerRunsOnThisEndpoint && (returnAddressForFailures.Queue.ToLower().EndsWith(".worker") || address == config.LocalAddress)) //this is a hack until we can refactor the SLR to be a feature. "Worker" is there to catch the local worker in the distributor { returnAddressForFailures = settings.Get <Address>("MasterNode.Address"); Logger.InfoFormat("Worker started, failures will be redirected to {0}", returnAddressForFailures); } FailureManager.Init(returnAddressForFailures); firstLevelRetries = new FirstLevelRetries(TransactionSettings.MaxRetries, FailureManager, CriticalError); InitializePerformanceCounters(); throughputLimiter = new ThroughputLimiter(); throughputLimiter.Start(MaximumMessageThroughputPerSecond); StartReceiver(); if (MaximumMessageThroughputPerSecond > 0) { Logger.InfoFormat("Transport: {0} started with its throughput limited to {1} msg/sec", receiveAddress, MaximumMessageThroughputPerSecond); } isStarted = true; }
void ProcessMessage(TransportMessage message) { if (string.IsNullOrWhiteSpace(message.Id)) { Logger.Error("Message without message id detected"); FailureManager.SerializationFailedForMessage(message, new SerializationException("Message without message id received.")); return; } var exceptionFromStartedMessageHandling = OnStartedMessageProcessing(message); if (TransactionSettings.IsTransactional) { if (firstLevelRetries.HasMaxRetriesForMessageBeenReached(message)) { OnFinishedMessageProcessing(message); return; } } if (exceptionFromStartedMessageHandling != null) { throw exceptionFromStartedMessageHandling; //cause rollback } //care about failures here var exceptionFromMessageHandling = OnTransportMessageReceived(message); //and here var exceptionFromMessageModules = OnFinishedMessageProcessing(message); //but need to abort takes precedence - failures aren't counted here, //so messages aren't moved to the error queue. if (needToAbort) { return; } if (exceptionFromMessageHandling != null) { if (exceptionFromMessageHandling is AggregateException) { var serializationException = exceptionFromMessageHandling.GetBaseException() as SerializationException; if (serializationException != null) { Logger.Error("Failed to serialize message with ID: " + message.Id, serializationException); message.RevertToOriginalBodyIfNeeded(); FailureManager.SerializationFailedForMessage(message, serializationException); } else { throw exceptionFromMessageHandling;//cause rollback } } else { throw exceptionFromMessageHandling;//cause rollback } } if (exceptionFromMessageModules != null) //cause rollback { throw exceptionFromMessageModules; } }
void ProcessMessage(TransportMessage message) { try { OnStartedMessageProcessing(message); } catch (Exception exception) { Logger.Error("Failed raising 'started message processing' event.", exception); if (ShouldExitBecauseOfRetries(message)) { return; } throw; } if (string.IsNullOrWhiteSpace(message.Id)) { Logger.Error("Message without message id detected"); FailureManager.SerializationFailedForMessage(message, new SerializationException("Message without message id received.")); return; } if (ShouldExitBecauseOfRetries(message)) { try { OnFinishedMessageProcessing(message); } catch (Exception exception) { Logger.Error("Failed raising 'finished message processing' event.", exception); } return; } try { OnTransportMessageReceived(message); } catch (SerializationException serializationException) { Logger.Error("Failed to deserialize message with ID: " + message.Id, serializationException); message.RevertToOriginalBodyIfNeeded(); FailureManager.SerializationFailedForMessage(message, serializationException); } catch (Exception) { //but need to abort takes precedence - failures aren't counted here, //so messages aren't moved to the error queue. if (!needToAbort) { throw; } } finally { try { OnFinishedMessageProcessing(message); } catch (Exception exception) { Logger.Error("Failed raising 'finished message processing' event.", exception); //but need to abort takes precedence - failures aren't counted here, //so messages aren't moved to the error queue. if (!needToAbort) { throw; } } } }