Skip to content

Commit 4e4ae7c

Browse files
committed
Add GetValueOrCreateAsync() in IMemcachedClient
1 parent d83cb8c commit 4e4ae7c

File tree

4 files changed

+132
-89
lines changed

4 files changed

+132
-89
lines changed

Enyim.Caching.Tests/MemcachedClientGetTests.cs

Lines changed: 110 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -2,101 +2,122 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Text;
5+
using System.Threading.Tasks;
56
using Enyim.Caching.Memcached.Results.StatusCodes;
67
using Xunit;
78

89
namespace Enyim.Caching.Tests
910
{
10-
public class MemcachedClientGetTests : MemcachedClientTestsBase
11-
{
12-
[Fact]
13-
public void When_Getting_Existing_Item_Value_Is_Not_Null_And_Result_Is_Successful()
14-
{
15-
var key = GetUniqueKey("get");
16-
var value = GetRandomString();
17-
var storeResult = Store(key: key, value: value);
18-
StoreAssertPass(storeResult);
19-
20-
var getResult = _client.ExecuteGet(key);
21-
GetAssertPass(getResult, value);
22-
}
23-
24-
[Fact]
25-
public void When_Getting_Item_For_Invalid_Key_HasValue_Is_False_And_Result_Is_Not_Successful()
26-
{
27-
var key = GetUniqueKey("get");
28-
29-
var getResult = _client.ExecuteGet(key);
30-
Assert.True(getResult.StatusCode == (int)StatusCodeEnums.NotFound, "Invalid status code");
31-
GetAssertFail(getResult);
32-
}
33-
34-
[Fact]
35-
public void When_TryGetting_Existing_Item_Value_Is_Not_Null_And_Result_Is_Successful()
36-
{
37-
var key = GetUniqueKey("get");
38-
var value = GetRandomString();
39-
var storeResult = Store(key: key, value: value);
40-
StoreAssertPass(storeResult);
41-
42-
object temp;
43-
var getResult = _client.ExecuteTryGet(key, out temp);
44-
GetAssertPass(getResult, temp);
45-
}
46-
47-
[Fact]
48-
public void When_Generic_Getting_Existing_Item_Value_Is_Not_Null_And_Result_Is_Successful()
49-
{
50-
var key = GetUniqueKey("get");
51-
var value = GetRandomString();
52-
var storeResult = Store(key: key, value: value);
53-
StoreAssertPass(storeResult);
54-
55-
var getResult = _client.ExecuteGet<string>(key);
56-
Assert.True(getResult.Success, "Success was false");
57-
Assert.True(getResult.Cas > 0, "Cas value was 0");
11+
public class MemcachedClientGetTests : MemcachedClientTestsBase
12+
{
13+
[Fact]
14+
public void When_Getting_Existing_Item_Value_Is_Not_Null_And_Result_Is_Successful()
15+
{
16+
var key = GetUniqueKey("get");
17+
var value = GetRandomString();
18+
var storeResult = Store(key: key, value: value);
19+
StoreAssertPass(storeResult);
20+
21+
var getResult = _client.ExecuteGet(key);
22+
GetAssertPass(getResult, value);
23+
}
24+
25+
[Fact]
26+
public void When_Getting_Item_For_Invalid_Key_HasValue_Is_False_And_Result_Is_Not_Successful()
27+
{
28+
var key = GetUniqueKey("get");
29+
30+
var getResult = _client.ExecuteGet(key);
31+
Assert.True(getResult.StatusCode == (int)StatusCodeEnums.NotFound, "Invalid status code");
32+
GetAssertFail(getResult);
33+
}
34+
35+
[Fact]
36+
public void When_TryGetting_Existing_Item_Value_Is_Not_Null_And_Result_Is_Successful()
37+
{
38+
var key = GetUniqueKey("get");
39+
var value = GetRandomString();
40+
var storeResult = Store(key: key, value: value);
41+
StoreAssertPass(storeResult);
42+
43+
object temp;
44+
var getResult = _client.ExecuteTryGet(key, out temp);
45+
GetAssertPass(getResult, temp);
46+
}
47+
48+
[Fact]
49+
public void When_Generic_Getting_Existing_Item_Value_Is_Not_Null_And_Result_Is_Successful()
50+
{
51+
var key = GetUniqueKey("get");
52+
var value = GetRandomString();
53+
var storeResult = Store(key: key, value: value);
54+
StoreAssertPass(storeResult);
55+
56+
var getResult = _client.ExecuteGet<string>(key);
57+
Assert.True(getResult.Success, "Success was false");
58+
Assert.True(getResult.Cas > 0, "Cas value was 0");
5859
Assert.True((getResult.StatusCode ?? 0) == 0, "StatusCode was neither 0 nor null");
59-
Assert.Equal(value, getResult.Value);
60-
}
61-
62-
[Fact]
63-
public void When_Getting_Multiple_Keys_Result_Is_Successful()
64-
{
65-
var keys = GetUniqueKeys().Distinct();
66-
foreach (var key in keys)
67-
{
68-
Store(key: key, value: "Value for" + key);
69-
}
70-
71-
var dict = _client.ExecuteGet(keys);
72-
Assert.Equal(keys.Count(), dict.Keys.Count);
73-
74-
foreach (var key in dict.Keys)
75-
{
76-
Assert.True(dict[key].Success, "Get failed for key: " + key);
77-
}
78-
}
79-
80-
[Fact]
81-
public void When_Getting_Byte_Result_Is_Successful()
82-
{
83-
var key = GetUniqueKey("Get");
84-
const byte expectedValue = 1;
85-
Store(key: key, value: expectedValue);
86-
var getResult = _client.ExecuteGet(key);
87-
GetAssertPass(getResult, expectedValue);
88-
}
89-
90-
[Fact]
91-
public void When_Getting_SByte_Result_Is_Successful()
92-
{
93-
var key = GetUniqueKey("Get");
94-
const sbyte expectedValue = 1;
95-
Store(key: key, value: expectedValue);
96-
var getResult = _client.ExecuteGet(key);
97-
GetAssertPass(getResult, expectedValue);
98-
}
99-
}
60+
Assert.Equal(value, getResult.Value);
61+
}
62+
63+
[Fact]
64+
public void When_Getting_Multiple_Keys_Result_Is_Successful()
65+
{
66+
var keys = GetUniqueKeys().Distinct();
67+
foreach (var key in keys)
68+
{
69+
Store(key: key, value: "Value for" + key);
70+
}
71+
72+
var dict = _client.ExecuteGet(keys);
73+
Assert.Equal(keys.Count(), dict.Keys.Count);
74+
75+
foreach (var key in dict.Keys)
76+
{
77+
Assert.True(dict[key].Success, "Get failed for key: " + key);
78+
}
79+
}
80+
81+
[Fact]
82+
public void When_Getting_Byte_Result_Is_Successful()
83+
{
84+
var key = GetUniqueKey("Get");
85+
const byte expectedValue = 1;
86+
Store(key: key, value: expectedValue);
87+
var getResult = _client.ExecuteGet(key);
88+
GetAssertPass(getResult, expectedValue);
89+
}
90+
91+
[Fact]
92+
public void When_Getting_SByte_Result_Is_Successful()
93+
{
94+
var key = GetUniqueKey("Get");
95+
const sbyte expectedValue = 1;
96+
Store(key: key, value: expectedValue);
97+
var getResult = _client.ExecuteGet(key);
98+
GetAssertPass(getResult, expectedValue);
99+
}
100+
101+
[Fact]
102+
public async Task When_GetValueOrCreateAsync_Is_Successful()
103+
{
104+
var key = GetUniqueKey("Get");
105+
var expected = "hello word";
106+
var value = await _client.GetValueOrCreateAsync(key, 10, async () =>
107+
{
108+
return await Task.FromResult(expected);
109+
});
110+
Assert.Equal(expected, value);
111+
Assert.Equal(expected, await _client.GetValueAsync<string>(key));
112+
113+
key = GetUniqueKey("Get");
114+
await _client.GetValueOrCreateAsync(key, 10, async () =>
115+
{
116+
return await Task.FromResult<string>(null);
117+
});
118+
Assert.False((await _client.GetAsync<string>(key)).Success);
119+
}
120+
}
100121
}
101122

