Skip to content
Merged
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
30 changes: 28 additions & 2 deletions src/IceRpc.Locator/Internal/LocationResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ internal static partial void LogFailedToResolve(
string locationKind,
Location location,
Exception? exception = null);

[LoggerMessage(
EventId = (int)LocationEventId.BackgroundRefreshFailed,
EventName = nameof(LocationEventId.BackgroundRefreshFailed),
Level = LogLevel.Debug,
Message = "Background cache refresh failed for {LocationKind} '{Location}'")]
internal static partial void LogBackgroundRefreshFailed(
this ILogger logger,
string locationKind,
Location location,
Exception exception);
}

/// <summary>An implementation of <see cref="ILocationResolver" /> without a cache.</summary>
Expand Down Expand Up @@ -67,6 +78,7 @@ internal CacheLessLocationResolver(IServerAddressFinder serverAddressFinder) =>
internal class LocationResolver : ILocationResolver
{
private readonly bool _background;
private readonly ILogger _logger;
private readonly IServerAddressCache _serverAddressCache;
private readonly IServerAddressFinder _serverAddressFinder;
private readonly TimeSpan _refreshThreshold;
Expand All @@ -78,13 +90,15 @@ internal LocationResolver(
IServerAddressCache serverAddressCache,
bool background,
TimeSpan refreshThreshold,
TimeSpan ttl)
TimeSpan ttl,
ILogger logger)
{
_serverAddressFinder = serverAddressFinder;
_serverAddressCache = serverAddressCache;
_background = background;
_refreshThreshold = refreshThreshold;
_ttl = ttl;
_logger = logger;
}

public ValueTask<(ServiceAddress? ServiceAddress, bool FromCache)> ResolveAsync(
Expand Down Expand Up @@ -118,7 +132,7 @@ internal LocationResolver(
else if (_background && expired)
{
// We retrieved an expired service address from the cache, so we launch a refresh in the background.
_ = _serverAddressFinder.FindAsync(location, cancellationToken: default).ConfigureAwait(false);
_ = RefreshInBackgroundAsync();
}

// A well-known service address resolution can return a service address with an adapter-id.
Expand Down Expand Up @@ -150,6 +164,18 @@ internal LocationResolver(
}

return (serviceAddress, serviceAddress is not null && !resolved);

async Task RefreshInBackgroundAsync()
{
try
{
_ = await _serverAddressFinder.FindAsync(location, cancellationToken: default).ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.LogBackgroundRefreshFailed(location.Kind, location, exception);
}
}
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/IceRpc.Locator/LocationEventId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,8 @@ public enum LocationEventId
FindFailed,

/// <summary>The server address finder found server address(es) for the given location.</summary>
Found
Found,

/// <summary>A background cache refresh failed.</summary>
BackgroundRefreshFailed
}
3 changes: 2 additions & 1 deletion src/IceRpc.Locator/LocatorInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ public LocatorLocationResolver(ILocator locator, LocatorOptions options, ILogger
serverAddressCache,
options.Background,
options.RefreshThreshold,
options.Ttl);
options.Ttl,
logger);
if (logger != NullLogger.Instance)
{
_locationResolver = new LogLocationResolverDecorator(_locationResolver, logger);
Expand Down
16 changes: 11 additions & 5 deletions tests/IceRpc.Locator.Tests/LocationResolverTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) ZeroC, Inc.

using IceRpc.Locator.Internal;
using Microsoft.Extensions.Logging.Abstractions;
using NUnit.Framework;

namespace IceRpc.Locator.Tests;
Expand All @@ -21,7 +22,8 @@ public async Task ServerAddress_finder_not_called_when_cache_entry_age_is_less_o
new MockServerAddressCache(cachedServiceAddress, insertionTime: TimeSpan.FromSeconds(cacheEntryAge)),
background: false,
TimeSpan.FromSeconds(refreshThreshold),
ttl: Timeout.InfiniteTimeSpan);
ttl: Timeout.InfiniteTimeSpan,
NullLogger.Instance);

(ServiceAddress? resolved, bool _) = await resolver.ResolveAsync(default, refreshCache: true, default);

Expand All @@ -44,7 +46,8 @@ public async Task ServerAddress_finder_called_when_cache_entry_age_is_greater_th
new MockServerAddressCache(cachedServiceAddress, insertionTime: TimeSpan.FromSeconds(cacheEntryAge)),
background: false,
TimeSpan.FromSeconds(refreshThreshold),
ttl: Timeout.InfiniteTimeSpan);
ttl: Timeout.InfiniteTimeSpan,
NullLogger.Instance);

(ServiceAddress? resolved, bool _) = await resolver.ResolveAsync(default, refreshCache: true, default);

Expand All @@ -64,7 +67,8 @@ public async Task ServerAddress_finder_called_on_background()
new MockServerAddressCache(cachedServiceAddress, insertionTime: TimeSpan.FromSeconds(120)),
background: true,
TimeSpan.FromSeconds(1),
ttl: TimeSpan.FromSeconds(30));
ttl: TimeSpan.FromSeconds(30),
NullLogger.Instance);

(ServiceAddress? resolved, bool fromCache) = await resolver.ResolveAsync(default, refreshCache: false, default);

Expand All @@ -84,7 +88,8 @@ public async Task Location_recursive_resolution()
new MockServerAddressCache(),
background: true,
TimeSpan.FromSeconds(1),
ttl: TimeSpan.FromSeconds(30));
ttl: TimeSpan.FromSeconds(30),
NullLogger.Instance);

(ServiceAddress? resolved, bool fromCache) = await resolver.ResolveAsync(
new Location
Expand All @@ -111,7 +116,8 @@ public async Task Failure_to_recursively_resolve_adapter_id_removes_proxy_from_c
serverAddressCache,
background: true,
TimeSpan.FromSeconds(1),
ttl: TimeSpan.FromSeconds(30));
ttl: TimeSpan.FromSeconds(30),
NullLogger.Instance);
var location = new Location
{
Value = "/hello",
Expand Down
Loading