Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
8 changes: 6 additions & 2 deletions src/IceRpc.Locator/LocatorInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,17 @@ public async Task<IncomingResponse> InvokeAsync(OutgoingRequest request, Cancell
ServiceAddress serviceAddress,
IEnumerable<ServerAddress> excludedAddresses)
{
// Use the ServerAddressComparer.OptionalTransport comparer so the filter matches the connection layer's
// equality.
(ServerAddress? ServerAddress, ImmutableList<ServerAddress> AltServerAddresses) result =
(serviceAddress.ServerAddress, serviceAddress.AltServerAddresses);
if (result.ServerAddress is ServerAddress serverAddress && excludedAddresses.Contains(serverAddress))
if (result.ServerAddress is ServerAddress serverAddress &&
excludedAddresses.Contains(serverAddress, ServerAddressComparer.OptionalTransport))
{
result.ServerAddress = null;
}
result.AltServerAddresses = result.AltServerAddresses.RemoveAll(e => excludedAddresses.Contains(e));
result.AltServerAddresses = result.AltServerAddresses.RemoveAll(
e => excludedAddresses.Contains(e, ServerAddressComparer.OptionalTransport));

if (result.ServerAddress is null && result.AltServerAddresses.Count > 0)
{
Expand Down
29 changes: 29 additions & 0 deletions tests/IceRpc.Locator.Tests/LocatorInterceptorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,35 @@ public async Task Resolve_refresh_cache_on_the_second_lookup()
Assert.That(locationResolver.RefreshCache, Is.True);
}

/// <summary>Verifies that an excluded server address that differs only in transport from a newly-resolved one
/// is filtered out: the connection layer treats them as the same physical endpoint, so the locator must use the
/// same OptionalTransport equality when applying RemovedServerAddresses.</summary>
[Test]
public async Task Removed_address_with_explicit_transport_filters_resolved_address_without_transport()
{
// Arrange
var invoker = new InlineInvoker((request, cancellationToken) =>
Task.FromResult(new IncomingResponse(request, FakeConnectionContext.Instance)));
var resolved = new ServiceAddress(new Uri("ice://localhost:10000/foo"));
var locationResolver = new MockLocationResolver(resolved, adapterId: false);
var sut = new LocatorInterceptor(invoker, locationResolver);
var serviceAddress = new ServiceAddress(Protocol.Ice) { Path = "/foo" };
using var request = new OutgoingRequest(serviceAddress);
var serverAddressFeature = new ServerAddressFeature(serviceAddress)
{
RemovedServerAddresses = ImmutableList.Create(
new ServerAddress(new Uri("ice://localhost:10000?transport=tcp")))
};
request.Features = request.Features.With<IServerAddressFeature>(serverAddressFeature);

// Act
await sut.InvokeAsync(request, default);

// Assert
Assert.That(serverAddressFeature.ServerAddress, Is.Null);
Assert.That(serverAddressFeature.AltServerAddresses, Is.Empty);
}

/// <summary>Verifies that the locator interceptor does not set the refresh cache parameter on the second attempt
/// to resolve a location if the first attempt returned a non cached result.</summary>
[Test]
Expand Down
Loading