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

Supervisor strategy bad timeouts #986

Merged
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
99 changes: 99 additions & 0 deletions src/core/Akka.Tests/Actor/SupervisorStrategySpecs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using Akka.Actor;
using Xunit;

namespace Akka.Tests.Actor
{
public class SupervisorStrategySpecs
{
public static readonly object[][] RetriesTestData = new[]
{
new object[] { new int?(), -1 },
new object[] { new int?(-1), -1 },
new object[] { new int?(0), 0 },
new object[] { new int?(5), 5 },
};

public static readonly object[][] TimeoutTestData = new[]
{
new object[] { new TimeSpan?(), -1 },
new object[] { new TimeSpan?(System.Threading.Timeout.InfiniteTimeSpan), -1 },
new object[] { new TimeSpan?(TimeSpan.FromMilliseconds(0)), 0 },
new object[] { new TimeSpan?(TimeSpan.FromMilliseconds(100)), 100 },
new object[] { new TimeSpan?(TimeSpan.FromMilliseconds(100).Add(TimeSpan.FromTicks(75))), 100 },
new object[] { new TimeSpan?(TimeSpan.FromMilliseconds(10000)), 10000 },
};

[Theory]
[MemberData("RetriesTestData")]
public void A_constructed_OneForOne_supervisor_strategy_with_nullable_retries_has_the_expected_properties(int? retries, int expectedRetries)
{
var uut = new OneForOneStrategy(retries, null, exn => Directive.Restart);

Assert.Equal(uut.MaxNumberOfRetries, expectedRetries);
}

[Theory]
[MemberData("TimeoutTestData")]
public void A_constructed_OneForOne_supervisor_strategy_with_nullable_timeouts_has_the_expected_properties(TimeSpan? timeout, int expectedTimeoutMilliseconds)
{
var uut = new OneForOneStrategy(-1, timeout, exn => Directive.Restart);

Assert.Equal(uut.WithinTimeRangeMilliseconds, expectedTimeoutMilliseconds);
}

[Theory]
[MemberData("RetriesTestData")]
public void A_constructed_OneForOne_supervisor_strategy_with_nullable_retries_and_a_decider_has_the_expected_properties(int? retries, int expectedRetries)
{
var uut = new OneForOneStrategy(retries, null, Decider.From(Directive.Restart));

Assert.Equal(uut.MaxNumberOfRetries, expectedRetries);
}

[Theory]
[MemberData("TimeoutTestData")]
public void A_constructed_OneForOne_supervisor_strategy_with_nullable_timeouts_and_a_decider_has_the_expected_properties(TimeSpan? timeout, int expectedTimeoutMilliseconds)
{
var uut = new OneForOneStrategy(-1, timeout, Decider.From(Directive.Restart));

Assert.Equal(uut.WithinTimeRangeMilliseconds, expectedTimeoutMilliseconds);
}

[Theory]
[MemberData("RetriesTestData")]
public void A_constructed_AllForOne_supervisor_strategy_with_nullable_retries_has_the_expected_properties(int? retries, int expectedRetries)
{
var uut = new AllForOneStrategy(retries, null, exn => Directive.Restart);

Assert.Equal(uut.MaxNumberOfRetries, expectedRetries);
}

[Theory]
[MemberData("TimeoutTestData")]
public void A_constructed_AllForOne_supervisor_strategy_with_nullable_timeouts_has_the_expected_properties(TimeSpan? timeout, int expectedTimeoutMilliseconds)
{
var uut = new AllForOneStrategy(-1, timeout, exn => Directive.Restart);

Assert.Equal(uut.WithinTimeRangeMilliseconds, expectedTimeoutMilliseconds);
}

[Theory]
[MemberData("RetriesTestData")]
public void A_constructed_AllForOne_supervisor_strategy_with_nullable_retries_and_a_decider_has_the_expected_properties(int? retries, int expectedRetries)
{
var uut = new OneForOneStrategy(retries, null, Decider.From(Directive.Restart));

Assert.Equal(uut.MaxNumberOfRetries, expectedRetries);
}

[Theory]
[MemberData("TimeoutTestData")]
public void A_constructed_AllForOne_supervisor_strategy_with_nullable_timeouts_and_a_decider_has_the_expected_properties(TimeSpan? timeout, int expectedTimeoutMilliseconds)
{
var uut = new OneForOneStrategy(-1, timeout, Decider.From(Directive.Restart));

Assert.Equal(uut.WithinTimeRangeMilliseconds, expectedTimeoutMilliseconds);
}
}
}
1 change: 1 addition & 0 deletions src/core/Akka.Tests/Akka.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
<Compile Include="Actor\StashMailboxSpec.cs" />
<Compile Include="Actor\Stash\ActorWithStashSpec.cs" />
<Compile Include="Actor\SupervisorHierarchySpec.cs" />
<Compile Include="Actor\SupervisorStrategySpecs.cs" />
<Compile Include="Actor\SystemGuardianTests.cs" />
<Compile Include="Configuration\ConfigurationSpec.cs" />
<Compile Include="Actor\ReceiveActorTests_Become.cs" />
Expand Down
14 changes: 8 additions & 6 deletions src/core/Akka/Actor/SupervisorStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public IDecider Decider
/// <param name="withinTimeRange">duration of the time window for maxNrOfRetries, Duration.Inf means no window.</param>
/// <param name="localOnlyDecider">mapping from Exception to <see cref="Directive" /></param>
public OneForOneStrategy(int? maxNrOfRetries, TimeSpan? withinTimeRange, Func<Exception, Directive> localOnlyDecider)
: this(maxNrOfRetries.GetValueOrDefault(-1), withinTimeRange.GetValueOrDefault(Timeout.InfiniteTimeSpan).Milliseconds, localOnlyDecider)
: this(maxNrOfRetries.GetValueOrDefault(-1), (int) withinTimeRange.GetValueOrDefault(Timeout.InfiniteTimeSpan).TotalMilliseconds, localOnlyDecider)
{
//Intentionally left blank
}
Expand All @@ -248,7 +248,7 @@ public OneForOneStrategy(int? maxNrOfRetries, TimeSpan? withinTimeRange, Func<Ex
/// <param name="withinTimeRange">duration of the time window for maxNrOfRetries, Duration.Inf means no window.</param>
/// <param name="decider">mapping from Exception to <see cref="Directive" /></param>
public OneForOneStrategy(int? maxNrOfRetries, TimeSpan? withinTimeRange, IDecider decider)
: this(maxNrOfRetries.GetValueOrDefault(-1), withinTimeRange.GetValueOrDefault(Timeout.InfiniteTimeSpan).Milliseconds, decider)
: this(maxNrOfRetries.GetValueOrDefault(-1), (int) withinTimeRange.GetValueOrDefault(Timeout.InfiniteTimeSpan).TotalMilliseconds, decider)
{
//Intentionally left blank
}
Expand All @@ -265,7 +265,8 @@ public OneForOneStrategy(int? maxNrOfRetries, TimeSpan? withinTimeRange, IDecide
/// <param name="withinTimeMilliseconds">duration in milliseconds of the time window for <paramref name="maxNrOfRetries"/>, negative values means no window.</param>
/// <param name="localOnlyDecider">Mapping from an <see cref="Exception"/> to <see cref="Directive"/></param>
/// <param name="loggingEnabled">If <c>true</c> failures will be logged</param>
public OneForOneStrategy(int maxNrOfRetries, int withinTimeMilliseconds, Func<Exception, Directive> localOnlyDecider, bool loggingEnabled = true) : this(maxNrOfRetries,withinTimeMilliseconds,new LocalOnlyDecider(localOnlyDecider),loggingEnabled)
public OneForOneStrategy(int maxNrOfRetries, int withinTimeMilliseconds, Func<Exception, Directive> localOnlyDecider, bool loggingEnabled = true)
: this(maxNrOfRetries, withinTimeMilliseconds, new LocalOnlyDecider(localOnlyDecider), loggingEnabled)
{
//Intentionally left blank
}
Expand Down Expand Up @@ -403,7 +404,7 @@ public IDecider Decider
/// <param name="withinTimeRange">duration of the time window for maxNrOfRetries, <see cref="Timeout.InfiniteTimeSpan"/> means no window.</param>
/// <param name="localOnlyDecider">mapping from Exception to <see cref="Directive"/></param>
public AllForOneStrategy(int? maxNrOfRetries, TimeSpan? withinTimeRange, Func<Exception, Directive> localOnlyDecider)
: this(maxNrOfRetries.GetValueOrDefault(-1), withinTimeRange.GetValueOrDefault(Timeout.InfiniteTimeSpan).Milliseconds, localOnlyDecider)
: this(maxNrOfRetries.GetValueOrDefault(-1), (int) withinTimeRange.GetValueOrDefault(Timeout.InfiniteTimeSpan).TotalMilliseconds, localOnlyDecider)
{
//Intentionally left blank
}
Expand All @@ -420,7 +421,7 @@ public AllForOneStrategy(int? maxNrOfRetries, TimeSpan? withinTimeRange, Func<Ex
/// <param name="withinTimeRange">duration of the time window for maxNrOfRetries, <see cref="Timeout.InfiniteTimeSpan"/> means no window.</param>
/// <param name="decider">mapping from Exception to <see cref="Directive"/></param>
public AllForOneStrategy(int? maxNrOfRetries, TimeSpan? withinTimeRange, IDecider decider)
: this(maxNrOfRetries.GetValueOrDefault(-1), withinTimeRange.GetValueOrDefault(Timeout.InfiniteTimeSpan).Milliseconds, decider)
: this(maxNrOfRetries.GetValueOrDefault(-1), (int) withinTimeRange.GetValueOrDefault(Timeout.InfiniteTimeSpan).TotalMilliseconds, decider)
{
//Intentionally left blank
}
Expand All @@ -437,7 +438,8 @@ public AllForOneStrategy(int? maxNrOfRetries, TimeSpan? withinTimeRange, IDecide
/// <param name="withinTimeMilliseconds">duration in milliseconds of the time window for <paramref name="maxNrOfRetries"/>, negative values means no window.</param>
/// <param name="localOnlyDecider">Mapping from an <see cref="Exception"/> to <see cref="Directive"/></param>
/// <param name="loggingEnabled">If <c>true</c> failures will be logged</param>
public AllForOneStrategy(int maxNrOfRetries, int withinTimeMilliseconds, Func<Exception, Directive> localOnlyDecider, bool loggingEnabled=true) : this(maxNrOfRetries,withinTimeMilliseconds,new LocalOnlyDecider(localOnlyDecider),loggingEnabled)
public AllForOneStrategy(int maxNrOfRetries, int withinTimeMilliseconds, Func<Exception, Directive> localOnlyDecider, bool loggingEnabled=true)
: this(maxNrOfRetries, withinTimeMilliseconds, new LocalOnlyDecider(localOnlyDecider), loggingEnabled)
{
//Intentionally left blank
}
Expand Down