Skip to content

Eagerly read IAsyncEnumerable{object} instances before formatting #11118

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

Merged
merged 5 commits into from
Jun 25, 2019

Conversation

pranavkm
Copy link
Contributor

Fixes #4833

@pranavkm pranavkm requested review from rynowak and davidfowl June 11, 2019 22:54
@analogrelay analogrelay added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Jun 11, 2019
@pranavkm pranavkm force-pushed the prkrishn/asyncenumerable branch from 8e5e4ad to b6a3036 Compare June 13, 2019 18:32
var type = value.GetType();
if (!_asyncEnumerableConverters.TryGetValue(type, out var result))
{
var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(type, typeof(IAsyncEnumerable<>));
Copy link
Member

Choose a reason for hiding this comment

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

What happens if you implement multiple IAsyncEnumerable<> interfaces? implementation-defined? Crash with a bad error?


var converter = (ReadAsyncEnumerableDelegate)Converter
.MakeGenericMethod(enumeratedObjectType)
.CreateDelegate(typeof(ReadAsyncEnumerableDelegate), this);
Copy link
Member

Choose a reason for hiding this comment

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

cheeky.

@pranavkm pranavkm force-pushed the prkrishn/asyncenumerable branch 2 times, most recently from b1f2a6b to c2469ac Compare June 20, 2019 17:26
@pranavkm
Copy link
Contributor Author

🆙 📅

/// an <see cref="IAsyncEnumerable{T}"/>. An accurate <see cref="ICollection{T}"/> is required for XML formatters to
/// correctly serialize.
/// </remarks>
public sealed class AsyncEnumerableReader
Copy link
Member

Choose a reason for hiding this comment

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

Does this really need to be public? I don't have a strong objection, but it seems like infrastructure, rather than something we expect users to need.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could defer reading this from DI or have duplicated caching if your app uses a mix of ObjectResult and JsonResult returning IAsyncEnumerable. I guess the latter is rare and easily fixable if it turns out to be a problem in the future.

Copy link
Member

Choose a reason for hiding this comment

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

I don't understand your answer. What's the reason why this type is public?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ObjectResultExecutor is public. If we have to share the same singleton instance between the JsonResultExecutor(s) and ObjectResultExecutor, we either have to make the type public for ctor DI or read it in the body of ExecuteAsync.

if (!_asyncEnumerableConverters.TryGetValue(type, out var result))
{
var enumerableType = ClosedGenericMatcher.ExtractGenericInterface(type, typeof(IAsyncEnumerable<>));
Debug.Assert(enumerableType != null);
Copy link
Member

Choose a reason for hiding this comment

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

This is a public API, so this should probably throw instead of assert. Someone could pass in any type here.

private async Task ExecuteAsyncEnumerable(ActionContext context, ObjectResult result, IAsyncEnumerable<object> asyncEnumerable)
{
var enumerated = await _asyncEnumerableReader.ReadAsync(asyncEnumerable);
await ExecuteAsyncCore(context, result, enumerated.GetType(), enumerated);
Copy link
Member

Choose a reason for hiding this comment

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

Should we be logging here?

@pranavkm pranavkm force-pushed the prkrishn/asyncenumerable branch from c2469ac to ca281db Compare June 25, 2019 00:46
@pranavkm pranavkm merged commit b10c8a6 into master Jun 25, 2019
@ghost ghost deleted the prkrishn/asyncenumerable branch June 25, 2019 17:53
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add IAsyncEnumerable support to MVC
4 participants