Skip to content

Commit cee2679

Browse files
committed
Add extensible resilience pipelines
1 parent 4101ff6 commit cee2679

35 files changed

Lines changed: 676 additions & 279 deletions

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"sdk": {
33
"version": "8.0.100",
4-
"rollForward": "latestMinor",
4+
"rollForward": "latestMajor",
55
"allowPrerelease": false
66
}
77
}

src/Foundatio.DataProtection/FoundatioStorageXmlRepository.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Xml.Linq;
77
using Foundatio.Storage;
88
using Foundatio.Utility;
9+
using Foundatio.Utility.Resilience;
910
using Microsoft.AspNetCore.DataProtection.Repositories;
1011
using Microsoft.Extensions.Logging;
1112
using Microsoft.Extensions.Logging.Abstractions;
@@ -22,17 +23,26 @@ public sealed class FoundatioStorageXmlRepository : IXmlRepository
2223
{
2324
private readonly IFileStorage _storage;
2425
private readonly ILogger _logger;
26+
private readonly IResiliencePipeline _resiliencePipeline;
2527

2628
/// <summary>
2729
/// Creates a new instance of the <see cref="FoundatioStorageXmlRepository"/>.
2830
/// </summary>
29-
public FoundatioStorageXmlRepository(IFileStorage storage, ILoggerFactory loggerFactory = null)
31+
public FoundatioStorageXmlRepository(IFileStorage storage, ILoggerFactory loggerFactory = null) : this(storage, null, loggerFactory)
32+
{
33+
}
34+
35+
/// <summary>
36+
/// Creates a new instance of the <see cref="FoundatioStorageXmlRepository"/>.
37+
/// </summary>
38+
public FoundatioStorageXmlRepository(IFileStorage storage, IResiliencePipelineProvider resiliencePipelineProvider, ILoggerFactory loggerFactory = null)
3039
{
3140
if (storage == null)
3241
throw new ArgumentNullException(nameof(storage));
3342

3443
_storage = new ScopedFileStorage(storage, "DataProtection");
3544
_logger = loggerFactory?.CreateLogger<FoundatioStorageXmlRepository>() ?? NullLogger<FoundatioStorageXmlRepository>.Instance;
45+
_resiliencePipeline = resiliencePipelineProvider?.GetPipeline(nameof(FoundatioStorageXmlRepository)) ?? new FoundatioResiliencePipeline(TimeProvider.System, _logger);
3646
}
3747

3848
/// <inheritdoc />
@@ -81,14 +91,14 @@ private Task StoreElementAsync(XElement element, string friendlyName)
8191
string path = String.Concat(!String.IsNullOrEmpty(friendlyName) ? friendlyName : Guid.NewGuid().ToString("N"), ".xml");
8292
_logger.LogTrace("Saving element: {File}.", path);
8393

84-
return Run.WithRetriesAsync(async () =>
94+
return _resiliencePipeline.ExecuteAsync(async ct =>
8595
{
8696
using var memoryStream = new MemoryStream();
8797
element.Save(memoryStream, SaveOptions.DisableFormatting);
8898
memoryStream.Seek(0, SeekOrigin.Begin);
8999

90-
await _storage.SaveFileAsync(path, memoryStream).AnyContext();
100+
await _storage.SaveFileAsync(path, memoryStream, ct).AnyContext();
91101
_logger.LogTrace("Saved element: {File}.", path);
92-
});
102+
}).AsTask();
93103
}
94104
}

