sprints work
This commit is contained in:
@@ -20,6 +20,7 @@ public sealed class CiscoProviderMetadataLoader
|
||||
private readonly ILogger<CiscoProviderMetadataLoader> _logger;
|
||||
private readonly CiscoConnectorOptions _options;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
private readonly JsonSerializerOptions _serializerOptions;
|
||||
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
||||
|
||||
@@ -28,7 +29,8 @@ public sealed class CiscoProviderMetadataLoader
|
||||
IMemoryCache memoryCache,
|
||||
IOptions<CiscoConnectorOptions> options,
|
||||
ILogger<CiscoProviderMetadataLoader> logger,
|
||||
IFileSystem? fileSystem = null)
|
||||
IFileSystem? fileSystem = null,
|
||||
TimeProvider? timeProvider = null)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
|
||||
_memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache));
|
||||
@@ -36,6 +38,7 @@ public sealed class CiscoProviderMetadataLoader
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
_options = options.Value ?? throw new ArgumentNullException(nameof(options));
|
||||
_fileSystem = fileSystem ?? new FileSystem();
|
||||
_timeProvider = timeProvider ?? TimeProvider.System;
|
||||
_serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web)
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
@@ -45,7 +48,8 @@ public sealed class CiscoProviderMetadataLoader
|
||||
|
||||
public async Task<CiscoProviderMetadataResult> LoadAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_memoryCache.TryGetValue<CacheEntry>(CacheKey, out var cached) && cached is not null && !cached.IsExpired())
|
||||
var now = _timeProvider.GetUtcNow();
|
||||
if (_memoryCache.TryGetValue<CacheEntry>(CacheKey, out var cached) && cached is not null && !cached.IsExpired(now))
|
||||
{
|
||||
_logger.LogDebug("Returning cached Cisco provider metadata (expires {Expires}).", cached.ExpiresAt);
|
||||
return new CiscoProviderMetadataResult(cached.Provider, cached.FetchedAt, cached.FromOffline, true);
|
||||
@@ -54,7 +58,8 @@ public sealed class CiscoProviderMetadataLoader
|
||||
await _semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (_memoryCache.TryGetValue<CacheEntry>(CacheKey, out cached) && cached is not null && !cached.IsExpired())
|
||||
now = _timeProvider.GetUtcNow();
|
||||
if (_memoryCache.TryGetValue<CacheEntry>(CacheKey, out cached) && cached is not null && !cached.IsExpired(now))
|
||||
{
|
||||
return new CiscoProviderMetadataResult(cached.Provider, cached.FetchedAt, cached.FromOffline, true);
|
||||
}
|
||||
@@ -76,8 +81,8 @@ public sealed class CiscoProviderMetadataLoader
|
||||
{
|
||||
var entry = offline with
|
||||
{
|
||||
FetchedAt = DateTimeOffset.UtcNow,
|
||||
ExpiresAt = DateTimeOffset.UtcNow + _options.MetadataCacheDuration,
|
||||
FetchedAt = _timeProvider.GetUtcNow(),
|
||||
ExpiresAt = _timeProvider.GetUtcNow() + _options.MetadataCacheDuration,
|
||||
FromOffline = true,
|
||||
};
|
||||
StoreCache(entry);
|
||||
@@ -115,8 +120,8 @@ public sealed class CiscoProviderMetadataLoader
|
||||
_logger.LogDebug("Cisco provider metadata not modified (etag {ETag}).", previous.ETag);
|
||||
return previous with
|
||||
{
|
||||
FetchedAt = DateTimeOffset.UtcNow,
|
||||
ExpiresAt = DateTimeOffset.UtcNow + _options.MetadataCacheDuration,
|
||||
FetchedAt = _timeProvider.GetUtcNow(),
|
||||
ExpiresAt = _timeProvider.GetUtcNow() + _options.MetadataCacheDuration,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -140,8 +145,8 @@ public sealed class CiscoProviderMetadataLoader
|
||||
|
||||
return new CacheEntry(
|
||||
provider,
|
||||
DateTimeOffset.UtcNow,
|
||||
DateTimeOffset.UtcNow + _options.MetadataCacheDuration,
|
||||
_timeProvider.GetUtcNow(),
|
||||
_timeProvider.GetUtcNow() + _options.MetadataCacheDuration,
|
||||
etagHeader,
|
||||
FromOffline: false);
|
||||
}
|
||||
@@ -169,7 +174,7 @@ public sealed class CiscoProviderMetadataLoader
|
||||
{
|
||||
var payload = _fileSystem.File.ReadAllText(_options.OfflineSnapshotPath);
|
||||
var provider = ParseProvider(payload);
|
||||
return new CacheEntry(provider, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow + _options.MetadataCacheDuration, null, true);
|
||||
return new CacheEntry(provider, _timeProvider.GetUtcNow(), _timeProvider.GetUtcNow() + _options.MetadataCacheDuration, null, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -242,7 +247,7 @@ public sealed class CiscoProviderMetadataLoader
|
||||
string? ETag,
|
||||
bool FromOffline)
|
||||
{
|
||||
public bool IsExpired() => DateTimeOffset.UtcNow >= ExpiresAt;
|
||||
public bool IsExpired(DateTimeOffset now) => now >= ExpiresAt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ public sealed class RancherHubMetadataLoader
|
||||
private readonly RancherHubTokenProvider _tokenProvider;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly ILogger<RancherHubMetadataLoader> _logger;
|
||||
private readonly TimeProvider _timeProvider;
|
||||
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
||||
private readonly JsonDocumentOptions _documentOptions;
|
||||
|
||||
@@ -33,13 +34,15 @@ public sealed class RancherHubMetadataLoader
|
||||
IMemoryCache memoryCache,
|
||||
RancherHubTokenProvider tokenProvider,
|
||||
IFileSystem fileSystem,
|
||||
ILogger<RancherHubMetadataLoader> logger)
|
||||
ILogger<RancherHubMetadataLoader> logger,
|
||||
TimeProvider? timeProvider = null)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
|
||||
_memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache));
|
||||
_tokenProvider = tokenProvider ?? throw new ArgumentNullException(nameof(tokenProvider));
|
||||
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_timeProvider = timeProvider ?? TimeProvider.System;
|
||||
_documentOptions = new JsonDocumentOptions
|
||||
{
|
||||
CommentHandling = JsonCommentHandling.Skip,
|
||||
@@ -52,7 +55,7 @@ public sealed class RancherHubMetadataLoader
|
||||
ArgumentNullException.ThrowIfNull(options);
|
||||
|
||||
var cacheKey = CreateCacheKey(options);
|
||||
if (_memoryCache.TryGetValue<CacheEntry>(cacheKey, out var cached) && cached is not null && !cached.IsExpired())
|
||||
if (_memoryCache.TryGetValue<CacheEntry>(cacheKey, out var cached) && cached is not null && !cached.IsExpired(_timeProvider.GetUtcNow()))
|
||||
{
|
||||
_logger.LogDebug("Returning cached Rancher hub metadata (expires {Expires}).", cached.ExpiresAt);
|
||||
return new RancherHubMetadataResult(cached.Metadata, cached.FetchedAt, FromCache: true, cached.FromOfflineSnapshot);
|
||||
@@ -61,7 +64,7 @@ public sealed class RancherHubMetadataLoader
|
||||
await _semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
if (_memoryCache.TryGetValue<CacheEntry>(cacheKey, out cached) && cached is not null && !cached.IsExpired())
|
||||
if (_memoryCache.TryGetValue<CacheEntry>(cacheKey, out cached) && cached is not null && !cached.IsExpired(_timeProvider.GetUtcNow()))
|
||||
{
|
||||
return new RancherHubMetadataResult(cached.Metadata, cached.FetchedAt, FromCache: true, cached.FromOfflineSnapshot);
|
||||
}
|
||||
@@ -131,8 +134,8 @@ public sealed class RancherHubMetadataLoader
|
||||
_logger.LogDebug("Rancher hub discovery document not modified (etag {ETag}).", previous.ETag);
|
||||
return previous with
|
||||
{
|
||||
FetchedAt = DateTimeOffset.UtcNow,
|
||||
ExpiresAt = DateTimeOffset.UtcNow + options.MetadataCacheDuration,
|
||||
FetchedAt = _timeProvider.GetUtcNow(),
|
||||
ExpiresAt = _timeProvider.GetUtcNow() + options.MetadataCacheDuration,
|
||||
FromOfflineSnapshot = false,
|
||||
};
|
||||
}
|
||||
@@ -142,8 +145,8 @@ public sealed class RancherHubMetadataLoader
|
||||
var metadata = ParseMetadata(payload, options);
|
||||
var entry = new CacheEntry(
|
||||
metadata,
|
||||
DateTimeOffset.UtcNow,
|
||||
DateTimeOffset.UtcNow + options.MetadataCacheDuration,
|
||||
_timeProvider.GetUtcNow(),
|
||||
_timeProvider.GetUtcNow() + options.MetadataCacheDuration,
|
||||
response.Headers.ETag?.ToString(),
|
||||
FromOfflineSnapshot: false,
|
||||
Payload: payload);
|
||||
@@ -177,8 +180,8 @@ public sealed class RancherHubMetadataLoader
|
||||
var metadata = ParseMetadata(payload, options);
|
||||
return new CacheEntry(
|
||||
metadata,
|
||||
DateTimeOffset.UtcNow,
|
||||
DateTimeOffset.UtcNow + options.MetadataCacheDuration,
|
||||
_timeProvider.GetUtcNow(),
|
||||
_timeProvider.GetUtcNow() + options.MetadataCacheDuration,
|
||||
ETag: null,
|
||||
FromOfflineSnapshot: true,
|
||||
Payload: payload);
|
||||
@@ -422,7 +425,7 @@ public sealed class RancherHubMetadataLoader
|
||||
bool FromOfflineSnapshot,
|
||||
string? Payload)
|
||||
{
|
||||
public bool IsExpired() => DateTimeOffset.UtcNow >= ExpiresAt;
|
||||
public bool IsExpired(DateTimeOffset now) => now >= ExpiresAt;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user