-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
DecorrelatedJitter is a first-class citizen #536
Conversation
I thought about this some more. I think the above would only work in serializable contexts. What would be our guidance when users try to use a shared (eg reified singleton) strategy in concurrent scenarios. In that case you'd need a distinct |
IIRC the details of So it all works thread-safely - provided, of course, that within our |
You are right, I couldn't recall whether the generated state machine was per-execution or not. I convinced myself using the following code (and associated unit): const int count = 10;
DecorrelatedJitterBackoff durationStrategy = new DecorrelatedJitterBackoff(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3));
IEnumerable<TimeSpan> generate = durationStrategy.GetSleepDurations(count);
var tasks = new Task<TimeSpan[]>[100];
var start = new ManualResetEvent(false);
for (var i = 0; i < tasks.Length; i++)
{
var tcs = new TaskCompletionSource<TimeSpan[]>();
tasks[i] = tcs.Task;
var thread = new Thread(() =>
{
start.WaitOne();
tcs.SetResult(generate.ToArray()); // Every thread enumerates the singleton
});
thread.Start();
}
start.Set(); // Unleash the fury
Task.WaitAll(tasks);
tasks.Should().NotContain(n => n.IsFaulted); // All passed |
@grant-d @george-polevoy . Similar to for the current fault-injection work, I am going to propose that we promote this contribution to its own package, in this case (something like)
Please let me know any thoughts. Mechanics:
|
@grant-d The separate package proposal (if agreed) helps guide some of our decisions around interfaces-or-not; and instances-of-a-class configuration versus static factory methods. Propose we may go for: (a) static factory methods on a separate-class-per-strategy, ie a syntax
(b) static methods, no instances, no interface
Again, let me know if this path forward seems ok. |
Sorry, been snowed under at work, will try get to this this week |
@grant-d No problem! |
Sorry for the long delay, I should have more time now. |
Regarding |
/// For example: 117ms, 236ms, 141ms, 424ms, ... | ||
/// For background, see https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/. | ||
/// </summary> | ||
public static class DecorrelatedJitterBackoff_static // Temporary name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the option where we have static methods returning IEnumerable
only
|
||
// Static-based instantiation | ||
IEnumerable<TimeSpan> discrete4 = DecorrelatedJitterBackoff_static.Create(minDelay, maxDelay, count, fastFirst, seed).ToList(); | ||
discrete4.Should().HaveCount(count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sample callsite for static instantiation
|
||
// Factory-based instantiation | ||
IEnumerable<TimeSpan> discrete3 = DecorrelatedJitterBackoff.Create(minDelay, maxDelay, count, fastFirst, seed).ToList(); | ||
discrete3.Should().HaveCount(count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sample callsite for factory instantiation
{ | ||
var backoff = new DecorrelatedJitterBackoff(minDelay, maxDelay, fastFirst, seed); | ||
return backoff.GetSleepDurations(retryCount); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is the new factory method
Thanks @grant-d . I disposed of a question around the new jitter strategy also over the festive season, probably going to be a bit more kanban over next couple of weeks (courtesy update) to focus purely on getting Polly v7.0 and Simmy out, then let's bring this to fruition also. Thanks again! |
This PR was unexpectedly automatically closed by github, when deleting a (now-outdated) base branch which the PR targeted . @grant-d Thank you for everything you have done on this! Now that Polly v7.0.0 is released, I hope to revert shortly to how we may take this forward. |
@reisenberger any news on the plans here |
@grant-d , I hope to come back to this at the weekend. |
Cool. My personal feeling is that class called |
ISleepDurationSeriesStrategy
providersPer my design proposal in #526, this PR includes changes that make
DecorrelatedJitterBackoff
,ConstantBackoff
,LinearBackoff
andExponentialBackoff
first-class citizens in Polly.Questions
Details in the linked issue.
PolicyBuilder
to demonstrate the pattern should we decide to integrate it directly. See additional notes there. I am happy to revert such integration if need be. [Edit: Scoped-out]*Forever
overloads, I have not integrated that at all. [Edit: Scoped-out]Notes
Random
instance islock
controlled (per separate discussion)Usage
Details are in the associated design document. But for quick reference, here's how you would call a strategy. Of course, we may decide to provide direct overloads too:
Here's an example of how to call it. Note that the class is instantiated as a singleton (directly or via DI) and each execution uses the
.Generate()
.Risks
yield
instead of an eagerTimeSpan[]
array has mitigated the following concern: Inadequate guidance could lead to consumers using the exact same instance of a strategy across multiple calls. It is essential that.Generate
is called just-in-time, not pre-generated. (Docs should include info in DecorrelatedJitter is a first-class citizen #536 (comment))Confirm the following
(I am not sure which of the 2 dev branches to merge from and target)EDIT by @reisenberger : I fixed this and targeted the branch.