Skip to content

Commit

Permalink
Add TelemetrySource to RateLimiterRejectedException
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-csala committed Oct 16, 2024
1 parent 14ac109 commit cfb42a9
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 7 deletions.
6 changes: 5 additions & 1 deletion src/Polly.Core/Telemetry/ResilienceStrategyTelemetry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ internal ResilienceStrategyTelemetry(ResilienceTelemetrySource source, Telemetry

internal TelemetryListener? Listener { get; }

internal ResilienceTelemetrySource TelemetrySource { get; }
/// <summary>
/// Gets BlahBlahBlah.
/// </summary>
/// <value>dummy.</value>
public ResilienceTelemetrySource TelemetrySource { get; } // TODO: fix visibility

/// <summary>
/// Reports an event that occurred in a resilience strategy.
Expand Down
3 changes: 3 additions & 0 deletions src/Polly.RateLimiting/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#nullable enable
Polly.RateLimiting.RateLimiterRejectedException.RateLimiterRejectedException(Polly.Telemetry.ResilienceTelemetrySource! telemetrySource) -> void
Polly.RateLimiting.RateLimiterRejectedException.RateLimiterRejectedException(Polly.Telemetry.ResilienceTelemetrySource! telemetrySource, System.TimeSpan retryAfter) -> void
Polly.RateLimiting.RateLimiterRejectedException.TelemetrySource.get -> string?
49 changes: 44 additions & 5 deletions src/Polly.RateLimiting/RateLimiterRejectedException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#endif
using System.Threading.RateLimiting;

using Polly.Telemetry;

namespace Polly.RateLimiting;

/// <summary>
Expand All @@ -21,6 +23,19 @@ public RateLimiterRejectedException()
{
}

/// <summary>
/// Initializes a new instance of the <see cref="RateLimiterRejectedException"/> class.
/// </summary>
/// <param name="telemetrySource">The source pipeline and strategy names.</param>
public RateLimiterRejectedException(ResilienceTelemetrySource telemetrySource)
: base("The operation could not be executed because it was rejected by the rate limiter.")
{
var pipelineName = telemetrySource?.PipelineName ?? "(null)";
var pipelineInstanceName = telemetrySource?.PipelineInstanceName ?? "(null)";
var strategyName = telemetrySource?.StrategyName ?? "(null)";
TelemetrySource = $"{pipelineName}/{pipelineInstanceName}/{strategyName}";
}

/// <summary>
/// Initializes a new instance of the <see cref="RateLimiterRejectedException"/> class.
/// </summary>
Expand All @@ -29,6 +44,21 @@ public RateLimiterRejectedException(TimeSpan retryAfter)
: base($"The operation could not be executed because it was rejected by the rate limiter. It can be retried after '{retryAfter}'.")
=> RetryAfter = retryAfter;

/// <summary>
/// Initializes a new instance of the <see cref="RateLimiterRejectedException"/> class.
/// </summary>
/// <param name="telemetrySource">The source pipeline and strategy names.</param>
/// <param name="retryAfter">The retry after value.</param>
public RateLimiterRejectedException(ResilienceTelemetrySource telemetrySource, TimeSpan retryAfter)
: base($"The operation could not be executed because it was rejected by the rate limiter. It can be retried after '{retryAfter}'.")
{
var pipelineName = telemetrySource?.PipelineName ?? "(null)";
var pipelineInstanceName = telemetrySource?.PipelineInstanceName ?? "(null)";
var strategyName = telemetrySource?.StrategyName ?? "(null)";
TelemetrySource = $"{pipelineName}/{pipelineInstanceName}/{strategyName}";
RetryAfter = retryAfter;
}

/// <summary>
/// Initializes a new instance of the <see cref="RateLimiterRejectedException"/> class.
/// </summary>
Expand Down Expand Up @@ -74,6 +104,11 @@ public RateLimiterRejectedException(string message, TimeSpan retryAfter, Excepti
/// </remarks>
public TimeSpan? RetryAfter { get; }

/// <summary>
/// Gets the name of the strategy which has thrown the exception.
/// </summary>
public string? TelemetrySource { get; }

#pragma warning disable RS0016 // Add public types and members to the declared API
#if !NETCOREAPP
/// <summary>
Expand All @@ -84,25 +119,29 @@ public RateLimiterRejectedException(string message, TimeSpan retryAfter, Excepti
private RateLimiterRejectedException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
var value = info.GetDouble("RetryAfter");
if (value >= 0.0)
var retryAfter = info.GetDouble(nameof(RetryAfter));
if (retryAfter >= 0.0)
{
RetryAfter = TimeSpan.FromSeconds(value);
RetryAfter = TimeSpan.FromSeconds(retryAfter);
}

Source = info.GetString(nameof(Source));
}

/// <inheritdoc/>
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
Guard.NotNull(info);

info.AddValue(nameof(Source), Source);

if (RetryAfter.HasValue)
{
info.AddValue("RetryAfter", RetryAfter.Value.TotalSeconds);
info.AddValue(nameof(RetryAfter), RetryAfter.Value.TotalSeconds);
}
else
{
info.AddValue("RetryAfter", -1.0);
info.AddValue(nameof(RetryAfter), -1.0);
}

base.GetObjectData(info, context);
Expand Down
3 changes: 2 additions & 1 deletion src/Polly.RateLimiting/RateLimiterResilienceStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ protected override async ValueTask<Outcome<TResult>> ExecuteCore<TResult, TState
await OnLeaseRejected(new OnRateLimiterRejectedArguments(context, lease)).ConfigureAwait(context.ContinueOnCapturedContext);
}

var exception = retryAfter.HasValue ? new RateLimiterRejectedException(retryAfter.Value) : new RateLimiterRejectedException();
var source = _telemetry.TelemetrySource;
var exception = retryAfter.HasValue ? new RateLimiterRejectedException(source, retryAfter.Value) : new RateLimiterRejectedException(source);

return Outcome.FromException<TResult>(exception.TrySetStackTrace());
}
Expand Down

0 comments on commit cfb42a9

Please sign in to comment.