Skip to content

Commit

Permalink
Sync TimeProvider and cleanup (#1339)
Browse files Browse the repository at this point in the history
  • Loading branch information
martintmk authored Jun 22, 2023
1 parent 1a72192 commit 18171df
Show file tree
Hide file tree
Showing 49 changed files with 121 additions and 258 deletions.
3 changes: 0 additions & 3 deletions Polly.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
build.cake = build.cake
.github\workflows\build.yml = .github\workflows\build.yml
.github\dependabot.yml = .github\dependabot.yml
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
Directory.Packages.props = Directory.Packages.props
GitVersion.yml = GitVersion.yml
global.json = global.json
README.md = README.md
Version.props = Version.props
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polly", "src\Polly\Polly.csproj", "{E273E6D8-87D4-4EC9-A2BE-734DD633EF15}"
Expand Down
10 changes: 2 additions & 8 deletions bench/Polly.Core.Benchmarks/GenericOverheadBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,12 @@ public GenericOverheadBenchmark()
public class GenericStrategy<T>
{
[MethodImpl(MethodImplOptions.NoOptimization)]
public virtual ValueTask<T> ExecuteAsync(Func<ValueTask<T>> callback)
{
return callback();
}
public virtual ValueTask<T> ExecuteAsync(Func<ValueTask<T>> callback) => callback();
}

public class NonGenericStrategy
{
[MethodImpl(MethodImplOptions.NoOptimization)]
public virtual ValueTask<T> ExecuteAsync<T>(Func<ValueTask<T>> callback)
{
return callback();
}
public virtual ValueTask<T> ExecuteAsync<T>(Func<ValueTask<T>> callback) => callback();
}
}
4 changes: 1 addition & 3 deletions bench/Polly.Core.Benchmarks/HedgingBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ public class HedgingBenchmark
private ResilienceStrategy<string>? _strategy;

[GlobalSetup]
public void Setup()
{
public void Setup() =>
_strategy = Helper.CreateHedging();
}

[Benchmark(Baseline = true)]
public async ValueTask Hedging_Primary()
Expand Down
4 changes: 1 addition & 3 deletions bench/Polly.Core.Benchmarks/PredicateBenchmark.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.Net;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

namespace Polly.Core.Benchmarks;

Expand Down
1 change: 0 additions & 1 deletion bench/Polly.Core.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
using Polly.Core.Benchmarks;

var config = ManualConfig
.Create(DefaultConfig.Instance)
Expand Down
4 changes: 1 addition & 3 deletions bench/Polly.Core.Benchmarks/Utils/MeteringUtil.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using System.Diagnostics.Metrics;

