Permalink
Browse files

Reverted to a better solution for handling serialization errors when …

…dequeueing in Rhino Queues.
  • Loading branch information...
1 parent b8bcb01 commit 23227543c8ada98b85ab4b925ecca837d9c29155 @CoreyKaylor CoreyKaylor committed Aug 4, 2010
@@ -144,7 +144,7 @@
<Compile Include="RhinoQueues\PhtSubscriptionStorageFixture.cs" />
<Compile Include="RhinoQueues\UsingRhinoQueuesBus.cs" />
<Compile Include="RhinoQueues\UsingRhinoQueuesTransport.cs" />
- <Compile Include="RhinoQueues\WhenSerializationErrorOccurs.cs" />
+ <Compile Include="RhinoQueues\WhenErrorOccurs.cs" />
<Compile Include="RhinoQueues\WithDebugging.cs" />
<Compile Include="SagaTests.cs" />
<Compile Include="TestExtensions.cs" />
@@ -1,5 +1,6 @@
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
- <ProjectView>ShowAllFiles</ProjectView>
+ <ProjectView>ProjectFiles</ProjectView>
</PropertyGroup>
</Project>
@@ -0,0 +1,113 @@
+using System;
+using System.IO;
+using System.Threading;
+using System.Transactions;
+using Castle.MicroKernel;
+using Rhino.ServiceBus.Impl;
+using Rhino.ServiceBus.Internal;
+using Rhino.ServiceBus.RhinoQueues;
+using Rhino.ServiceBus.Serializers;
+using Xunit;
+
+namespace Rhino.ServiceBus.Tests.RhinoQueues
+{
+ public class WhenErrorOccurs : IDisposable
+ {
+ private RhinoQueuesTransport transport;
+ private readonly ManualResetEvent wait = new ManualResetEvent(false);
+ private IMessageSerializer messageSerializer;
+
+ public int FailedCount;
+
+ public WhenErrorOccurs()
+ {
+ if (Directory.Exists("test.esent"))
+ Directory.Delete("test.esent", true);
+ }
+
+ [Fact]
+ public void Deserialization_Error_Will_Not_Retry()
+ {
+ messageSerializer = new ThrowingSerializer(new XmlMessageSerializer(new DefaultReflection(), new DefaultKernel()));
+ transport = new RhinoQueuesTransport(
+ new Uri("rhino.queues://localhost:23456/q"),
+ new EndpointRouter(),
+ messageSerializer,
+ 1,
+ "test.esent",
+ IsolationLevel.Serializable,
+ 5,
+ new RhinoQueuesMessageBuilder(messageSerializer)
+ );
+ transport.Start();
+ var count = 0;
+ transport.MessageProcessingFailure += (messageInfo, ex) =>
+ {
+ count++;
+ };
+ transport.Send(transport.Endpoint, new object[] { "test" });
+
+ wait.WaitOne(TimeSpan.FromSeconds(5));
+
+ Assert.Equal(1, count);
+ }
+
+ [Fact]
+ public void Arrived_Error_Will_Retry_Number_Of_Times_Configured()
+ {
+ messageSerializer = new XmlMessageSerializer(new DefaultReflection(), new DefaultKernel());
+ transport = new RhinoQueuesTransport(
+ new Uri("rhino.queues://localhost:23456/q"),
+ new EndpointRouter(),
+ messageSerializer,
+ 1,
+ "test.esent",
+ IsolationLevel.Serializable,
+ 5,
+ new RhinoQueuesMessageBuilder(messageSerializer)
+ );
+ transport.Start();
+ var count = 0;
+ transport.MessageArrived += info =>
+ {
+ throw new InvalidOperationException();
+ };
+ transport.MessageProcessingFailure += (messageInfo, ex) =>
+ {
+ count++;
+ };
+ transport.Send(transport.Endpoint, new object[] { "test" });
+
+ wait.WaitOne(TimeSpan.FromSeconds(5));
+
+ Assert.Equal(5, count);
+ }
+
+ public void Dispose()
+ {
+ transport.Dispose();
+ }
+ }
+
+ public class ThrowingSerializer : IMessageSerializer
+ {
+ private readonly XmlMessageSerializer serializer;
+
+ public ThrowingSerializer(XmlMessageSerializer serializer)
+ {
+ this.serializer = serializer;
+ }
+
+ public void Serialize(object[] messages, Stream message)
+ {
+ serializer.Serialize(messages, message);
+ }
+
+ public object[] Deserialize(Stream message)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+
+}
@@ -1,84 +0,0 @@
-using System;
-using System.IO;
-using System.Threading;
-using System.Transactions;
-using Castle.MicroKernel;
-using Rhino.ServiceBus.Impl;
-using Rhino.ServiceBus.Internal;
-using Rhino.ServiceBus.MessageModules;
-using Rhino.ServiceBus.RhinoQueues;
-using Rhino.ServiceBus.Serializers;
-using Xunit;
-
-namespace Rhino.ServiceBus.Tests.RhinoQueues
-{
- public class WhenSerializationErrorOccurs : IDisposable
- {
- private readonly RhinoQueuesTransport transport;
- private readonly ManualResetEvent wait = new ManualResetEvent(false);
- private readonly IMessageSerializer messageSerializer;
-
- public int FailedCount;
-
- public WhenSerializationErrorOccurs()
- {
- if (Directory.Exists("test.esent"))
- Directory.Delete("test.esent", true);
-
- messageSerializer = new ThrowingSerializer(new XmlMessageSerializer(new DefaultReflection(), new DefaultKernel()));
- transport = new RhinoQueuesTransport(
- new Uri("rhino.queues://localhost:23456/q"),
- new EndpointRouter(),
- messageSerializer,
- 1,
- "test.esent",
- IsolationLevel.Serializable,
- 5,
- new RhinoQueuesMessageBuilder(messageSerializer)
- );
- transport.Start();
- }
-
- [Fact]
- public void Will_Retry_Number_Of_Times_Configured()
- {
- var count = 0;
- transport.MessageProcessingFailure += (messageInfo, ex) =>
- {
- count++;
- };
- transport.Send(transport.Endpoint, new object[] { "test" });
-
- wait.WaitOne(TimeSpan.FromSeconds(5));
-
- Assert.Equal(5, count);
- }
-
- public void Dispose()
- {
- transport.Dispose();
- }
- }
-
- public class ThrowingSerializer : IMessageSerializer
- {
- private readonly XmlMessageSerializer serializer;
-
- public ThrowingSerializer(XmlMessageSerializer serializer)
- {
- this.serializer = serializer;
- }
-
- public void Serialize(object[] messages, Stream message)
- {
- serializer.Serialize(messages, message);
- }
-
- public object[] Deserialize(Stream message)
- {
- throw new NotImplementedException();
- }
- }
-
-
-}
@@ -1,5 +1,6 @@
using System;
using System.Text;
+using System.Transactions;
using Rhino.Queues;
using Rhino.Queues.Model;
using Rhino.ServiceBus.DataStructures;
@@ -29,47 +30,58 @@ public void Init(ITransport transport)
private bool Transport_OnMessageArrived(CurrentMessageInformation information)
{
- var info = (RhinoQueueCurrentMessageInformation) information;
- ErrorCounter val = null;
- failureCounts.Read(reader => reader.TryGetValue(info.TransportMessageId, out val));
- if (val != null)
- val.AtLeastOneMessageWasReceived = true;
- return MoveToErrorSubqueueIfReachedMaximumRetry(info, val);
- }
+ var info = (RhinoQueueCurrentMessageInformation)information;
+ ErrorCounter val = null;
+ failureCounts.Read(reader => reader.TryGetValue(info.TransportMessageId, out val));
+ if (val == null || val.FailureCount < numberOfRetries)
+ return false;
- private bool MoveToErrorSubqueueIfReachedMaximumRetry(RhinoQueueCurrentMessageInformation info, ErrorCounter errorCounter)
- {
- if(errorCounter == null || errorCounter.FailureCount < numberOfRetries)
- return false;
+ var result = false;
+ failureCounts.Write(writer =>
+ {
+ if (writer.TryGetValue(info.TransportMessageId, out val) == false)
+ return;
- failureCounts.Write(writer =>
- {
- if (writer.TryGetValue(info.TransportMessageId, out errorCounter) == false)
- return;
+ info.Queue.MoveTo(SubQueue.Errors.ToString(), info.TransportMessage);
+ info.Queue.EnqueueDirectlyTo(SubQueue.Errors.ToString(), new MessagePayload
+ {
+ Data = val.ExceptionText == null ? null : Encoding.Unicode.GetBytes(val.ExceptionText),
+ Headers =
+ {
+ {"correlation-id", info.TransportMessageId},
+ {"retries", val.FailureCount.ToString()}
+ }
+ });
- info.Queue.MoveTo(SubQueue.Errors.ToString(), info.TransportMessage);
- info.Queue.EnqueueDirectlyTo(SubQueue.Errors.ToString(), new MessagePayload
- {
- Data = errorCounter.ExceptionText == null ? null : Encoding.Unicode.GetBytes(errorCounter.ExceptionText),
- Headers =
- {
- {"correlation-id", info.TransportMessageId},
- {"retries", errorCounter.FailureCount.ToString()}
- }
- });
+ result = true;
+ });
- });
- return true;
- }
+ return result;
+ }
- private void Transport_OnMessageSerializationException(CurrentMessageInformation information, Exception exception)
+ private void Transport_OnMessageSerializationException(CurrentMessageInformation information, Exception exception)
{
- var info = (RhinoQueueCurrentMessageInformation) information;
+ var info = (RhinoQueueCurrentMessageInformation)information;
failureCounts.Write(writer => writer.Add(info.TransportMessageId, new ErrorCounter
{
ExceptionText = exception == null ? null : exception.ToString(),
FailureCount = numberOfRetries + 1
}));
+
+ using (var tx = new TransactionScope(TransactionScopeOption.RequiresNew))
+ {
+ info.Queue.MoveTo(SubQueue.Errors.ToString(), info.TransportMessage);
+ info.Queue.EnqueueDirectlyTo(SubQueue.Errors.ToString(), new MessagePayload
+ {
+ Data = exception == null ? null : Encoding.Unicode.GetBytes(exception.ToString()),
+ Headers =
+ {
+ {"correlation-id", info.TransportMessageId},
+ {"retries", "1"}
+ }
+ });
+ tx.Complete();
+ }
}
private void Transport_OnMessageProcessingCompleted(CurrentMessageInformation information, Exception ex)
@@ -98,9 +110,6 @@ private void Transport_OnMessageProcessingFailure(CurrentMessageInformation info
};
writer.Add(information.TransportMessageId, errorCounter);
}
-
- if (errorCounter.AtLeastOneMessageWasReceived == false)
- MoveToErrorSubqueueIfReachedMaximumRetry((RhinoQueueCurrentMessageInformation) information, errorCounter);
errorCounter.FailureCount += 1;
});
}
@@ -109,7 +118,6 @@ private class ErrorCounter
{
public string ExceptionText;
public int FailureCount;
- public bool AtLeastOneMessageWasReceived;
}
}
Oops, something went wrong.

0 comments on commit 2322754

Please sign in to comment.