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

WebHook : UseFireAndForget + Delay #803

Merged
merged 9 commits into from
Sep 12, 2022
Merged

WebHook : UseFireAndForget + Delay #803

merged 9 commits into from
Sep 12, 2022

Conversation

StefH
Copy link
Collaborator

@StefH StefH commented Sep 5, 2022

No description provided.

@StefH StefH self-assigned this Sep 5, 2022
@StefH StefH added the feature label Sep 5, 2022
@codecov
Copy link

codecov bot commented Sep 5, 2022

Codecov Report

Merging #803 (fb3943f) into master (13a06b9) will decrease coverage by 0.07%.
The diff coverage is 68.88%.

@@            Coverage Diff             @@
##           master     #803      +/-   ##
==========================================
- Coverage   72.50%   72.42%   -0.08%     
==========================================
  Files         211      211              
  Lines        7386     7446      +60     
  Branches      766      769       +3     
==========================================
+ Hits         5355     5393      +38     
- Misses       1800     1820      +20     
- Partials      231      233       +2     
Impacted Files Coverage Δ
src/WireMock.Net/Server/RespondWithAProvider.cs 83.73% <33.33%> (-2.71%) ⬇️
src/WireMock.Net/Serialization/MappingConverter.cs 56.37% <50.00%> (+0.21%) ⬆️
src/WireMock.Net/Http/WebhookSender.cs 72.22% <55.55%> (-12.40%) ⬇️
src/WireMock.Net/Owin/WireMockMiddleware.cs 82.01% <56.00%> (-4.82%) ⬇️
...ck.Net.Abstractions/Admin/Mappings/MappingModel.cs 100.00% <100.00%> (ø)
...ck.Net.Abstractions/Admin/Mappings/WebhookModel.cs 100.00% <100.00%> (ø)
...Abstractions/Admin/Mappings/WebhookRequestModel.cs 100.00% <100.00%> (ø)
src/WireMock.Net/Mapping.cs 96.92% <100.00%> (+0.14%) ⬆️
...Net/Matchers/Request/RequestMessageParamMatcher.cs 92.18% <100.00%> (ø)
src/WireMock.Net/Models/Webhook.cs 100.00% <100.00%> (ø)
... and 5 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@StefH
Copy link
Collaborator Author

StefH commented Sep 5, 2022

#801

@StefH StefH changed the title WebHook : UseFireAndForget + ...? WebHook : UseFireAndForget + Delay Sep 5, 2022
@StefH StefH mentioned this pull request Sep 5, 2022
@mattisking
Copy link
Contributor

The delay should happen before the send. The goal here is to say, wait this long before sending this webhook.


// Call the URL
return client.SendAsync(httpRequestMessage);
var sendTask = client.SendAsync(httpRequestMessage);
Copy link
Contributor

Choose a reason for hiding this comment

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

The goal here is to wait before sending the requested amount of time. The actual mocked API request should return immediately (unless a global delay is used or a configured delay on the mapping), regardless of the webhooks. Then the webhooks should fire after the configured delay for each webhook.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've modified the code according to your proposal. Please see the updated PR.

Copy link
Contributor

@mattisking mattisking Sep 6, 2022

Choose a reason for hiding this comment

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

This fixes the timing and the fire and forget is working on each webhook, but the calling process remains blocked until the webhooks finish running which can be a long time if the webhook timing is big. Perhaps the UseFireAndForget should be at another level and automatically apply to all webhooks. Use the following example:

// Webhook server.Given(Request.Create().WithPath(new WildcardMatcher("/Cars", true)).UsingPost()) .WithWebhook(new Webhook { Request = new WebhookRequest { Url = "https://localhost:12345/foo1", Method = "post", BodyData = new BodyData { BodyAsString = "OK 1!", DetectedBodyType = BodyType.String }, Delay = 1000, UseFireAndForget = true } }) .WithWebhook(new Webhook { Request = new WebhookRequest { Url = "https://localhost:12345/foo2", Method = "post", BodyData = new BodyData { BodyAsString = "OK 2!", DetectedBodyType = BodyType.String }, Delay = 5000, UseFireAndForget = true } }) .RespondWith(Response.Create().WithBody("a-response"));

I'd expect here to get "a-response" more or less immediately, and then see the two webhooks trickle in separately. If you use this example, however, what you'll see is that it takes approximately ~6 seconds for the request to return. That's because even though the SendAsync isn't being awaited, the overall tasks are which include the delay. That's why in my example I had the hacky:

        //await Task.WhenAll(tasks.Select(async task => await task.Invoke()));
        await Task.WhenAll(tasks.Select(async task => task.Invoke()));

That await still causes the long delay in the request response. If we moved the FireAndForget so that it applies to all webhooks, we could move your FireAndForget(sendTask); out of the WebhookSender.cs and use it in the line above. What do you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think you are right. However I'm also a bit lost.

If you can comment on the PR and specify which code needs to change. I will change it.

Copy link
Contributor

Choose a reason for hiding this comment

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

We want to keep webhooks individually configurable for delays, but I think the fireandforget setting needs to be a mapping setting, not a webhookmapping setting. That way we can do the await or not as a whole, not on each specific, which would allow us to wait or not in WireMockMiddleware.cs around line 226.

//await Task.WhenAll(tasks.Select(async task => await task.Invoke()));
await Task.WhenAll(tasks.Select(async task => task.Invoke()));

Let me see if I can be a little more clear.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've made a branch based on your branch. Of course I don't have permission to create the branch. I suppose I could fork the whole thing and do it that way, or I can try another approach to show my changes based on yours.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Easiest would be (I think) that you fork this project, and create a new branch based on my branch (stef-webhooks) and tell me your branch, or just create a PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sent you a PR from my fork. The PR is to merge into your stef-webhooks branch since I wasn't quite sure the state of master. If you accept that merge, then you can finish your current PR with my changes to go to master (or tell me if you just want me to do a PR against master instead).

StefH and others added 3 commits September 6, 2022 19:14
…ssic, move the new FireAndForget into the main mapping, out of individual webhook mappings making it all or nothing, update tests, change Middleware to await or not the firing of all webhooks. Update models as needed. (#804)

Co-authored-by: Matt Philmon <[email protected]>
@StefH
Copy link
Collaborator Author

StefH commented Sep 7, 2022

@mattisking
I did merge your code, updated some small things.

And about this one:
image

Should this be changed into:

await Task.WhenAll(tasks.Select(task => task.Invoke()));

??

@mattisking
Copy link
Contributor

I submitted another smaller PR. I've done this in a way that makes that little squiggle go away in Visual Studio and the associated warning but in general, the Tasks library doesn't necessarily love it when you ignore your await which is what I need to do to make this work. If I take that async away we're back to blocking on the thread. So, I'll spin it out into it's own Task. I also fixed a misunderstanding I had in adding webhooks in the example app.

@mattisking
Copy link
Contributor

Sent in another PR that I updated first

@mattisking
Copy link
Contributor

Let me know if I can add anything.

@StefH
Copy link
Collaborator Author

StefH commented Sep 8, 2022

It's ok.

Next Monday I will merge and create a new NuGet.

@StefH StefH merged commit 98a0f2f into master Sep 12, 2022
@StefH StefH deleted the stef-webhooks branch September 12, 2022 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants