Skip to content

Commit 8bd2948

Browse files
authored
Merge pull request #65 from dotnetcore/dev
TrySet/TrySetAsync
2 parents 248aebd + 38697ce commit 8bd2948

File tree

11 files changed

+316
-13
lines changed

11 files changed

+316
-13
lines changed

build/releasenotes.props

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
<Project>
22
<PropertyGroup>
33
<EasyCachingCorePackageNotes>
4-
1. Make IEasyCaching Obsolete.
5-
2. Remove the class restrict
4+
1. TrySet/TrySetAsync.
65
</EasyCachingCorePackageNotes>
76
<EasyCachingMemcachedPackageNotes>
8-
1. Remove the class restrict
7+
1. TrySet/TrySetAsync.
98
</EasyCachingMemcachedPackageNotes>
109
<EasyCachingRedisPackageNotes>
11-
1. Remove the class restrict
10+
1. TrySet/TrySetAsync.
1211
</EasyCachingRedisPackageNotes>
1312
<EasyCachingSQLitePackageNotes>
14-
1. Remove the class restrict
13+
1. TrySet/TrySetAsync.
1514
</EasyCachingSQLitePackageNotes>
1615
<EasyCachingInMemoryPackageNotes>
17-
1. Remove the class restrict
16+
1. TrySet/TrySetAsync.
1817
</EasyCachingInMemoryPackageNotes>
1918
<EasyCachingHybridPackageNotes>
20-
1. Remove the class restrict
19+
1. TrySet/TrySetAsync.
2120
</EasyCachingHybridPackageNotes>
2221
<EasyCachingAspectCorePackageNotes>
2322
1. Remove Dependency of IEasyCaching.

build/version.props

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<Project>
22
<PropertyGroup>
3-
<EasyCachingCorePackageVersion>0.4.1</EasyCachingCorePackageVersion>
4-
<EasyCachingMemcachedPackageVersion>0.4.1</EasyCachingMemcachedPackageVersion>
5-
<EasyCachingRedisPackageVersion>0.4.1</EasyCachingRedisPackageVersion>
6-
<EasyCachingSQLitePackageVersion>0.4.1</EasyCachingSQLitePackageVersion>
7-
<EasyCachingInMemoryPackageVersion>0.4.1</EasyCachingInMemoryPackageVersion>
8-
<EasyCachingHybridPackageVersion>0.3.0</EasyCachingHybridPackageVersion>
3+
<EasyCachingCorePackageVersion>0.4.2</EasyCachingCorePackageVersion>
4+
<EasyCachingMemcachedPackageVersion>0.4.2</EasyCachingMemcachedPackageVersion>
5+
<EasyCachingRedisPackageVersion>0.4.2</EasyCachingRedisPackageVersion>
6+
<EasyCachingSQLitePackageVersion>0.4.2</EasyCachingSQLitePackageVersion>
7+
<EasyCachingInMemoryPackageVersion>0.4.2</EasyCachingInMemoryPackageVersion>
8+
<EasyCachingHybridPackageVersion>0.4.2</EasyCachingHybridPackageVersion>
99
<EasyCachingAspectCorePackageVersion>0.3.2</EasyCachingAspectCorePackageVersion>
1010
<EasyCachingCastlePackageVersion>0.3.2</EasyCachingCastlePackageVersion>
1111
<EasyCachingResponseCachingPackageVersion>0.3.0</EasyCachingResponseCachingPackageVersion>

