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

Move async collection to core #7038

Merged
merged 4 commits into from
Jul 29, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions sdk/core/Azure.Core/src/AsyncCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
pakrym marked this conversation as resolved.
Show resolved Hide resolved
// Licensed under the MIT License. See License.txt in the project root for
// license information.

using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;

namespace Azure
{
/// <summary>
/// A collection of values that may take multiple service requests to
/// iterate over.
/// </summary>
/// <typeparam name="T">The type of the values.</typeparam>
public abstract class AsyncCollection<T> : IAsyncEnumerable<Response<T>>
Copy link
Member

Choose a reason for hiding this comment

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

Open question - are we going to have a SyncCollection<T> or similar as an indicator to customers that the sync version of GetBlobs() may make 100 requests?

{
/// <summary>
/// Gets a <see cref="CancellationToken"/> used for requests made while
/// enumerating asynchronously.
/// </summary>
protected virtual CancellationToken CancellationToken { get; }

/// <summary>
/// Initializes a new instance of the <see cref="AsyncCollection{T}"/>
/// class for mocking.
/// </summary>
protected AsyncCollection() =>
this.CancellationToken = CancellationToken.None;

/// <summary>
/// Initializes a new instance of the <see cref="AsyncCollection{T}"/>
/// class.
/// </summary>
/// <param name="cancellationToken">
/// The <see cref="CancellationToken"/> used for requests made while
/// enumerating asynchronously.
/// </param>
protected AsyncCollection(CancellationToken cancellationToken) =>
this.CancellationToken = cancellationToken;

/// <summary>
/// Enumerate the values a <see cref="Page{T}"/> at a time. This may
/// make mutliple service requests.
/// </summary>
/// <param name="continuationToken">
/// A continuation token indicating where to resume paging or null to
/// begin paging from the beginning.
/// </param>
/// <param name="pageSizeHint">
/// The size of <see cref="Page{T}"/>s that should be requested (from
/// service operations that support it).
/// </param>
/// <returns>
/// An async sequence of <see cref="Page{T}"/>s.
/// </returns>
public abstract IAsyncEnumerable<Page<T>> ByPage(
string continuationToken = default,
int? pageSizeHint = default);

/// <summary>
/// Enumerate the values in the collection asynchronously. This may
/// make mutliple service requests.
/// </summary>
/// <param name="cancellationToken">
/// The <see cref="CancellationToken"/> used for requests made while
/// enumerating asynchronously.
/// </param>
/// <returns>An async sequence of values.</returns>
public abstract IAsyncEnumerator<Response<T>> GetAsyncEnumerator(CancellationToken cancellationToken = default);

/// <summary>
/// Creates a string representation of an <see cref="AsyncCollection{T}"/>.
/// </summary>
/// <returns>
/// A string representation of an <see cref="AsyncCollection{T}"/>.
/// </returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();

/// <summary>
/// Check if two <see cref="AsyncCollection{T}"/> instances are equal.
/// </summary>
/// <param name="obj">The instance to compare to.</param>
/// <returns>True if they're equal, false otherwise.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => base.Equals(obj);

/// <summary>
/// Get a hash code for the <see cref="AsyncCollection{T}"/>.
/// </summary>
/// <returns>Hash code for the <see cref="Page{T}"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() => base.GetHashCode();
}
}
82 changes: 82 additions & 0 deletions sdk/core/Azure.Core/src/Page.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;
using System.ComponentModel;

namespace Azure
{
/// <summary>
/// A single <see cref="Page{T}"/> of values from a request that may return
/// zero or more <see cref="Page{T}"/>s of values.
/// </summary>
/// <typeparam name="T">The type of values.</typeparam>
public readonly struct Page<T>
{
/// <summary>
/// Gets the values in this <see cref="Page{T}"/>.
/// </summary>
public IReadOnlyList<T> Values { get; }
Copy link
Member

Choose a reason for hiding this comment

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

Open question - we've got open issues like #6894 to use T[] (rather than IEnumerable<T> or IReadOnlyList<T>) and it'd be great to be consistent.


/// <summary>
/// Gets the continuation token used to request the next
/// <see cref="Page{T}"/>. The continuation token may be null or
/// empty when there are no more pages.
/// </summary>
public string ContinuationToken { get; }

/// <summary>
/// The <see cref="Response"/> that provided this <see cref="Page{T}"/>.
/// </summary>
private readonly Response _response;

/// <summary>
/// Gets the <see cref="Response"/> that provided this
/// <see cref="Page{T}"/>.
/// </summary>
public Response GetRawResponse() => this._response;

/// <summary>
/// Creates a new <see cref="Page{T}"/>.
/// </summary>
/// <param name="values">
/// The values in this <see cref="Page{T}"/>.
/// </param>
/// <param name="continuationToken">
/// The continuation token used to request the next <see cref="Page{T}"/>.
/// </param>
/// <param name="response">
/// The <see cref="Response"/> that provided this <see cref="Page{T}"/>.
/// </param>
public Page(IReadOnlyList<T> values, string continuationToken, Response response)
{
this.Values = values;
this.ContinuationToken = continuationToken;
this._response = response;
}

/// <summary>
/// Creates a string representation of an <see cref="Page{T}"/>.
/// </summary>
/// <returns>
/// A string representation of an <see cref="Page{T}"/>.
/// </returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override string ToString() => base.ToString();

/// <summary>
/// Check if two <see cref="Page{T}"/> instances are equal.
/// </summary>
/// <param name="obj">The instance to compare to.</param>
/// <returns>True if they're equal, false otherwise.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => base.Equals(obj);

/// <summary>
/// Get a hash code for the <see cref="Page{T}"/>.
/// </summary>
/// <returns>Hash code for the <see cref="Page{T}"/>.</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() => base.GetHashCode();
}
}
4 changes: 2 additions & 2 deletions sdk/storage/Azure.Storage.Blobs/tests/ContainerClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,7 @@ public async Task ListBlobsFlatSegmentAsync_MaxResults()
var page = await container.GetBlobsAsync().ByPage(pageSizeHint: 2).FirstAsync();

// Assert
Assert.AreEqual(2, page.Values.Length);
Assert.AreEqual(2, page.Values.Count);
}
}

Expand Down Expand Up @@ -1365,7 +1365,7 @@ public async Task ListBlobsHierarchySegmentAsync_MaxResults()
.FirstAsync();

// Assert
Assert.AreEqual(2, page.Values.Length);
Assert.AreEqual(2, page.Values.Count);
}
}

Expand Down
192 changes: 0 additions & 192 deletions sdk/storage/Azure.Storage.Common/src/AsyncCollection.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public override async IAsyncEnumerator<Response<T>> GetAsyncEnumerator(Cancellat
/// make mutliple service requests.
/// </summary>
/// <returns>A sequence of values.</returns>
protected override IEnumerator<Response<T>> GetEnumerator()
protected IEnumerator<Response<T>> GetEnumerator()
{
string continuationToken = null;
do
Expand Down
Loading