I have ~2 dozen consumers that all handle the happy days scenario (no
exceptions). I then have a message module which will handle the
exceptions. the code my be easier to understand

    public class OutOfRetriesMessageModule : IMessageModule
    {
        private readonly IReflection reflection;
        private readonly int numberOfRetries;
        private readonly Hashtable<Guid, int> failures;

        private ITransport theTransport;

        public OutOfRetriesMessageModule(int numberOfRetries,
Hashtable<Guid, int> failures, IReflection reflection)
        {
            this.numberOfRetries = numberOfRetries;
            this.failures = failures;
            this.reflection = reflection;
        }

        public void Init(ITransport transport)
        {
            theTransport = transport;
            transport.MessageProcessingFailure +=
message_processing_failure_send_failure_notice_if_necessary;
            transport.MessageProcessingCompleted +=
message_processing_completed_clear_failures_if_necessary;
        }

        public void Stop(ITransport transport)
        {
            transport.MessageProcessingFailure -=
message_processing_failure_send_failure_notice_if_necessary;
            transport.MessageProcessingCompleted -=
message_processing_completed_clear_failures_if_necessary;
        }

        private void
message_processing_failure_send_failure_notice_if_necessary
(CurrentMessageInformation information, Exception exception)
        {
            var messageId = information.MessageId;
            if (exception == null) return;
            if(!typeof
(RequestToGenerateReportMessage).IsAssignableFrom
(information.Message.GetType())) return;

            increment_failed_attempts(messageId);
            if (!has_exceeded_number_of_retries(messageId)) return;

            send_failure_notice(information);
        }

        private void
message_processing_completed_clear_failures_if_necessary
(CurrentMessageInformation information, Exception exception)
        {
            if (exception != null) return;
            failures.Write(writer => writer.Remove
(information.MessageId));
        }

        private void increment_failed_attempts(Guid messageId)
        {
            failures.Write(writer =>
                               {
                                   int attempts;
                                   writer.TryGetValue(messageId, out
attempts);
                                   writer.Add(messageId, ++attempts);
                               });
        }

        private bool has_exceeded_number_of_retries(Guid id)
        {
            var attempts = 0;
            failures.Read(reader => reader.TryGetValue(id, out
attempts));
            return attempts >= numberOfRetries;
        }

        private void send_failure_notice(CurrentMessageInformation
information)
        {
            var message = information.Message;
            var generatedReportFailed = new ReportGeneratedMessage
                              {
                                  instance_id =
reflection.parse_instance_id(message),
                                  date = reflection.parse_date
(message),
                                  region_id =
reflection.parse_region_id(message),
                                  report_id =
reflection.parse_report_id(message),
                                  file_name = "",
                                  success = false
                              };
            theTransport.Reply(generatedReportFailed);
        }
    }

the problem is the system is not throwing an excpetion and I'm not
consuming the generatedReportFailed message on the other end. if I
move the send_failure_notice logic into the Consume() member of each
consumer wrapped in a try/catch the workflow is processed correctly
and I receive a failure notice on the other end.

it what i'm trying to do possible? send/reply a message from within
the message module? it would seem I don't need to wrap this in a
transactionscope because theTransport will handle that for me. the
Transport implementation is RQ.

I also tried
theTransport.Send(new EndPoint{Url=information.Source}, new object[]
{generatedReportFailed});
but that was throwing timeout exceptions. (duration cannot be
negative). or just not working at all.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Rhino Tools Dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rhino-tools-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to