namespace Polly.Core.Benchmarks.Utils;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ private void CloseCircuit_NeedsLock(Outcome<T> outcome, bool manual, ResilienceC

private bool PermitHalfOpenCircuitTest_NeedsLock()
{
var now = _timeProvider.UtcNow;
var now = _timeProvider.GetUtcNow();
if (now >= _blockedUntil)
{
_blockedUntil = now + _breakDuration;
Expand Down Expand Up @@ -312,7 +312,7 @@ private void OpenCircuit_NeedsLock(Outcome<T> outcome, bool manual, ResilienceCo
private void OpenCircuitFor_NeedsLock(Outcome<T> outcome, TimeSpan breakDuration, bool manual, ResilienceContext context, out Task? scheduledTask)
{
scheduledTask = null;
var utcNow = _timeProvider.UtcNow;
var utcNow = _timeProvider.GetUtcNow();

_blockedUntil = IsDateTimeOverflow(utcNow, breakDuration) ? DateTimeOffset.MaxValue : utcNow + breakDuration;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public override HealthInfo GetHealthInfo()

private HealthWindow UpdateCurrentWindow()
{
var now = TimeProvider.UtcNow;
var now = TimeProvider.GetUtcNow();
if (_currentWindow == null || now - _currentWindow.StartedAt >= _windowDuration)
{
_currentWindow = new()
Expand Down
6 changes: 3 additions & 3 deletions src/Polly.Core/CircuitBreaker/Health/SingleHealthMetrics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public SingleHealthMetrics(TimeSpan samplingDuration, TimeProvider timeProvider)
: base(timeProvider)
{
_samplingDuration = samplingDuration;
_startedAt = timeProvider.UtcNow;
_startedAt = timeProvider.GetUtcNow();
}

public override void IncrementSuccess()
Expand All @@ -30,7 +30,7 @@ public override void IncrementFailure()

public override void Reset()
{
_startedAt = TimeProvider.UtcNow;
_startedAt = TimeProvider.GetUtcNow();
_successes = 0;
_failures = 0;
}
Expand All @@ -44,7 +44,7 @@ public override HealthInfo GetHealthInfo()

private void TryReset()
{
if (TimeProvider.UtcNow - _startedAt >= _samplingDuration)
if (TimeProvider.GetUtcNow() - _startedAt >= _samplingDuration)
{
Reset();
}
Expand Down
8 changes: 2 additions & 6 deletions src/Polly.Core/Hedging/Controller/TaskExecution.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using Polly.Hedging.Utils;
using Polly.Telemetry;

Expand Down Expand Up @@ -148,7 +147,7 @@ public async ValueTask ResetAsync()
{
OnReset?.Invoke(this);

if (_cancellationRegistration is CancellationTokenRegistration registration)
if (_cancellationRegistration is { } registration)
{
#if NETCOREAPP
await registration.DisposeAsync().ConfigureAwait(false);
Expand Down Expand Up @@ -204,10 +203,7 @@ private async Task ExecuteSecondaryActionAsync(Func<ValueTask<Outcome<T>>> actio
await UpdateOutcomeAsync(outcome).ConfigureAwait(Context.ContinueOnCapturedContext);
}

private async Task ExecuteCreateActionException(Exception e)
{
await UpdateOutcomeAsync(Polly.Outcome.FromException<T>(e)).ConfigureAwait(Context.ContinueOnCapturedContext);
}
private async Task ExecuteCreateActionException(Exception e) => await UpdateOutcomeAsync(Polly.Outcome.FromException<T>(e)).ConfigureAwait(Context.ContinueOnCapturedContext);

private async Task ExecutePrimaryActionAsync<TState>(Func<ResilienceContext, TState, ValueTask<Outcome<T>>> primaryCallback, TState state)
{
Expand Down
1 change: 0 additions & 1 deletion src/Polly.Core/Hedging/HedgingResilienceStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using Polly.Hedging.Utils;
using Polly.Telemetry;

Expand Down
1 change: 0 additions & 1 deletion src/Polly.Core/Outcome.TResult.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma warning disable CA1815 // Override equals and operator equals on value types

using System;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;

Expand Down
1 change: 0 additions & 1 deletion src/Polly.Core/Retry/RetryResilienceStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Polly.Telemetry;
using Polly.Utils;

namespace Polly.Retry;

Expand Down
79 changes: 79 additions & 0 deletions src/Polly.Core/ToBeRemoved/TimeProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;

#pragma warning disable S3872 // Parameter names should not duplicate the names of their methods

namespace System
{
// Temporary, will be removed
// Copied from https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/System/TimeProvider.cs and trimmed some fat which is not relevant for internal stuff

[ExcludeFromCodeCoverage]
internal abstract class TimeProvider
{
public static TimeProvider System { get; } = new SystemTimeProvider();

protected TimeProvider()
{
}

public virtual DateTimeOffset GetUtcNow() => DateTimeOffset.UtcNow;

private static readonly long MinDateTicks = DateTime.MinValue.Ticks;
private static readonly long MaxDateTicks = DateTime.MaxValue.Ticks;

public DateTimeOffset GetLocalNow()
{
DateTimeOffset utcDateTime = GetUtcNow();
TimeZoneInfo zoneInfo = LocalTimeZone;
if (zoneInfo is null)
{
throw new InvalidOperationException();
}

TimeSpan offset = zoneInfo.GetUtcOffset(utcDateTime);

long localTicks = utcDateTime.Ticks + offset.Ticks;
if ((ulong)localTicks > (ulong)MaxDateTicks)
{
localTicks = localTicks < MinDateTicks ? MinDateTicks : MaxDateTicks;
}

return new DateTimeOffset(localTicks, offset);
}

public virtual TimeZoneInfo LocalTimeZone => TimeZoneInfo.Local;

public virtual long TimestampFrequency => Stopwatch.Frequency;

public virtual long GetTimestamp() => Stopwatch.GetTimestamp();

// This one is not on TimeProvider, temporarly we need to use it
public virtual Task Delay(TimeSpan delay, CancellationToken cancellationToken = default) => Task.Delay(delay, cancellationToken);

// This one is not on TimeProvider, temporarly we need to use it
public virtual void CancelAfter(CancellationTokenSource source, TimeSpan delay) => source.CancelAfter(delay);

public TimeSpan GetElapsedTime(long startingTimestamp, long endingTimestamp)
{
long timestampFrequency = TimestampFrequency;
if (timestampFrequency <= 0)
{
throw new InvalidOperationException();
}

return new TimeSpan((long)((endingTimestamp - startingTimestamp) * ((double)TimeSpan.TicksPerSecond / timestampFrequency)));
}

public TimeSpan GetElapsedTime(long startingTimestamp) => GetElapsedTime(startingTimestamp, GetTimestamp());

private sealed class SystemTimeProvider : TimeProvider
{
internal SystemTimeProvider()
{
}
}
}
}
5 changes: 1 addition & 4 deletions src/Polly.Core/Utils/DefaultPredicates.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using System;
using System.Threading.Tasks;

namespace Polly.Utils;
namespace Polly.Utils;

internal static class DefaultPredicates<TArgs, TResult>
{
Expand Down
4 changes: 1 addition & 3 deletions src/Polly.Core/Utils/OutcomeResilienceStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Runtime.CompilerServices;

namespace Polly.Utils;
namespace Polly.Utils;

/// <summary>
/// This base strategy class is used to simplify the implementation of generic (reactive)
Expand Down
53 changes: 0 additions & 53 deletions src/Polly.Core/Utils/TimeProvider.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Polly.Extensions/Polly.Extensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<ItemGroup>
<Compile Include="..\Polly.Core\Utils\Guard.cs" Link="Utils\Guard.cs" />
<Compile Include="..\Polly.Core\Utils\ObjectPool.cs" Link="Utils\ObjectPool.cs" />
<Compile Include="..\Polly.Core\Utils\TimeProvider.cs" Link="Utils\TimeProvider.cs" />
<Compile Include="..\Polly.Core\ToBeRemoved\TimeProvider.cs" Link="ToBeRemoved\TimeProvider.cs" />
<Compile Include="..\Polly.Core\Utils\ValidationHelper.cs" Link="Utils\ValidationHelper.cs" />
</ItemGroup>

Expand Down
2 changes: 0 additions & 2 deletions src/Polly.Extensions/Telemetry/EnrichmentUtil.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System.Collections.Generic;

namespace Polly.Extensions.Telemetry;

internal static class EnrichmentUtil
Expand Down
1 change: 0 additions & 1 deletion src/Polly.Extensions/Telemetry/TelemetryOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.Net.Http;
using Microsoft.Extensions.Logging;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Diagnostics.Metrics;
using Microsoft.Extensions.Logging;
using Polly.Utils;

namespace Polly.Extensions.Telemetry;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.Threading.RateLimiting;
using Polly.RateLimiting;
using Polly.Utils;

namespace Polly;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ public class BrokenCircuitExceptionTests
[Fact]
public void Ctor_Ok()
{
var brokenCircuit = new BrokenCircuitException();
new BrokenCircuitException("Dummy.").Message.Should().Be("Dummy.");
new BrokenCircuitException("Dummy.", new InvalidOperationException()).Message.Should().Be("Dummy.");
new BrokenCircuitException("Dummy.", new InvalidOperationException()).InnerException.Should().BeOfType<InvalidOperationException>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void AddCircuitBreaker_IntegrationTest()
var timeProvider = new FakeTimeProvider();
var strategy = new ResilienceStrategyBuilder { TimeProvider = timeProvider.Object }.AddSimpleCircuitBreaker(options).Build();
var time = DateTime.UtcNow;
timeProvider.Setup(v => v.UtcNow).Returns(() => time);
timeProvider.Setup(v => v.GetUtcNow()).Returns(() => time);

for (int i = 0; i < options.FailureThreshold; i++)
{
Expand Down Expand Up @@ -154,7 +154,7 @@ public void AddAdvancedCircuitBreaker_IntegrationTest()
var timeProvider = new FakeTimeProvider();
var strategy = new ResilienceStrategyBuilder { TimeProvider = timeProvider.Object }.AddAdvancedCircuitBreaker(options).Build();
var time = DateTime.UtcNow;
timeProvider.Setup(v => v.UtcNow).Returns(() => time);
timeProvider.Setup(v => v.GetUtcNow()).Returns(() => time);

for (int i = 0; i < 10; i++)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Moq;
using Polly.CircuitBreaker;
using Polly.Telemetry;
using Polly.Utils;

namespace Polly.Core.Tests.CircuitBreaker;

Expand All @@ -16,7 +15,7 @@ public class CircuitBreakerResilienceStrategyTests : IDisposable
public CircuitBreakerResilienceStrategyTests()
{
_timeProvider = new FakeTimeProvider();
_timeProvider.Setup(v => v.UtcNow).Returns(DateTime.UtcNow);
_timeProvider.Setup(v => v.GetUtcNow()).Returns(DateTime.UtcNow);
_behavior = new Mock<CircuitBehavior>(MockBehavior.Strict);
_telemetry = TestUtilities.CreateResilienceTelemetry(Mock.Of<DiagnosticSource>());
_options = new SimpleCircuitBreakerStrategyOptions<int>();
Expand Down
Loading

0 comments on commit 18171df

Please sign in to comment.