From 9a938452c424be1069235aed8ac448b855235d7b Mon Sep 17 00:00:00 2001 From: David Lee Date: Sat, 5 Oct 2024 00:04:25 +0800 Subject: [PATCH] Add binary serialization support for circuit breaker exception RetryAfter property. --- .../CircuitBreaker/BrokenCircuitException.cs | 26 +++++++++++++++++++ .../BrokenCircuitExceptionTests.cs | 22 ++++++++++++++-- .../IsolatedCircuitExceptionTests.cs | 11 ++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/Polly.Core/CircuitBreaker/BrokenCircuitException.cs b/src/Polly.Core/CircuitBreaker/BrokenCircuitException.cs index 744bf1d31a8..6238950613c 100644 --- a/src/Polly.Core/CircuitBreaker/BrokenCircuitException.cs +++ b/src/Polly.Core/CircuitBreaker/BrokenCircuitException.cs @@ -76,6 +76,32 @@ public BrokenCircuitException(string message, TimeSpan retryAfter, Exception inn protected BrokenCircuitException(SerializationInfo info, StreamingContext context) : base(info, context) { + Guard.NotNull(info); + + // https://github.com/dotnet/runtime/issues/42460 + SerializationInfoEnumerator enumerator = info.GetEnumerator(); + while (enumerator.MoveNext()) + { + SerializationEntry entry = enumerator.Current; + if (string.Equals(entry.Name, "RetryAfter", StringComparison.Ordinal)) + { + var ticks = (long)entry.Value; + RetryAfter = new TimeSpan(ticks); + break; + } + } + } + + /// + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + Guard.NotNull(info); + if (RetryAfter.HasValue) + { + info.AddValue("RetryAfter", RetryAfter.Value.Ticks); + } + + base.GetObjectData(info, context); } #endif #pragma warning restore RS0016 // Add public types and members to the declared API diff --git a/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs b/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs index d386e4288bf..70f9dc128bc 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs @@ -56,8 +56,26 @@ public void Ctor_Message_RetryAfter_InnerException_Ok() #if !NETCOREAPP [Fact] - public void BinarySerialization_Ok() => - BinarySerializationUtil.SerializeAndDeserializeException(new BrokenCircuitException()).Should().NotBeNull(); + public void BinarySerialization_NonNullRetryAfter_Ok() + { + var exception = new BrokenCircuitException(TestMessage, TestRetryAfter, new InvalidOperationException()); + BrokenCircuitException roundtripResult = BinarySerializationUtil.SerializeAndDeserializeException(exception); + roundtripResult.Should().NotBeNull(); + roundtripResult.Message.Should().Be(TestMessage); + roundtripResult.InnerException.Should().BeOfType(); + roundtripResult.RetryAfter.Should().Be(TestRetryAfter); + } + + [Fact] + public void BinarySerialization_NullRetryAfter_Ok() + { + var exception = new BrokenCircuitException(TestMessage, new InvalidOperationException()); + BrokenCircuitException roundtripResult = BinarySerializationUtil.SerializeAndDeserializeException(exception); + roundtripResult.Should().NotBeNull(); + roundtripResult.Message.Should().Be(TestMessage); + roundtripResult.InnerException.Should().BeOfType(); + roundtripResult.RetryAfter.Should().BeNull(); + } #endif private const string TestMessage = "Dummy."; diff --git a/test/Polly.Core.Tests/CircuitBreaker/IsolatedCircuitExceptionTests.cs b/test/Polly.Core.Tests/CircuitBreaker/IsolatedCircuitExceptionTests.cs index 09413c8a1ee..7a76a623229 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/IsolatedCircuitExceptionTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/IsolatedCircuitExceptionTests.cs @@ -31,8 +31,15 @@ public void Ctor_Message_InnerException_Ok() #if !NETCOREAPP [Fact] - public void BinarySerialization_Ok() => - BinarySerializationUtil.SerializeAndDeserializeException(new IsolatedCircuitException("dummy")).Should().NotBeNull(); + public void BinarySerialization_Ok() + { + var exception = new IsolatedCircuitException(TestMessage, new InvalidOperationException()); + IsolatedCircuitException roundtripResult = BinarySerializationUtil.SerializeAndDeserializeException(exception); + roundtripResult.Should().NotBeNull(); + roundtripResult.Message.Should().Be(TestMessage); + roundtripResult.InnerException.Should().BeOfType(); + roundtripResult.RetryAfter.Should().BeNull(); + } #endif private const string TestMessage = "Dummy.";