src/Foundatio.TestHarness/Jobs/HelloWorldJob.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class HelloWorldJob : JobBase
1010
{
1111
private readonly string _id;
1212

13-
public HelloWorldJob(TimeProvider timeProvider, ILoggerFactory loggerFactory) : base(timeProvider, loggerFactory)
13+
public HelloWorldJob(TimeProvider timeProvider, ILoggerFactory loggerFactory) : base(timeProvider, null, loggerFactory)
1414
{
1515
_id = Guid.NewGuid().ToString("N").Substring(0, 10);
1616
}
@@ -35,7 +35,7 @@ public class FailingJob : JobBase
3535

3636
public int RunCount { get; set; }
3737

38-
public FailingJob(TimeProvider timeProvider, ILoggerFactory loggerFactory) : base(timeProvider, loggerFactory)
38+
public FailingJob(TimeProvider timeProvider, ILoggerFactory loggerFactory) : base(timeProvider, null, loggerFactory)
3939
{
4040
_id = Guid.NewGuid().ToString("N").Substring(0, 10);
4141
}
@@ -55,7 +55,7 @@ public class LongRunningJob : JobBase
5555
private readonly string _id;
5656
private int _iterationCount;
5757

58-
public LongRunningJob(TimeProvider timeProvider, ILoggerFactory loggerFactory) : base(timeProvider, loggerFactory)
58+
public LongRunningJob(TimeProvider timeProvider, ILoggerFactory loggerFactory) : base(timeProvider, null, loggerFactory)
5959
{
6060
_id = Guid.NewGuid().ToString("N").Substring(0, 10);
6161
}

src/Foundatio.TestHarness/Jobs/JobQueueTestsBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ await queue.EnqueueAsync(new SampleQueueWorkItem
108108
});
109109
});
110110

111-
var lockProvider = new ThrottlingLockProvider(new InMemoryCacheClient(o => o.LoggerFactory(Log)), allowedLockCount, TimeSpan.FromDays(1), null, Log);
111+
var lockProvider = new ThrottlingLockProvider(new InMemoryCacheClient(o => o.LoggerFactory(Log)), allowedLockCount, TimeSpan.FromDays(1), null, null, Log);
112112
var job = new SampleQueueJobWithLocking(queue, lockProvider, null, Log);
113113
await Task.Delay(10);
114114
_logger.LogInformation("Starting RunUntilEmptyAsync");

src/Foundatio.TestHarness/Jobs/SampleQueueJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public class SampleQueueWorkItem
7676

