Skip to content

Commit 4df2018

Browse files
authored
Merge pull request #393 from reisenberger/v570tidyTtlStrategies
More on `ResultTtl`, merged to `v5.7.0` branch
2 parents a10dbd2 + 40d376c commit 4df2018

6 files changed

Lines changed: 53 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
## 5.7.0
33
- Minor cache fixes
4+
- Add ability to calculate cache Ttl based on item to cache
45
- Allow user-created custom policies
56

67
## 5.6.1

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,7 @@ For details of changes by release see the [change log](https://github.com/App-vN
947947
* [@reisenberger](https://github.com/reisenberger) - Add new .HandleInner<TException>(...) syntax for handling inner exceptions natively.
948948
* [@rjongeneelen](https://github.com/rjongeneelen) and [@reisenberger](https://github.com/reisenberger) - Allow PolicyWrap configuration to configure policies via interfaces.
949949
* [@reisenberger](https://github.com/reisenberger) - Performance improvements.
950+
* [@awarrenlove](https://github.com/awarrenlove) - Add ability to calculate cache Ttl based on item to cache.
950951
951952
# Sample Projects
952953

src/Polly.Net40Async.nuspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
5.7.0
1919
---------------------
2020
- Minor cache fixes
21+
- Add ability to calculate cache Ttl based on item to cache
2122
- Allow user-created custom policies
2223

2324
5.6.1

src/Polly.Shared/Caching/ResultTtl.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,30 @@
55
namespace Polly.Caching
66
{
77
/// <summary>
8-
/// Defines a ttl strategy which will cache items with some calculation from the result of the execution.
8+
/// Defines a ttl strategy which can calculate a duration to cache items dynamically based on the execution context and result of the execution.
99
/// </summary>
10-
10+
/// <typeparam name="TResult">The type of results that the ttl calculation function will take as an input parameter.</typeparam>
1111
public class ResultTtl<TResult> : ITtlStrategy<TResult>
1212
{
13-
private readonly Func<TResult, Ttl> ttlFunc;
13+
private readonly Func<Context, TResult, Ttl> _ttlFunc;
1414

1515
/// <summary>
16-
/// Constructs a new instance of the <see cref="ResultTtl{TResult}"/> ttl strategy.
16+
/// Constructs a new instance of the <see cref="ResultTtl{TResult}"/> ttl strategy, with a func calculating <see cref="Ttl"/> based on the <typeparamref name="TResult"/> value to cache.
1717
/// </summary>
1818
/// <param name="ttlFunc">The function to calculate the TTL for which cache items should be considered valid.</param>
1919
public ResultTtl(Func<TResult, Ttl> ttlFunc)
2020
{
2121
if (ttlFunc == null) throw new ArgumentNullException(nameof(ttlFunc));
22+
_ttlFunc = (context, result) => ttlFunc(result);
23+
}
2224

23-
this.ttlFunc = ttlFunc;
25+
/// <summary>
26+
/// Constructs a new instance of the <see cref="ResultTtl{TResult}"/> ttl strategy, with a func calculating <see cref="Ttl"/> based on the execution <see cref="Context"/> and <typeparamref name="TResult"/> value to cache.
27+
/// </summary>
28+
/// <param name="ttlFunc">The function to calculate the TTL for which cache items should be considered valid.</param>
29+
public ResultTtl(Func<Context, TResult, Ttl> ttlFunc)
30+
{
31+
_ttlFunc = ttlFunc ?? throw new ArgumentNullException(nameof(ttlFunc));
2432
}
2533

2634
/// <summary>
@@ -32,7 +40,7 @@ public ResultTtl(Func<TResult, Ttl> ttlFunc)
3240

3341
public Ttl GetTtl(Context context, TResult result)
3442
{
35-
return ttlFunc(result);
43+
return _ttlFunc(context, result);
3644
}
3745
}
3846
}
Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
42
using FluentAssertions;
53
using Polly.Caching;
4+
using Polly.Specs.Helpers.Caching;
65
using Xunit;
76

87
namespace Polly.Specs.Caching
@@ -12,15 +11,31 @@ public class ResultTtlSpecs
1211
[Fact]
1312
public void Should_throw_when_func_is_null()
1413
{
15-
Action configure = () => new ResultTtl<dynamic>(null);
14+
Action configure = () => new ResultTtl<object>((Func<object, Ttl>)null);
15+
16+
configure.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("ttlFunc");
17+
}
18+
19+
[Fact]
20+
public void Should_throw_when_func_is_null_using_context()
21+
{
22+
Action configure = () => new ResultTtl<object>((Func<Context, object, Ttl>)null);
1623

1724
configure.ShouldThrow<ArgumentNullException>().And.ParamName.Should().Be("ttlFunc");
1825
}
1926

2027
[Fact]
2128
public void Should_not_throw_when_func_is_set()
2229
{
23-
Action configure = () => new ResultTtl<dynamic>((result) => new Ttl());
30+
Action configure = () => new ResultTtl<object>((result) => new Ttl());
31+
32+
configure.ShouldNotThrow();
33+
}
34+
35+
[Fact]
36+
public void Should_not_throw_when_func_is_set_using_context()
37+
{
38+
Action configure = () => new ResultTtl<object>((context, result) => new Ttl());
2439

2540
configure.ShouldNotThrow();
2641
}
@@ -29,13 +44,27 @@ public void Should_not_throw_when_func_is_set()
2944
public void Should_return_func_result()
3045
{
3146
TimeSpan ttl = TimeSpan.FromMinutes(1);
32-
Func<dynamic, Ttl> func = (result) => { return new Ttl(ttl); };
47+
Func<dynamic, Ttl> func = (result) => { return new Ttl(result.Ttl); };
3348

3449
ResultTtl<dynamic> ttlStrategy = new ResultTtl<dynamic>(func);
3550

3651
Ttl retrieved = ttlStrategy.GetTtl(new Context("someExecutionKey"), new { Ttl = ttl });
37-
retrieved.Timespan.Should().BeCloseTo(ttl);
52+
retrieved.Timespan.Should().Be(ttl);
3853
retrieved.SlidingExpiration.Should().BeFalse();
3954
}
55+
56+
[Fact]
57+
public void Should_return_func_result_using_context()
58+
{
59+
const string specialKey = "specialKey";
60+
61+
TimeSpan ttl = TimeSpan.FromMinutes(1);
62+
Func<Context, dynamic, Ttl> func = (context, result) => { return context.ExecutionKey == specialKey ? new Ttl(TimeSpan.Zero) : new Ttl(result.Ttl); };
63+
64+
ResultTtl<dynamic> ttlStrategy = new ResultTtl<dynamic>(func);
65+
66+
ttlStrategy.GetTtl(new Context("someExecutionKey"), new { Ttl = ttl }).Timespan.Should().Be(ttl);
67+
ttlStrategy.GetTtl(new Context(specialKey), new { Ttl = ttl }).Timespan.Should().Be(TimeSpan.Zero);
68+
}
4069
}
4170
}

src/Polly.nuspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
5.7.0
1919
---------------------
2020
- Minor cache fixes
21+
- Add ability to calculate cache Ttl based on item to cache
2122
- Allow user-created custom policies
2223

2324
5.6.1

0 commit comments

Comments
 (0)