src/EasyCaching.Core/IEasyCachingProvider.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,5 +237,25 @@ public interface IEasyCachingProvider
237237
/// </summary>
238238
/// <value>The get stats.</value>
239239
CacheStats CacheStats { get; }
240+
241+
/// <summary>
242+
/// Tries the set.
243+
/// </summary>
244+
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
245+
/// <param name="cacheKey">Cache key.</param>
246+
/// <param name="cacheValue">Cache value.</param>
247+
/// <param name="expiration">Expiration.</param>
248+
/// <typeparam name="T">The 1st type parameter.</typeparam>
249+
bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration);
250+
251+
/// <summary>
252+
/// Tries the set async.
253+
/// </summary>
254+
/// <returns>The set async.</returns>
255+
/// <param name="cacheKey">Cache key.</param>
256+
/// <param name="cacheValue">Cache value.</param>
257+
/// <param name="expiration">Expiration.</param>
258+
/// <typeparam name="T">The 1st type parameter.</typeparam>
259+
Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration);
240260
}
241261
}

src/EasyCaching.HybridCache/HybridCachingProvider.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,5 +658,15 @@ public async Task FlushAsync()
658658

659659
await Task.WhenAll(tasks);
660660
}
661+
662+
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
663+
{
664+
throw new NotImplementedException();
665+
}
666+
667+
public Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
668+
{
669+
throw new NotImplementedException();
670+
}
661671
}
662672
}

src/EasyCaching.InMemory/DefaultInMemoryCachingProvider.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,5 +710,51 @@ private string BuildCacheKey(string prividerName, string cacheKey)
710710
? cacheKey
711711
: $"{prividerName}-{cacheKey}";
712712
}
713+
714+
/// <summary>
715+
/// Tries the set.
716+
/// </summary>
717+
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
718+
/// <param name="cacheKey">Cache key.</param>
719+
/// <param name="cacheValue">Cache value.</param>
720+
/// <param name="expiration">Expiration.</param>
721+
/// <typeparam name="T">The 1st type parameter.</typeparam>
722+
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
723+
{
724+
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
725+
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
726+
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
727+
728+
if (_cacheKeys.Contains(BuildCacheKey(Name, cacheKey)))
729+
{
730+
return false;
731+
}
732+
733+
Set(cacheKey, cacheValue, expiration);
734+
return true;
735+
}
736+
737+
/// <summary>
738+
/// Tries the set async.
739+
/// </summary>
740+
/// <returns>The set async.</returns>
741+
/// <param name="cacheKey">Cache key.</param>
742+
/// <param name="cacheValue">Cache value.</param>
743+
/// <param name="expiration">Expiration.</param>
744+
/// <typeparam name="T">The 1st type parameter.</typeparam>
745+
public async Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
746+
{
747+
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
748+
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
749+
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
750+
751+
if (_cacheKeys.Contains(BuildCacheKey(Name, cacheKey)))
752+
{
753+
return false;
754+
}
755+
756+
await SetAsync(cacheKey, cacheValue, expiration);
757+
return true;
758+
}
713759
}
714760
}

src/EasyCaching.Memcached/DefaultMemcachedCachingProvider.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,5 +641,51 @@ public async Task FlushAsync()
641641
await _memcachedClient.FlushAllAsync();
642642
}
643643

644+
/// <summary>
645+
/// Tries the set.
646+
/// </summary>
647+
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
648+
/// <param name="cacheKey">Cache key.</param>
649+
/// <param name="cacheValue">Cache value.</param>
650+
/// <param name="expiration">Expiration.</param>
651+
/// <typeparam name="T">The 1st type parameter.</typeparam>
652+
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
653+
{
654+
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
655+
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
656+
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
657+
658+
if (MaxRdSecond > 0)
659+
{
660+
var addSec = new Random().Next(1, MaxRdSecond);
661+
expiration.Add(new TimeSpan(0, 0, addSec));
662+
}
663+
664+
return _memcachedClient.Store(Enyim.Caching.Memcached.StoreMode.Add, this.HandleCacheKey(cacheKey), cacheValue, expiration);
665+
}
666+
667+
/// <summary>
668+
/// Tries the set async.
669+
/// </summary>
670+
/// <returns>The set async.</returns>
671+
/// <param name="cacheKey">Cache key.</param>
672+
/// <param name="cacheValue">Cache value.</param>
673+
/// <param name="expiration">Expiration.</param>
674+
/// <typeparam name="T">The 1st type parameter.</typeparam>
675+
public Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
676+
{
677+
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
678+
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
679+
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
680+
681+
if (MaxRdSecond > 0)
682+
{
683+
var addSec = new Random().Next(1, MaxRdSecond);
684+
expiration.Add(new TimeSpan(0, 0, addSec));
685+
}
686+
687+
return _memcachedClient.StoreAsync(Enyim.Caching.Memcached.StoreMode.Add, this.HandleCacheKey(cacheKey), cacheValue, expiration);
688+
}
689+
644690
}
645691
}

