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
-~----------~----~----~----~------~----~------~--~---