diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2013-02-09 15:31:56 -0800 |
---|---|---|
committer | Andrew Arnott <andrewarnott@gmail.com> | 2013-02-09 15:31:56 -0800 |
commit | 794a08cc9a84f4a1b6ec233e7733704de1fc04cb (patch) | |
tree | 91a9dcb2c3aa90560330f860b23e733c46cdfa29 | |
parent | 2e177b1c58ccd1c8edc2cc78e0c629784173a95c (diff) | |
download | DotNetOpenAuth-794a08cc9a84f4a1b6ec233e7733704de1fc04cb.zip DotNetOpenAuth-794a08cc9a84f4a1b6ec233e7733704de1fc04cb.tar.gz DotNetOpenAuth-794a08cc9a84f4a1b6ec233e7733704de1fc04cb.tar.bz2 |
Assocations with providers when OpenID discovery yields multiple endpoints can now happen in parallel.
-rw-r--r-- | src/DotNetOpenAuth.Core/Util.cs | 18 | ||||
-rw-r--r-- | src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationRequest.cs | 22 |
2 files changed, 29 insertions, 11 deletions
diff --git a/src/DotNetOpenAuth.Core/Util.cs b/src/DotNetOpenAuth.Core/Util.cs index d4204a0..a23b4d8 100644 --- a/src/DotNetOpenAuth.Core/Util.cs +++ b/src/DotNetOpenAuth.Core/Util.cs @@ -7,10 +7,12 @@ namespace DotNetOpenAuth { using System; using System.Collections.Generic; using System.Globalization; + using System.Linq; using System.Net; using System.Net.Http.Headers; using System.Reflection; using System.Text; + using System.Threading.Tasks; using System.Web; using System.Web.UI; using DotNetOpenAuth.Configuration; @@ -226,6 +228,22 @@ namespace DotNetOpenAuth { } /// <summary> + /// Creates a dictionary of a sequence of elements and the result of an asynchronous transform, + /// allowing the async work to proceed concurrently. + /// </summary> + /// <typeparam name="TSource">The type of the source.</typeparam> + /// <typeparam name="TResult">The type of the result.</typeparam> + /// <param name="source">The source.</param> + /// <param name="transform">The transform.</param> + /// <returns></returns> + internal static async Task<Dictionary<TSource, TResult>> ToDictionaryAsync<TSource, TResult>( + this IEnumerable<TSource> source, Func<TSource, Task<TResult>> transform) { + var taskResults = source.ToDictionary(s => s, transform); + await Task.WhenAll(taskResults.Values); + return taskResults.ToDictionary(p => p.Key, p => p.Value.Result); + } + + /// <summary> /// Manages an individual deferred ToString call. /// </summary> /// <typeparam name="T">The type of object to be serialized as a string.</typeparam> diff --git a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationRequest.cs b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationRequest.cs index f9abc37..0fb5b4a 100644 --- a/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationRequest.cs +++ b/src/DotNetOpenAuth.OpenId.RelyingParty/OpenId/RelyingParty/AuthenticationRequest.cs @@ -424,14 +424,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { Logger.Yadis.InfoFormat("Performing discovery on user-supplied identifier: {0}", userSuppliedIdentifier); IEnumerable<IdentifierDiscoveryResult> endpoints = FilterAndSortEndpoints(serviceEndpoints, relyingParty); - var results = new List<AuthenticationRequest>(); - // Maintain a list of endpoints that we could not form an association with. - // We'll fallback to generating requests to these if the ones we CAN create - // an association with run out. - var failedAssociationEndpoints = new List<IdentifierDiscoveryResult>(0); - - foreach (var endpoint in endpoints) { + var authRequestResults = await endpoints.ToDictionaryAsync(async endpoint => { Logger.OpenId.DebugFormat("Creating authentication request for user supplied Identifier: {0}", userSuppliedIdentifier); // The strategy here is to prefer endpoints with whom we can create associations. @@ -446,13 +440,19 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { // No association could be created. Add it to the list of failed association // endpoints and skip to the next available endpoint. - failedAssociationEndpoints.Add(endpoint); - continue; + return null; } } - results.Add(new AuthenticationRequest(endpoint, realm, returnToUrl, relyingParty)); - } + return new AuthenticationRequest(endpoint, realm, returnToUrl, relyingParty); + }); + + var results = (from pair in authRequestResults where pair.Value != null select pair.Value).ToList(); + + // Maintain a list of endpoints that we could not form an association with. + // We'll fallback to generating requests to these if the ones we CAN create + // an association with run out. + var failedAssociationEndpoints = (from pair in authRequestResults where pair.Value == null select pair.Key).ToList(); // Now that we've run out of endpoints that respond to association requests, // since we apparently are still running, the caller must want another request. |