src/EasyCaching.Redis/DefaultRedisCachingProvider.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,5 +752,61 @@ public async Task FlushAsync()
752752

753753
await Task.WhenAll(tasks);
754754
}
755+
756+
/// <summary>
757+
/// Tries the set.
758+
/// </summary>
759+
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
760+
/// <param name="cacheKey">Cache key.</param>
761+
/// <param name="cacheValue">Cache value.</param>
762+
/// <param name="expiration">Expiration.</param>
763+
/// <typeparam name="T">The 1st type parameter.</typeparam>
764+
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
765+
{
766+
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
767+
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
768+
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
769+
770+
if (MaxRdSecond > 0)
771+
{
772+
var addSec = new Random().Next(1, MaxRdSecond);
773+
expiration.Add(new TimeSpan(0, 0, addSec));
774+
}
775+
776+
return _cache.StringSet(
777+
cacheKey,
778+
_serializer.Serialize(cacheValue),
779+
expiration,
780+
When.NotExists
781+
);
782+
}
783+
784+
/// <summary>
785+
/// Tries the set async.
786+
/// </summary>
787+
/// <returns>The set async.</returns>
788+
/// <param name="cacheKey">Cache key.</param>
789+
/// <param name="cacheValue">Cache value.</param>
790+
/// <param name="expiration">Expiration.</param>
791+
/// <typeparam name="T">The 1st type parameter.</typeparam>
792+
public Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
793+
{
794+
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
795+
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
796+
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
797+
798+
if (MaxRdSecond > 0)
799+
{
800+
var addSec = new Random().Next(1, MaxRdSecond);
801+
expiration.Add(new TimeSpan(0, 0, addSec));
802+
}
803+
804+
return _cache.StringSetAsync(
805+
cacheKey,
806+
_serializer.Serialize(cacheValue),
807+
expiration,
808+
When.NotExists
809+
);
810+
}
755811
}
756812
}

src/EasyCaching.SQLite/ConstSQL.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,20 @@ INSERT INTO [easycaching]
2121
,@cachevalue
2222
,(select strftime('%s','now')) + @expiration);";
2323

24+
/// <summary>
25+
/// The trysetsql.
26+
/// </summary>
27+
public const string TRYSETSQL = @"
28+
INSERT INTO [easycaching]
29+
([name]
30+
,[cachekey]
31+
,[cachevalue]
32+
,[expiration])
33+
SELECT @name,@cachekey,@cachevalue,(select strftime('%s','now') + @expiration)
34+
WHERE NOT EXISTS (SELECT 1 FROM [easycaching] WHERE [cachekey] = @cachekey AND [name]=@name AND [expiration] > strftime('%s','now'));";
35+
36+
37+
2438
/// <summary>
2539
/// The getsql.
2640
/// </summary>

