Jaimin Gandhi

Jaimin Gandhi

  • NA
  • 1
  • 2.8k

Dead letter queue service stops picking up messages

Dec 15 2010 4:32 PM

Hi
I have a custom dead letter queue service to pick up messages from DLQ. This service picks up failed message from DLQ and tries to resend to a different end point. If the new endpoint doesn't work, it rolls back transaction. This works great. Here is the code.
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
        ConcurrencyMode = ConcurrencyMode.Single,
        AddressFilterMode = AddressFilterMode.Any)]
    public class FDPDLQService : IFDService
    {
        FDPManager _fdpManager = new FDPManager();
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void ProcessFDMessage(FDMessage message)
        {
            //System.Diagnostics.Debugger.Launch();
            try
            {
                MsmqMessageProperty mqProp =
                    OperationContext.Current.IncomingMessageProperties[MsmqMessageProperty.Name] as MsmqMessageProperty;
                // if message log required, and configured, log the incoming message
                try
                {
                ChannelFactory<IFDPRouter> factory = new ChannelFactory<IFDPRouter>("IFDPRouter_EP");
                IFDPRouter proxy = factory.CreateChannel();
                string ep = proxy.GetNextEPForGivenEP(OperationContext.Current.IncomingMessageHeaders.To.ToString());
                if (ep == null || ep == string.Empty)
                {
                    throw new EndpointNotFoundException(Common.Constants.FDP_NOT_FOUND_EXCEPTION_MESSAGE);
                }
                // Process message with next end point available
                _fdpManager.ProcessFDMessage(message, ep);
            }
            catch (EndpointNotFoundException enfe)
            {
                ExceptionManager.HandleException(enfe);
                Transaction.Current.Rollback();
                //throw;
            }
            catch (Exception ex)
            {
                ExceptionManager.HandleException(ex);
                Transaction.Current.Rollback();
                //throw;
            }
        }
    }
}
Below is config entries.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netMsmqBinding>
              <binding name="DLQServiceBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
            receiveTimeout="00:10:00" sendTimeout="00:01:00"  deadLetterQueue="Custom" customDeadLetterQueue ="net.msmq://localhost/private/FDPDLQ"
            durable="true" exactlyOnce="true" maxReceivedMessageSize="65536"
            maxRetryCycles="2" receiveErrorHandling="Fault" receiveRetryCount="5"
            retryCycleDelay="00:30:00" timeToLive="00:01:00" useSourceJournal="false"
            useMsmqTracing="false" queueTransferProtocol="Native" maxBufferPoolSize="524288"
            useActiveDirectory="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="None">
                  <transport msmqAuthenticationMode="WindowsDomain" msmqEncryptionAlgorithm="RC4Stream"
                      msmqProtectionLevel="Sign" msmqSecureHashAlgorithm="Sha1" />
                  <message clientCredentialType="Windows" />
                </security>
                <!--deadLetterQueue="System">-->
              </binding>
              <binding name="DefaultBinding" >
                <security mode="None" />
              </binding>
                <binding name="FDService_EP" closeTimeout="00:01:00" openTimeout="00:01:00" deadLetterQueue="Custom" customDeadLetterQueue ="net.msmq://localhost/private/FDPDLQ"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    durable="true" exactlyOnce="true" maxReceivedMessageSize="65536"
                    maxRetryCycles="2" receiveErrorHandling="Fault" receiveRetryCount="5"
                    retryCycleDelay="00:30:00" timeToLive="00:01:00" useSourceJournal="false"
                    useMsmqTracing="false" queueTransferProtocol="Native" maxBufferPoolSize="524288"
                    useActiveDirectory="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport msmqAuthenticationMode="WindowsDomain" msmqEncryptionAlgorithm="RC4Stream"
                            msmqProtectionLevel="Sign" msmqSecureHashAlgorithm="Sha1" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
                <binding name="FDChecking_EP" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" deadLetterQueue="System"
                    durable="true" exactlyOnce="true" maxReceivedMessageSize="65536"
                    maxRetryCycles="2" receiveErrorHandling="Fault" receiveRetryCount="5"
                    retryCycleDelay="00:30:00" timeToLive="1.00:00:00" useSourceJournal="false"
                    useMsmqTracing="false" queueTransferProtocol="Native" maxBufferPoolSize="524288"
                    useActiveDirectory="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport msmqAuthenticationMode="WindowsDomain" msmqEncryptionAlgorithm="RC4Stream"
                            msmqProtectionLevel="Sign" msmqSecureHashAlgorithm="Sha1" />
                        <message clientCredentialType="Windows" />
                    </security>
                </binding>
            </netMsmqBinding>
            <netNamedPipeBinding>
                <binding name="Teletrac.EFX.Interfaces.FDService.IFDPRouter" />
            </netNamedPipeBinding>
        </bindings>
      <behaviors>
        <serviceBehaviors>
          <behavior name="DLQServiceBehaviour">
            <serviceDebug includeExceptionDetailInFaults="true"/>
          </behavior>
        </serviceBehaviors>
      </behaviors>
      <services>
        <service name="Teletrac.Customer.Services.FDPDLQService.FDPDLQService" >
          <endpoint address="net.msmq://localhost/private/FDPDLQ" binding="netMsmqBinding"
                    contract="FDPServiceRef.IFDService"
                    bindingConfiguration="DefaultBinding"></endpoint>
        </service>
      </services>
        <client>
            <endpoint address="net.msmq://localhost/private/fdmessageQueue"
                binding="netMsmqBinding" bindingConfiguration="DLQServiceBinding"
                contract="FDPServiceRef.IFDService" name="FDService_EP" />
        </client>
    </system.serviceModel>
</configuration>
This works great.
But if all endpoints are not available for a long period of time, and if service rolls message back to the DLQ for a long period of time, after a certain period of time service stops picking up messages from DLQ. I am not sure which configuration is responsible for this. Can you guide me?
Regards
Jaimin Gandhi.

Answers (1)