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

Makes cancellable configuration-providing delegates #41

Merged
merged 3 commits into from
Jul 26, 2019

Conversation

vany0114
Copy link
Member

@vany0114 vany0114 commented Jul 12, 2019

@reisenberger I updated the overloads which were taking the Context in configuration-providing delegates instead of adding new overloads (breaking change), basically to avoid the proliferation of the overloads as we discussed it previously, but it might be solved with the new syntax tho.

I added some validations on AsyncMonkeyEngine (not sure if that is correct) in order to avoid to execute extra code when the cancellation token is signaled at different times during the execution.

I also changed the AsyncInjectLatencyPolicy (1, 2) in order to make the latency configuration delegate cancellable because it was injecting the latency even though you signal the cancellation from that configuration delegate.

However, after this refactor I have a big doubt: should we let the cancellation token request flow to the user rather than let Simmy does it using ThrowIfCancellationRequested() on AsyncMonkeyEngine? if not, I'll need to update the MonkeyEngine as well (to put those validations).

Or just validate once on ShouldInjectAsync method at the beginning? and let the user does something like this:

Func<Context, CancellationToken, Task> actionOrConfigDelegateAsync = (ctx, ct) =>
{
     ct.ThrowIfCancellationRequested();
     ...
};

Thoughts?

ref #19

vany0114 added 2 commits July 10, 2019 21:14
…ctors the engine to add some validations to avoid execute extra code when cancellation token is signaled.
@vany0114 vany0114 requested a review from reisenberger July 12, 2019 03:35
@vany0114 vany0114 changed the title makes cancellable configuration-providing delegates Makes cancellable configuration-providing delegates Jul 12, 2019
@reisenberger
Copy link
Member

Thanks @vany0114 , these are great questions! I will try to dive in and have a look over the weekend/coming days!

Copy link
Member

@reisenberger reisenberger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀 looking very nice to me, @vany0114 ! Will contribute thoughts separately on questions in your cover note.

{
if (!await enabled(context).ConfigureAwait(continueOnCapturedContext))
// to prevent execute config delegates if user cancels the whole execution before to start.
cancellationToken.ThrowIfCancellationRequested();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Perfect for a policy engine to test for cancellation as the first thing it does. This is a typical pattern for Polly policies.

It matches the approach of the .NET base class libraries: for example Task.Run(...) makes a cancellation check before running the passed delegate.

{
return false;
}

double injectionThreshold = await injectionRate(context).ConfigureAwait(continueOnCapturedContext);
// to prevent execute injectionRate config delegate if user cancels execution on enable configuration delegate.
cancellationToken.ThrowIfCancellationRequested();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 to check for cancellation again here (in case the CancellationToken has been signalled, but the user's enabled delegate didn't check it, so didn't honor cancellation).

Note: the good reason for checking cancellation here is that a timing-out CancellationToken might have been provided (for example from a TimeoutPolicy), and it is possible the user's enabled delegate didn't honor it.
(I am not thinking so much that the user would have signal the CancellationToken within the enabled delegate. If the user wants the chaos not to go ahead, they can simply return false from that delegate.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I think that's gonna cover cancellation for timing out just in case the user wrap chaos policies with a timeout policy, which would be highly likely.

double injectionThreshold = await injectionRate(context, cancellationToken).ConfigureAwait(continueOnCapturedContext);

// to prevent execute further config delegates if user cancels execution on injectionRate configuration delegate.
cancellationToken.ThrowIfCancellationRequested();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 to check for cancellation again here (for same reason as a few lines above)

{
Func<Context, CancellationToken, Task<bool>> enabled = (ctx, ct) =>
{
cts.Cancel();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I expect, if the user wanted to choose not to introduce the chaos, they could just return false from this delegate. But the cts.Cancel() here is a good simulation of something else (eg a TimeoutPolicy) signalling the CancellationToken some time during the execution of the enabled delegate.

(Similarly for all the other tests.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, I think is very unlikely that a user does something like that explicitly to cancel the chaos injection, I just wanted to show how would be the behavior of cancellation when the token is signaled, usually (as you said) from a timeout policy. Maybe I should rename the test cases to be clearer 😅

@reisenberger
Copy link
Member

Hey @vany0114

updated the overloads [...] instead of adding new overloads (breaking change), basically to avoid the proliferation

👍

added some validations on AsyncMonkeyEngine

Looks good to me! Per my comments in detailed review, a good reason for checking for cancellation frequently can be because something independent (some other thread; a timeout timer) has signalled the CancellationToken. And because the user's delegate may not have honored that CancellationToken (if they didn't bother to code it to do so).

should we let the cancellation token request flow to the user rather than let Simmy does it using ThrowIfCancellationRequested() on AsyncMonkeyEngine?

I think it is fine for a Policy to enforce cancellation even if the user code doesn't. Polly policies do this.


You are right that we should make the sync policies do the same.

After that, you can decide whether you want to make a v0.2 release with this straight away 🚀 , or if there is anything else you want to add/change for a v0.2. I can talk you through the process we normally use (for Polly) when we make a new release!

@vany0114
Copy link
Member Author

Hey @reisenberger

Thanks for taking a look and your thoughts. Yeah, I'm gonna do the change for sync policies as well and also implement #20 since it's related too. After that, I can make a v0.2 release.

And yes, I'd love to know how you guys handle the release process on Polly to apply it on Simmy as well!

@vany0114 vany0114 self-assigned this Jul 24, 2019
@vany0114
Copy link
Member Author

Sync policies are done already. I've updated the PR.

@vany0114 vany0114 changed the base branch from master to v0_2 July 26, 2019 03:35
@vany0114 vany0114 merged commit e211889 into v0_2 Jul 26, 2019
@vany0114 vany0114 added this to the V0.2 milestone Jul 30, 2019
@vany0114 vany0114 deleted the vany0114-ct-configuration-delegates branch January 4, 2020 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants