Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/Polly.Core/ResilienceStrategy.DebuggerProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
namespace Polly;

public abstract partial class ResilienceStrategy
{
internal class DebuggerProxy
{
private readonly ResilienceStrategy _resilienceStrategy;

public DebuggerProxy(ResilienceStrategy resilienceStrategy) => _resilienceStrategy = resilienceStrategy;

[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public IEnumerable<ResilienceStrategy> Strategies => UnwrapStrategies(_resilienceStrategy);

private IEnumerable<ResilienceStrategy> UnwrapStrategies(ResilienceStrategy strategy)
{
if (strategy is ResilienceStrategyPipeline pipeline)
{
return pipeline.Strategies;
}

if (strategy is ReloadableResilienceStrategy reloadableResilienceStrategy)
{
var list = new List<ResilienceStrategy>
{
strategy
};
list.AddRange(UnwrapStrategies(reloadableResilienceStrategy.Strategy));

return list;
}

return new[] { strategy };
}
}
}
3 changes: 3 additions & 0 deletions src/Polly.Core/ResilienceStrategy.TResult.Async.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Polly.Utils;

namespace Polly;

/// <summary>
Expand All @@ -8,6 +10,7 @@ namespace Polly;
/// Resilience strategy supports various types of callbacks of <typeparamref name="TResult"/> result type
/// and provides a unified way to execute them. This includes overloads for synchronous and asynchronous callbacks.
/// </remarks>
[DebuggerTypeProxy(typeof(ResilienceStrategy<>.DebuggerProxy))]
public partial class ResilienceStrategy<TResult>
{
internal ResilienceStrategy(ResilienceStrategy strategy) => Strategy = strategy;
Expand Down
14 changes: 14 additions & 0 deletions src/Polly.Core/ResilienceStrategy.TResult.DebuggerProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Polly;

public partial class ResilienceStrategy<TResult>
{
internal class DebuggerProxy
{
private readonly ResilienceStrategy.DebuggerProxy _proxy;

public DebuggerProxy(ResilienceStrategy<TResult> strategy) => _proxy = new ResilienceStrategy.DebuggerProxy(strategy.Strategy);

[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public IEnumerable<ResilienceStrategy> Strategies => _proxy.Strategies;
}
}
1 change: 1 addition & 0 deletions src/Polly.Core/ResilienceStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Polly;
/// Resilience strategy supports various types of callbacks and provides a unified way to execute them.
/// This includes overloads for synchronous and asynchronous callbacks, generic and non-generic callbacks.
/// </remarks>
[DebuggerTypeProxy(typeof(DebuggerProxy))]
public abstract partial class ResilienceStrategy
{
/// <summary>
Expand Down
3 changes: 3 additions & 0 deletions src/Polly.Core/Utils/ResilienceStrategyPipeline.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using System.Diagnostics;

namespace Polly.Utils;

#pragma warning disable S2302 // "nameof" should be used

/// <summary>
/// A pipeline of strategies.
/// </summary>
[DebuggerDisplay("ResilienceStrategyPipeline, Strategies = {Strategies.Count}")]
internal sealed class ResilienceStrategyPipeline : ResilienceStrategy
{
private readonly ResilienceStrategy _pipeline;
Expand Down
19 changes: 19 additions & 0 deletions test/Polly.Core.Tests/ResilienceStrategyTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using Moq;
using Polly.Utils;

namespace Polly.Core.Tests;

public partial class ResilienceStrategyTests
Expand Down Expand Up @@ -28,6 +31,22 @@ await TestUtilities.AssertWithTimeoutAsync(async () =>
});
}

[Fact]
public void DebuggerProxy_Ok()
{
var pipeline = ResilienceStrategyPipeline.CreatePipeline(new[]
{
new TestResilienceStrategy(),
new TestResilienceStrategy()
});
var reloadable = new ReloadableResilienceStrategy(pipeline, () => default, () => pipeline, TestUtilities.CreateResilienceTelemetry(Mock.Of<DiagnosticSource>()));

new ResilienceStrategy.DebuggerProxy(NullResilienceStrategy.Instance).Strategies.Should().HaveCount(1);
new ResilienceStrategy.DebuggerProxy(pipeline).Strategies.Should().HaveCount(2);
new ResilienceStrategy.DebuggerProxy(reloadable).Strategies.Should().HaveCount(3);
new ResilienceStrategy<string>.DebuggerProxy(NullResilienceStrategy<string>.Instance).Strategies.Should().HaveCount(1);
}

public class ExecuteParameters<T> : ExecuteParameters
{
public ExecuteParameters(Func<ResilienceStrategy, Task<T>> execute, T resultValue)
Expand Down