src/EasyCaching.SQLite/DefaultSQLiteCachingProvider.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,5 +678,67 @@ public int GetCount(string prefix = "")
678678
/// </summary>
679679
/// <returns>The async.</returns>
680680
public async Task FlushAsync() => await _cache.ExecuteAsync(ConstSQL.FLUSHSQL,new { name = _name });
681+
682+
/// <summary>
683+
/// Tries the set.
684+
/// </summary>
685+
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
686+
/// <param name="cacheKey">Cache key.</param>
687+
/// <param name="cacheValue">Cache value.</param>
688+
/// <param name="expiration">Expiration.</param>
689+
/// <typeparam name="T">The 1st type parameter.</typeparam>
690+
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
691+
{
692+
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
693+
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
694+
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
695+
696+
if (MaxRdSecond > 0)
697+
{
698+
var addSec = new Random().Next(1, MaxRdSecond);
699+
expiration.Add(new TimeSpan(0, 0, addSec));
700+
}
701+
702+
var rows = _cache.Execute(ConstSQL.TRYSETSQL, new
703+
{
704+
cachekey = cacheKey,
705+
name = _name,
706+
cachevalue = Newtonsoft.Json.JsonConvert.SerializeObject(cacheValue),
707+
expiration = expiration.Ticks / 10000000
708+
});
709+
710+
return rows > 0;
711+
}
712+
713+
/// <summary>
714+
/// Tries the set async.
715+
/// </summary>
716+
/// <returns>The set async.</returns>
717+
/// <param name="cacheKey">Cache key.</param>
718+
/// <param name="cacheValue">Cache value.</param>
719+
/// <param name="expiration">Expiration.</param>
720+
/// <typeparam name="T">The 1st type parameter.</typeparam>
721+
public async Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
722+
{
723+
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
724+
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
725+
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));
726+
727+
if (MaxRdSecond > 0)
728+
{
729+
var addSec = new Random().Next(1, MaxRdSecond);
730+
expiration.Add(new TimeSpan(0, 0, addSec));
731+
}
732+
733+
var rows = await _cache.ExecuteAsync(ConstSQL.TRYSETSQL, new
734+
{
735+
cachekey = cacheKey,
736+
name = _name,
737+
cachevalue = Newtonsoft.Json.JsonConvert.SerializeObject(cacheValue),
738+
expiration = expiration.Ticks / 10000000
739+
});
740+
741+
return rows > 0;
742+
}
681743
}
682744
}

test/EasyCaching.UnitTests/CachingTests/BaseCachingProviderTest.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,43 @@ protected virtual void Get_Count_With_Prefix_Should_Succeed()
10361036
}
10371037
#endregion
10381038

1039+
#region TrySet
1040+
[Fact]
1041+
protected virtual void TrySet_Value_And_Get_Cached_Value_Should_Succeed()
1042+
{
1043+
var cacheKey = Guid.NewGuid().ToString();
1044+
var cacheValue1 = "value1";
1045+
var cacheValue2 = "value2";
1046+
1047+
var first = _provider.TrySet(cacheKey, cacheValue1, _defaultTs);
1048+
var second = _provider.TrySet(cacheKey, cacheValue2, _defaultTs);
1049+
1050+
Assert.True(first);
1051+
Assert.False(second);
1052+
1053+
var val = _provider.Get<string>(cacheKey);
1054+
Assert.True(val.HasValue);
1055+
Assert.Equal(cacheValue1, val.Value);
1056+
}
1057+
1058+
[Fact]
1059+
protected virtual async Task TrySet_Value_And_Get_Cached_Value_Async_Should_Succeed()
1060+
{
1061+
var cacheKey = Guid.NewGuid().ToString();
1062+
var cacheValue1 = "value1";
1063+
var cacheValue2 = "value2";
1064+
1065+
var first = await _provider.TrySetAsync(cacheKey, cacheValue1, _defaultTs);
1066+
var second = await _provider.TrySetAsync(cacheKey, cacheValue2, _defaultTs);
1067+
1068+
Assert.True(first);
1069+
Assert.False(second);
1070+
1071+
var val = _provider.Get<string>(cacheKey);
1072+
Assert.True(val.HasValue);
1073+
Assert.Equal(cacheValue1, val.Value);
1074+
}
1075+
#endregion
10391076

10401077
#region common method
10411078
protected Dictionary<string, string> GetMultiDict(string prefix = "")

0 commit comments

Comments
 (0)