Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: do not recreate Random each time #945

Merged
merged 4 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 2 additions & 1 deletion Box.V2/Box.V2.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@
<Compile Include="Utility\ContentTypeMapper.cs" />
<Compile Include="Utility\Retry.cs" />
<Compile Include="Utility\SharedLinkUtils.cs" />
<Compile Include="Utility\ThreadSafeRandom.cs" />
<Compile Include="Wrappers\BoxError.cs" />
<Compile Include="Wrappers\BoxErrorContextInfo.cs" />
<Compile Include="Wrappers\BoxBinaryRequest.cs" />
Expand Down Expand Up @@ -343,4 +344,4 @@
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
5 changes: 3 additions & 2 deletions Box.V2/Utility/ExponentialBackoff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ public TimeSpan GetRetryTimeout(int numRetries)
const double RETRY_RANDOMIZATION_FACTOR = 0.5;
var minRandomization = 1 - RETRY_RANDOMIZATION_FACTOR;
var maxRandomization = 1 + RETRY_RANDOMIZATION_FACTOR;
var random = new Random();

var randomization = random.NextDouble() * (maxRandomization - minRandomization) + minRandomization;
var randomization = ThreadSafeRandom.Instance.NextDouble()
* (maxRandomization - minRandomization) + minRandomization;

var exponential = Math.Pow(2, numRetries - 1);
var result = Math.Ceiling(exponential * baseInterval.TotalSeconds * randomization);
return TimeSpan.FromSeconds(result);
Expand Down
31 changes: 31 additions & 0 deletions Box.V2/Utility/ThreadSafeRandom.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Runtime.CompilerServices;

namespace Box.V2.Utility
{
/// <summary>
/// A thread safe implementation of <see cref="Random"/>, following best practices
/// for .NET Framework and .NET Standard.
/// </summary>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-random"/>
internal static class ThreadSafeRandom
{
//
// Adapted from https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Random.cs
//
// NOTE: when/if this library updates to .NET 6+, this code can be replaced with `Random.Shared`
//

[ThreadStatic]
private static Random _random;

[MethodImpl(MethodImplOptions.NoInlining)]
private static Random CreateRandom() => _random = new Random();

/// <summary>
/// An instance of <see cref="Random"/> specific to the calling thread.
/// Do not pass this instance to other threads or contexts.
/// </summary>
public static Random Instance => _random ?? CreateRandom();
}
}
Loading