Skip to content

Conversation

@rafikiassumani-msft
Copy link
Contributor

@rafikiassumani-msft rafikiassumani-msft commented Apr 8, 2022

Fix allocation issue caused by ordering of MVC result executors for Task results

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

This PR changes the order of the ActionMethod executors for Task result types and adds tests to ensure the right executor gets chosen based on different action result scenarios.

Description

This PR changes the order of the ActionMethod executors so that for the case of Task where the result type is known at compile time, we can invoke the Execute sync method rather than the ExecuteAsync to allow us to "await" directly the result value via type cast. The ExecuteAync method returns a custom awaitable, which can incur extra head allocations.

Fixes #40364

@rafikiassumani-msft rafikiassumani-msft requested a review from a team as a code owner April 8, 2022 16:39
@ghost ghost added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Apr 8, 2022
@rafikiassumani-msft rafikiassumani-msft requested a review from a team April 8, 2022 16:40
new TaskResultExecutor(),
new AwaitableResultExecutor(),
new TaskOfIActionResultExecutor(),
new TaskOfActionResultExecutor(),
Copy link
Member

Choose a reason for hiding this comment

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

I think we should make sure every executor on this list is called by a test, for example I don't see an added check for "TaskOfActionResultExecutor", does this mean we are missing test coverage for it? Or is it shadowed by TaskOfIActionResultExecutor?

Copy link
Contributor Author

@rafikiassumani-msft rafikiassumani-msft Apr 8, 2022

Choose a reason for hiding this comment

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

Good catch @BrennanConroy , I think TaskOfIActionResultExecutor had a duplicate test. I adjusted it to account for TaskOfActionResultExecutor

var valueTask = actionMethodExecutor.Execute(mapper, objectMethodExecutor, controller, Array.Empty<object>());

// Assert
Assert.Equal("VoidResultExecutor", actionMethodExecutor.GetType().Name);
Copy link
Member

Choose a reason for hiding this comment

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

These types are internal so a type check would work? i.e.

Assert.IsType<VoidResultExecutor>(actionMethodExecutor);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@davidfowl All the executors are private classes. The only internal class is the ActionMethodExecutor. I don't think there is enough value in making these classes internal just for testing purposes.

Copy link
Member

@halter73 halter73 left a comment

Choose a reason for hiding this comment

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

We could make the private nested classes internal nested classes instead to allow for IsType checks in our tests, but I don't think that's very important.

@davidfowl
Copy link
Member

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@rafikiassumani-msft rafikiassumani-msft merged commit 55f1e2f into dotnet:main May 20, 2022
@ghost ghost added this to the 7.0-preview5 milestone May 20, 2022
@davidfowl davidfowl added the Perf label Aug 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates Perf

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TaskResultExecutor is never used by ActionMethodExecutor

4 participants