Skip to content

Commit

Permalink
API review: rename ServiceEndPointCollectionSource to IServiceEndPoin…
Browse files Browse the repository at this point in the history
…tBuilder
  • Loading branch information
ReubenBond committed Mar 25, 2024
1 parent 6b09407 commit 032d309
Show file tree
Hide file tree
Showing 19 changed files with 166 additions and 157 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Primitives;

namespace Microsoft.Extensions.ServiceDiscovery;

/// <summary>
/// Builder to create a <see cref="ServiceEndPointSource"/> instances.
/// </summary>
public interface IServiceEndPointBuilder
{
/// <summary>
/// Gets the endpoints.
/// </summary>
IList<ServiceEndPoint> EndPoints { get; }

/// <summary>
/// Gets the feature collection.
/// </summary>
IFeatureCollection Features { get; }

/// <summary>
/// Adds a change token to the resulting <see cref="ServiceEndPointSource"/>.
/// </summary>
/// <param name="changeToken">The change token.</param>
void AddChangeToken(IChangeToken changeToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ public interface IServiceEndPointProvider : IAsyncDisposable
/// <param name="endPoints">The endpoint collection, which resolved endpoints will be added to.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
/// <returns>The resolution status.</returns>
ValueTask ResolveAsync(ServiceEndPointCollectionSource endPoints, CancellationToken cancellationToken);
ValueTask ResolveAsync(IServiceEndPointBuilder endPoints, CancellationToken cancellationToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ public interface IServiceEndPointSelector
/// Sets the collection of endpoints which this instance will select from.
/// </summary>
/// <param name="endPoints">The collection of endpoints to select from.</param>
void SetEndPoints(ServiceEndPointCollection endPoints);
void SetEndPoints(ServiceEndPointSource endPoints);

/// <summary>
/// Selects an endpoints from the collection provided by the most recent call to <see cref="SetEndPoints(ServiceEndPointCollection)"/>.
/// Selects an endpoints from the collection provided by the most recent call to <see cref="SetEndPoints(ServiceEndPointSource)"/>.
/// </summary>
/// <param name="context">The context.</param>
/// <returns>An endpoint.</returns>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections;
using System.Diagnostics;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Primitives;

namespace Microsoft.Extensions.ServiceDiscovery;

/// <summary>
/// Represents an immutable collection of service endpoints.
/// Represents a collection of service endpoints.
/// </summary>
[DebuggerDisplay("{ToString(),nq}")]
[DebuggerTypeProxy(typeof(ServiceEndPointCollectionDebuggerView))]
public sealed class ServiceEndPointCollection : IReadOnlyList<ServiceEndPoint>
public sealed class ServiceEndPointSource
{
private readonly List<ServiceEndPoint>? _endpoints;

/// <summary>
/// Initializes a new <see cref="ServiceEndPointCollection"/> instance.
/// Initializes a new <see cref="ServiceEndPointSource"/> instance.
/// </summary>
/// <param name="endpoints">The endpoints.</param>
/// <param name="changeToken">The change token.</param>
/// <param name="features">The feature collection.</param>
public ServiceEndPointCollection(List<ServiceEndPoint>? endpoints, IChangeToken changeToken, IFeatureCollection features)
public ServiceEndPointSource(List<ServiceEndPoint>? endpoints, IChangeToken changeToken, IFeatureCollection features)
{
ArgumentNullException.ThrowIfNull(changeToken);

Expand All @@ -32,8 +31,10 @@ public ServiceEndPointCollection(List<ServiceEndPoint>? endpoints, IChangeToken
ChangeToken = changeToken;
}

/// <inheritdoc/>
public ServiceEndPoint this[int index] => _endpoints?[index] ?? throw new ArgumentOutOfRangeException(nameof(index));
/// <summary>
/// Gets the endpoints.
/// </summary>
public IReadOnlyList<ServiceEndPoint> EndPoints => _endpoints ?? (IReadOnlyList<ServiceEndPoint>)[];

/// <summary>
/// Gets the change token which indicates when this collection should be refreshed.
Expand All @@ -45,15 +46,6 @@ public ServiceEndPointCollection(List<ServiceEndPoint>? endpoints, IChangeToken
/// </summary>
public IFeatureCollection Features { get; }

/// <inheritdoc/>
public int Count => _endpoints?.Count ?? 0;

/// <inheritdoc/>
public IEnumerator<ServiceEndPoint> GetEnumerator() => _endpoints?.GetEnumerator() ?? Enumerable.Empty<ServiceEndPoint>().GetEnumerator();

/// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

/// <inheritdoc/>
public override string ToString()
{
Expand All @@ -65,13 +57,13 @@ public override string ToString()
return $"[{string.Join(", ", eps)}]";
}

private sealed class ServiceEndPointCollectionDebuggerView(ServiceEndPointCollection value)
private sealed class ServiceEndPointCollectionDebuggerView(ServiceEndPointSource value)
{
public IChangeToken ChangeToken => value.ChangeToken;

public IFeatureCollection Features => value.Features;

[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public ServiceEndPoint[] EndPoints => value.ToArray();
public ServiceEndPoint[] EndPoints => value.EndPoints.ToArray();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ protected DnsServiceEndPointResolverBase(
protected CancellationToken ShutdownToken => _disposeCancellation.Token;

/// <inheritdoc/>
public async ValueTask ResolveAsync(ServiceEndPointCollectionSource endPoints, CancellationToken cancellationToken)
public async ValueTask ResolveAsync(IServiceEndPointBuilder endPoints, CancellationToken cancellationToken)
{
// Only add endpoints to the collection if a previous provider (eg, a configuration override) did not add them.
if (endPoints.EndPoints.Count != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,32 +54,32 @@ public async ValueTask<ResolvedDestinationCollection> ResolveDestinationsAsync(I
var originalHost = originalConfig.Host is { Length: > 0 } h ? h : originalUri.Authority;
var serviceName = originalUri.GetLeftPart(UriPartial.Authority);

var endPoints = await resolver.GetEndPointsAsync(serviceName, cancellationToken).ConfigureAwait(false);
var results = new List<(string Name, DestinationConfig Config)>(endPoints.Count);
var result = await resolver.GetEndPointsAsync(serviceName, cancellationToken).ConfigureAwait(false);
var results = new List<(string Name, DestinationConfig Config)>(result.EndPoints.Count);
var uriBuilder = new UriBuilder(originalUri);
var healthUri = originalConfig.Health is { Length: > 0 } health ? new Uri(health) : null;
var healthUriBuilder = healthUri is { } ? new UriBuilder(healthUri) : null;
foreach (var endPoint in endPoints)
foreach (var endPoint in result.EndPoints)
{
var addressString = endPoint.GetEndPointString();
Uri result;
Uri uri;
if (!addressString.Contains("://"))
{
result = new Uri($"https://{addressString}");
uri = new Uri($"https://{addressString}");
}
else
{
result = new Uri(addressString);
uri = new Uri(addressString);
}

uriBuilder.Host = result.Host;
uriBuilder.Port = result.Port;
uriBuilder.Host = uri.Host;
uriBuilder.Port = uri.Port;
var resolvedAddress = uriBuilder.Uri.ToString();
var healthAddress = originalConfig.Health;
if (healthUriBuilder is not null)
{
healthUriBuilder.Host = result.Host;
healthUriBuilder.Port = result.Port;
healthUriBuilder.Host = uri.Host;
healthUriBuilder.Port = uri.Port;
healthAddress = healthUriBuilder.Uri.ToString();
}

Expand All @@ -88,6 +88,6 @@ public async ValueTask<ResolvedDestinationCollection> ResolveDestinationsAsync(I
results.Add((name, config));
}

return (results, endPoints.ChangeToken);
return (results, result.ChangeToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public ConfigurationServiceEndPointResolver(
public ValueTask DisposeAsync() => default;

/// <inheritdoc/>
public ValueTask ResolveAsync(ServiceEndPointCollectionSource endPoints, CancellationToken cancellationToken)
public ValueTask ResolveAsync(IServiceEndPointBuilder endPoints, CancellationToken cancellationToken)
{
// Only add resolved to the collection if a previous provider (eg, an override) did not add them.
if (endPoints.EndPoints.Count != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public ResolverEntry(ServiceEndPointWatcher resolver, IServiceEndPointSelector s
{
if (result.ResolvedSuccessfully)
{
_selector.SetEndPoints(result.EndPoints);
_selector.SetEndPoints(result.EndPointSource);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Microsoft.Extensions.ServiceDiscovery.Internal;
/// <summary>
/// Represents the result of service endpoint resolution.
/// </summary>
/// <param name="endPoints">The endpoint collection.</param>
/// <param name="endPointSource">The endpoint collection.</param>
/// <param name="exception">The exception which occurred during resolution.</param>
internal sealed class ServiceEndPointResolverResult(ServiceEndPointCollection? endPoints, Exception? exception)
internal sealed class ServiceEndPointResolverResult(ServiceEndPointSource? endPointSource, Exception? exception)
{
/// <summary>
/// Gets the exception which occurred during resolution.
Expand All @@ -20,11 +20,11 @@ internal sealed class ServiceEndPointResolverResult(ServiceEndPointCollection? e
/// <summary>
/// Gets a value indicating whether resolution completed successfully.
/// </summary>
[MemberNotNullWhen(true, nameof(EndPoints))]
[MemberNotNullWhen(true, nameof(EndPointSource))]
public bool ResolvedSuccessfully => Exception is null;

/// <summary>
/// Gets the endpoints.
/// </summary>
public ServiceEndPointCollection? EndPoints { get; } = endPoints;
public ServiceEndPointSource? EndPointSource { get; } = endPointSource;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ namespace Microsoft.Extensions.ServiceDiscovery.LoadBalancing;
internal sealed class RoundRobinServiceEndPointSelector : IServiceEndPointSelector
{
private uint _next;
private ServiceEndPointCollection? _endPoints;
private IReadOnlyList<ServiceEndPoint>? _endPoints;

/// <inheritdoc/>
public void SetEndPoints(ServiceEndPointCollection endPoints)
public void SetEndPoints(ServiceEndPointSource endPoints)
{
_endPoints = endPoints;
_endPoints = endPoints.EndPoints;
}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.Extensions.ServiceDiscovery.PassThrough;
/// </summary>
internal sealed partial class PassThroughServiceEndPointResolver(ILogger logger, string serviceName, EndPoint endPoint) : IServiceEndPointProvider
{
public ValueTask ResolveAsync(ServiceEndPointCollectionSource endPoints, CancellationToken cancellationToken)
public ValueTask ResolveAsync(IServiceEndPointBuilder endPoints, CancellationToken cancellationToken)
{
if (endPoints.EndPoints.Count == 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ namespace Microsoft.Extensions.ServiceDiscovery;
/// <summary>
/// A mutable collection of service endpoints.
/// </summary>
public sealed class ServiceEndPointCollectionSource
internal sealed class ServiceEndPointBuilder : IServiceEndPointBuilder
{
private readonly List<ServiceEndPoint> _endPoints = new();
private readonly List<IChangeToken> _changeTokens = new();
private FeatureCollection? _features;
private readonly FeatureCollection _features = new FeatureCollection();

/// <summary>
/// Adds a change token.
Expand All @@ -24,30 +24,23 @@ public void AddChangeToken(IChangeToken changeToken)
_changeTokens.Add(changeToken);
}

/// <summary>
/// Gets the composite change token.
/// </summary>
/// <returns>The composite change token.</returns>
public IChangeToken GetChangeToken() => new CompositeChangeToken(_changeTokens);

/// <summary>
/// Gets the feature collection.
/// </summary>
public IFeatureCollection Features => _features ??= new FeatureCollection();
public IFeatureCollection Features => _features;

/// <summary>
/// Gets the endpoints.
/// </summary>
public IList<ServiceEndPoint> EndPoints => _endPoints;

/// <summary>
/// Creates a <see cref="ServiceEndPointCollection"/> from the provided instance.
/// Creates a <see cref="ServiceEndPointSource"/> from the provided instance.
/// </summary>
/// <param name="source">The source collection.</param>
/// <returns>The service endpoint collection.</returns>
public static ServiceEndPointCollection CreateServiceEndPointCollection(ServiceEndPointCollectionSource source)
/// <returns>The service endpoint source.</returns>
public ServiceEndPointSource Build()
{
return new ServiceEndPointCollection(source._endPoints, source.GetChangeToken(), source.Features);
return new ServiceEndPointSource(_endPoints, new CompositeChangeToken(_changeTokens), _features);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal ServiceEndPointResolver(ServiceEndPointWatcherFactory resolverProvider,
/// <param name="serviceName">The service name.</param>
/// <param name="cancellationToken">A <see cref="CancellationToken"/>.</param>
/// <returns>The resolved service endpoints.</returns>
public async ValueTask<ServiceEndPointCollection> GetEndPointsAsync(string serviceName, CancellationToken cancellationToken)
public async ValueTask<ServiceEndPointSource> GetEndPointsAsync(string serviceName, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(serviceName);
ObjectDisposedException.ThrowIf(_disposed, this);
Expand Down Expand Up @@ -181,7 +181,7 @@ public bool CanExpire()
return (status & (CountMask | RecentUseFlag)) == 0;
}

public async ValueTask<(bool Valid, ServiceEndPointCollection? EndPoints)> GetEndPointsAsync(CancellationToken cancellationToken)
public async ValueTask<(bool Valid, ServiceEndPointSource? EndPoints)> GetEndPointsAsync(CancellationToken cancellationToken)
{
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ private sealed partial class Log
[LoggerMessage(3, LogLevel.Debug, "Resolved {Count} endpoints for service '{ServiceName}': {EndPoints}.", EventName = "ResolutionSucceeded")]
public static partial void ResolutionSucceededCore(ILogger logger, int count, string serviceName, string endPoints);

public static void ResolutionSucceeded(ILogger logger, string serviceName, ServiceEndPointCollection endPoints)
public static void ResolutionSucceeded(ILogger logger, string serviceName, ServiceEndPointSource endPointSource)
{
if (logger.IsEnabled(LogLevel.Debug))
{
ResolutionSucceededCore(logger, endPoints.Count, serviceName, string.Join(", ", endPoints.Select(GetEndPointString)));
ResolutionSucceededCore(logger, endPointSource.EndPoints.Count, serviceName, string.Join(", ", endPointSource.EndPoints.Select(GetEndPointString)));
}

static string GetEndPointString(ServiceEndPoint ep)
Expand Down
Loading

0 comments on commit 032d309

Please sign in to comment.