102123
#region [ License information ]

Enyim.Caching/IMemcachedClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public interface IMemcachedClient : IDisposable
1616

1717
Task<IGetOperationResult<T>> GetAsync<T>(string key);
1818
Task<T> GetValueAsync<T>(string key);
19+
Task<T> GetValueOrCreateAsync<T>(string key, int cacheSeconds, Func<Task<T>> factory);
1920
object Get(string key);
2021
T Get<T>(string key);
2122
IDictionary<string, T> Get<T>(IEnumerable<string> keys);

Enyim.Caching/MemcachedClient.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,22 @@ public async Task<T> GetValueAsync<T>(string key)
219219
return result.Success ? result.Value : default(T);
220220
}
221221

222+
public async Task<T> GetValueOrCreateAsync<T>(string key, int cacheSeconds, Func<Task<T>> factory)
223+
{
224+
var result = await GetAsync<T>(key);
225+
if(result.Success)
226+
{
227+
return result.Value;
228+
}
229+
230+
var value = await factory();
231+
if(value != null)
232+
{
233+
await AddAsync(key, value, cacheSeconds);
234+
}
235+
return value;
236+
}
237+
222238
/// <summary>
223239
/// Tries to get an item from the cache.
224240
/// </summary>

Enyim.Caching/NullMemcachedClient.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,5 +247,10 @@ public Task SetAsync(string key, object value, int cacheSeconds)
247247
{
248248
return Task.CompletedTask;
249249
}
250+
251+
public Task<T> GetValueOrCreateAsync<T>(string key, int cacheSeconds, Func<Task<T>> factory)
252+
{
253+
return Task.FromResult(default(T));
254+
}
250255
}
251256
}

0 commit comments

Comments
 (0)