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

Support for asynchronous autopagination #1947

Merged
merged 1 commit into from Mar 19, 2020

Conversation

ob-stripe
Copy link
Contributor

@ob-stripe ob-stripe commented Mar 6, 2020

r? @brandur-stripe @cjavilla-stripe @remi-stripe
cc @stripe/api-libraries

This PR adds support for asynchronous autopagination, using the new IAsyncEnumerable<T> interface introduced in C# 8.

Normally, this would require .NET Standard 2.1, but we can use it without changing our target of .NET Standard 2.0 thanks to the Microsoft.Bcl.AsyncInterfaces package. Unfortunately there is (AFAIK) no way to support this with .NET Framework 4.5, so I had to add a gazillion #if !NET45 preprocessor macros.

This PR is very large and I should have done a better job of splitting it into smaller commits, but it shouldn't be too hard to review:

For tests:

  • AutoPagingTest.cs was updated to add tests for the new async methods. ListAutoPagingAsync, ListAutoPagingAsync_NoParams, ListAutoPagingAsync_StartingAfter and ListAutoPagingAsync_EndingBefore are copies of the tests for the synchronous methods. ListAutoPagingAsync_WithCancellation is a new test unique to the async version to test the cancellation behavior.
  • Every ListAutoPaging test in service test classes was updated to use First() instead of ToList(). ToList() forces the conversion of the IEnumerable into a List, which could cause many requests if there were many pages to fetch. This is not actually an issue when using stripe-mock, but better safe than sorry
  • New ListAutoPagingAsync tests were added to all service test classes.

Fixes #1946.

@ob-stripe ob-stripe force-pushed the ob-auto-paging-async branch 6 times, most recently from d00bd3f to 0bfe8b4 Compare March 7, 2020 00:02
@clement911
Copy link
Contributor

❤️

@ob-stripe ob-stripe changed the title [wip] Support for asynchronous autopagination Support for asynchronous autopagination Mar 7, 2020
string url,
ListOptions options,
RequestOptions requestOptions,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not very well documented, but what the EnumeratorCancellation attribute does is add support for two different ways of passing the cancellation token:

@@ -38,6 +39,12 @@
<CodeAnalysisRuleSet>..\_stylecop\StyleCopRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.1.0" />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the backport package that adds support for IAsyncEnumerable in .NET Standard 2.0.

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.1.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.5.0" />
<PackageReference Include="System.Linq.Async" Version="4.0.0" />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This adds support for async enumerators to LINQ methods. We use this to convert the IAsyncEnumerable to a regular IEnumerable (so that the synchronous version ListRequestAutoPaging is just a thin wrapper over the async ListRequestAutoPagingAsync).


try
{
await foreach (var model in service.ListAutoPagingAsync(options).WithCancellation(source.Token))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This illustrates the new await foreach syntax added in C# 8, as well as support for .WithCancellation() to pass cancellation tokens.

@@ -67,5 +67,12 @@ public virtual IEnumerable<TaxId> ListAutoPaging(string customerId, TaxIdListOpt
{
return this.ListNestedEntitiesAutoPaging(customerId, options, requestOptions);
}

#if !NET45
public virtual IAsyncEnumerable<TaxId> ListAutoPagingAsync(string customerId, TaxIdListOptions options = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default)
Copy link
Contributor

Choose a reason for hiding this comment

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

Wondering if these customerId parameter names will be easy to derive from the spec, or if it would be easier to use id or parentId in the nested cases...

Copy link
Contributor

Choose a reason for hiding this comment

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

They shouldn't need to. In another PR for your codegen branch we renamed all of those to parentId and id instead. It's likely just that ob used a codemod or a regex to generate those

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, this PR is like 90% codemod. Sorry for the additional toil CJ :/

@ob-stripe ob-stripe changed the base branch from master to integration-v36 March 19, 2020 18:22
Copy link
Contributor

@cjavilla-stripe cjavilla-stripe left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@brandur-stripe brandur-stripe left a comment

Choose a reason for hiding this comment

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

Seems good to me too. Thanks OB!

@ob-stripe
Copy link
Contributor Author

Thanks both!

@ob-stripe ob-stripe mentioned this pull request Mar 19, 2020
2 tasks
@ob-stripe ob-stripe merged commit 471bf1f into integration-v36 Mar 19, 2020
@ob-stripe ob-stripe deleted the ob-auto-paging-async branch March 19, 2020 18:39
@clement911
Copy link
Contributor

Thank you!

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.

ListAutoPaging async version
6 participants