7777
public class SampleJob : JobBase
7878
{
79-
public SampleJob(TimeProvider timeProvider, ILoggerFactory loggerFactory) : base(timeProvider, loggerFactory)
79+
public SampleJob(TimeProvider timeProvider, ILoggerFactory loggerFactory) : base(timeProvider, null, loggerFactory)
8080
{
8181
}
8282

src/Foundatio.TestHarness/Jobs/ThrottledJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class ThrottledJob : JobWithLockBase
1212
{
1313
public ThrottledJob(ICacheClient client, ILoggerFactory loggerFactory = null) : base(loggerFactory)
1414
{
15-
_locker = new ThrottlingLockProvider(client, 1, TimeSpan.FromMilliseconds(100), null, loggerFactory);
15+
_locker = new ThrottlingLockProvider(client, 1, TimeSpan.FromMilliseconds(100), null, null, loggerFactory);
1616
}
1717

1818
private readonly ILockProvider _locker;

src/Foundatio.TestHarness/Jobs/WithDependencyJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Foundatio.Tests.Jobs;
66

77
public class WithDependencyJob : JobBase
88
{
9-
public WithDependencyJob(MyDependency dependency, ILoggerFactory loggerFactory = null) : base(null, loggerFactory)
9+
public WithDependencyJob(MyDependency dependency, ILoggerFactory loggerFactory = null) : base(null, null, loggerFactory)
1010
{
1111
Dependency = dependency;
1212
}

src/Foundatio.TestHarness/Jobs/WithLockingJob.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class WithLockingJob : JobWithLockBase
1616

1717
public WithLockingJob(ILoggerFactory loggerFactory) : base(loggerFactory)
1818
{
19-
_locker = new CacheLockProvider(new InMemoryCacheClient(o => o.LoggerFactory(loggerFactory)), new InMemoryMessageBus(o => o.LoggerFactory(loggerFactory)), null, loggerFactory);
19+
_locker = new CacheLockProvider(new InMemoryCacheClient(o => o.LoggerFactory(loggerFactory)), new InMemoryMessageBus(o => o.LoggerFactory(loggerFactory)), null, null, loggerFactory);
2020
}
2121

2222
public int RunCount { get; set; }

src/Foundatio.TestHarness/Queue/QueueTestBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,7 @@ public virtual async Task CanDequeueWithLockingAsync()
12811281
using var cache = new InMemoryCacheClient(o => o.LoggerFactory(Log));
12821282
using var messageBus = new InMemoryMessageBus(o => o.LoggerFactory(Log));
12831283

1284-
var distributedLock = new CacheLockProvider(cache, messageBus, null, Log);
1284+
var distributedLock = new CacheLockProvider(cache, messageBus, null, null, Log);
12851285
await CanDequeueWithLockingImpAsync(distributedLock);
12861286
}
12871287

@@ -1335,7 +1335,7 @@ public virtual async Task CanHaveMultipleQueueInstancesWithLockingAsync()
13351335
using var cache = new InMemoryCacheClient(o => o.LoggerFactory(Log));
13361336
using var messageBus = new InMemoryMessageBus(o => o.LoggerFactory(Log));
13371337

1338-
var distributedLock = new CacheLockProvider(cache, messageBus, null, Log);
1338+
var distributedLock = new CacheLockProvider(cache, messageBus, null, null, Log);
13391339
await CanHaveMultipleQueueInstancesWithLockingImplAsync(distributedLock);
13401340
}
13411341

src/Foundatio/Caching/HybridCacheClient.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,33 @@
55
using System.Threading.Tasks;
66
using Foundatio.Messaging;
77
using Foundatio.Utility;
8+
using Foundatio.Utility.Resilience;
89
using Microsoft.Extensions.Logging;
910
using Microsoft.Extensions.Logging.Abstractions;
1011

1112
namespace Foundatio.Caching;
1213

1314
public interface IHybridCacheClient : ICacheClient { }
1415

15-
public class HybridCacheClient : IHybridCacheClient, IHaveTimeProvider, IHaveLogger
16+
public class HybridCacheClient : IHybridCacheClient, IHaveTimeProvider, IHaveLogger, IHaveLoggerFactory, IHaveResiliencePipelineProvider
1617
{
1718
protected readonly ICacheClient _distributedCache;
1819
protected readonly IMessageBus _messageBus;
1920
private readonly string _cacheId = Guid.NewGuid().ToString("N");
2021
private readonly InMemoryCacheClient _localCache;
2122
private readonly ILogger _logger;
23+
private readonly ILoggerFactory _loggerFactory;
24+
private readonly TimeProvider _timeProvider;
25+
private readonly IResiliencePipelineProvider _resiliencePipelineProvider;
2226
private long _localCacheHits;
2327
private long _invalidateCacheCalls;
2428

2529
public HybridCacheClient(ICacheClient distributedCacheClient, IMessageBus messageBus, InMemoryCacheClientOptions localCacheOptions = null, ILoggerFactory loggerFactory = null)
2630
{
27-
_logger = loggerFactory?.CreateLogger<HybridCacheClient>() ?? NullLogger<HybridCacheClient>.Instance;
31+
_loggerFactory = loggerFactory ?? distributedCacheClient.GetLoggerFactory() ?? localCacheOptions.LoggerFactory ?? NullLoggerFactory.Instance;
32+
_logger = _loggerFactory.CreateLogger<HybridCacheClient>();
33+
_timeProvider = distributedCacheClient.GetTimeProvider() ?? localCacheOptions?.TimeProvider ?? TimeProvider.System;
34+
_resiliencePipelineProvider = distributedCacheClient.GetResiliencePipelineProvider() ?? localCacheOptions?.ResiliencePipelineProvider;
2835
_distributedCache = distributedCacheClient;
2936
_messageBus = messageBus;
3037
_messageBus.SubscribeAsync<InvalidateCache>(OnRemoteCacheItemExpiredAsync).AnyContext().GetAwaiter().GetResult();
@@ -39,7 +46,9 @@ public HybridCacheClient(ICacheClient distributedCacheClient, IMessageBus messag
3946
public long InvalidateCacheCalls => _invalidateCacheCalls;
4047

4148
ILogger IHaveLogger.Logger => _logger;
42-
TimeProvider IHaveTimeProvider.TimeProvider => _distributedCache.GetTimeProvider();
49+
ILoggerFactory IHaveLoggerFactory.LoggerFactory => _loggerFactory;
50+
TimeProvider IHaveTimeProvider.TimeProvider => _timeProvider;
51+
IResiliencePipelineProvider IHaveResiliencePipelineProvider.ResiliencePipelineProvider => _resiliencePipelineProvider;
4352

4453
private Task OnLocalCacheItemExpiredAsync(object sender, ItemExpiredEventArgs args)
4554
{

0 commit comments

Comments
 (0)