Skip to content

Commit

Permalink
Merge pull request #65 from dotnetcore/dev
Browse files Browse the repository at this point in the history
TrySet/TrySetAsync
  • Loading branch information
catcherwong authored Jan 5, 2019
2 parents 248aebd + 38697ce commit 8bd2948
Show file tree
Hide file tree
Showing 11 changed files with 316 additions and 13 deletions.
13 changes: 6 additions & 7 deletions build/releasenotes.props
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
<Project>
<PropertyGroup>
<EasyCachingCorePackageNotes>
1. Make IEasyCaching Obsolete.
2. Remove the class restrict
1. TrySet/TrySetAsync.
</EasyCachingCorePackageNotes>
<EasyCachingMemcachedPackageNotes>
1. Remove the class restrict
1. TrySet/TrySetAsync.
</EasyCachingMemcachedPackageNotes>
<EasyCachingRedisPackageNotes>
1. Remove the class restrict
1. TrySet/TrySetAsync.
</EasyCachingRedisPackageNotes>
<EasyCachingSQLitePackageNotes>
1. Remove the class restrict
1. TrySet/TrySetAsync.
</EasyCachingSQLitePackageNotes>
<EasyCachingInMemoryPackageNotes>
1. Remove the class restrict
1. TrySet/TrySetAsync.
</EasyCachingInMemoryPackageNotes>
<EasyCachingHybridPackageNotes>
1. Remove the class restrict
1. TrySet/TrySetAsync.
</EasyCachingHybridPackageNotes>
<EasyCachingAspectCorePackageNotes>
1. Remove Dependency of IEasyCaching.
Expand Down
12 changes: 6 additions & 6 deletions build/version.props
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project>
<PropertyGroup>
<EasyCachingCorePackageVersion>0.4.1</EasyCachingCorePackageVersion>
<EasyCachingMemcachedPackageVersion>0.4.1</EasyCachingMemcachedPackageVersion>
<EasyCachingRedisPackageVersion>0.4.1</EasyCachingRedisPackageVersion>
<EasyCachingSQLitePackageVersion>0.4.1</EasyCachingSQLitePackageVersion>
<EasyCachingInMemoryPackageVersion>0.4.1</EasyCachingInMemoryPackageVersion>
<EasyCachingHybridPackageVersion>0.3.0</EasyCachingHybridPackageVersion>
<EasyCachingCorePackageVersion>0.4.2</EasyCachingCorePackageVersion>
<EasyCachingMemcachedPackageVersion>0.4.2</EasyCachingMemcachedPackageVersion>
<EasyCachingRedisPackageVersion>0.4.2</EasyCachingRedisPackageVersion>
<EasyCachingSQLitePackageVersion>0.4.2</EasyCachingSQLitePackageVersion>
<EasyCachingInMemoryPackageVersion>0.4.2</EasyCachingInMemoryPackageVersion>
<EasyCachingHybridPackageVersion>0.4.2</EasyCachingHybridPackageVersion>
<EasyCachingAspectCorePackageVersion>0.3.2</EasyCachingAspectCorePackageVersion>
<EasyCachingCastlePackageVersion>0.3.2</EasyCachingCastlePackageVersion>
<EasyCachingResponseCachingPackageVersion>0.3.0</EasyCachingResponseCachingPackageVersion>
Expand Down
20 changes: 20 additions & 0 deletions src/EasyCaching.Core/IEasyCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,5 +237,25 @@ public interface IEasyCachingProvider
/// </summary>
/// <value>The get stats.</value>
CacheStats CacheStats { get; }

/// <summary>
/// Tries the set.
/// </summary>
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration);

/// <summary>
/// Tries the set async.
/// </summary>
/// <returns>The set async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration);
}
}
10 changes: 10 additions & 0 deletions src/EasyCaching.HybridCache/HybridCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -658,5 +658,15 @@ public async Task FlushAsync()

await Task.WhenAll(tasks);
}

public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
throw new NotImplementedException();
}

public Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
throw new NotImplementedException();
}
}
}
46 changes: 46 additions & 0 deletions src/EasyCaching.InMemory/DefaultInMemoryCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -710,5 +710,51 @@ private string BuildCacheKey(string prividerName, string cacheKey)
? cacheKey
: $"{prividerName}-{cacheKey}";
}

/// <summary>
/// Tries the set.
/// </summary>
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

if (_cacheKeys.Contains(BuildCacheKey(Name, cacheKey)))
{
return false;
}

Set(cacheKey, cacheValue, expiration);
return true;
}

/// <summary>
/// Tries the set async.
/// </summary>
/// <returns>The set async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public async Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

if (_cacheKeys.Contains(BuildCacheKey(Name, cacheKey)))
{
return false;
}

await SetAsync(cacheKey, cacheValue, expiration);
return true;
}
}
}
46 changes: 46 additions & 0 deletions src/EasyCaching.Memcached/DefaultMemcachedCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -641,5 +641,51 @@ public async Task FlushAsync()
await _memcachedClient.FlushAllAsync();
}

/// <summary>
/// Tries the set.
/// </summary>
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

if (MaxRdSecond > 0)
{
var addSec = new Random().Next(1, MaxRdSecond);
expiration.Add(new TimeSpan(0, 0, addSec));
}

return _memcachedClient.Store(Enyim.Caching.Memcached.StoreMode.Add, this.HandleCacheKey(cacheKey), cacheValue, expiration);
}

/// <summary>
/// Tries the set async.
/// </summary>
/// <returns>The set async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

if (MaxRdSecond > 0)
{
var addSec = new Random().Next(1, MaxRdSecond);
expiration.Add(new TimeSpan(0, 0, addSec));
}

return _memcachedClient.StoreAsync(Enyim.Caching.Memcached.StoreMode.Add, this.HandleCacheKey(cacheKey), cacheValue, expiration);
}

}
}
56 changes: 56 additions & 0 deletions src/EasyCaching.Redis/DefaultRedisCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -752,5 +752,61 @@ public async Task FlushAsync()

await Task.WhenAll(tasks);
}

/// <summary>
/// Tries the set.
/// </summary>
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

if (MaxRdSecond > 0)
{
var addSec = new Random().Next(1, MaxRdSecond);
expiration.Add(new TimeSpan(0, 0, addSec));
}

return _cache.StringSet(
cacheKey,
_serializer.Serialize(cacheValue),
expiration,
When.NotExists
);
}

/// <summary>
/// Tries the set async.
/// </summary>
/// <returns>The set async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

if (MaxRdSecond > 0)
{
var addSec = new Random().Next(1, MaxRdSecond);
expiration.Add(new TimeSpan(0, 0, addSec));
}

return _cache.StringSetAsync(
cacheKey,
_serializer.Serialize(cacheValue),
expiration,
When.NotExists
);
}
}
}
14 changes: 14 additions & 0 deletions src/EasyCaching.SQLite/ConstSQL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ INSERT INTO [easycaching]
,@cachevalue
,(select strftime('%s','now')) + @expiration);";

/// <summary>
/// The trysetsql.
/// </summary>
public const string TRYSETSQL = @"
INSERT INTO [easycaching]
([name]
,[cachekey]
,[cachevalue]
,[expiration])
SELECT @name,@cachekey,@cachevalue,(select strftime('%s','now') + @expiration)
WHERE NOT EXISTS (SELECT 1 FROM [easycaching] WHERE [cachekey] = @cachekey AND [name]=@name AND [expiration] > strftime('%s','now'));";



/// <summary>
/// The getsql.
/// </summary>
Expand Down
62 changes: 62 additions & 0 deletions src/EasyCaching.SQLite/DefaultSQLiteCachingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -678,5 +678,67 @@ public int GetCount(string prefix = "")
/// </summary>
/// <returns>The async.</returns>
public async Task FlushAsync() => await _cache.ExecuteAsync(ConstSQL.FLUSHSQL,new { name = _name });

/// <summary>
/// Tries the set.
/// </summary>
/// <returns><c>true</c>, if set was tryed, <c>false</c> otherwise.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public bool TrySet<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

if (MaxRdSecond > 0)
{
var addSec = new Random().Next(1, MaxRdSecond);
expiration.Add(new TimeSpan(0, 0, addSec));
}

var rows = _cache.Execute(ConstSQL.TRYSETSQL, new
{
cachekey = cacheKey,
name = _name,
cachevalue = Newtonsoft.Json.JsonConvert.SerializeObject(cacheValue),
expiration = expiration.Ticks / 10000000
});

return rows > 0;
}

/// <summary>
/// Tries the set async.
/// </summary>
/// <returns>The set async.</returns>
/// <param name="cacheKey">Cache key.</param>
/// <param name="cacheValue">Cache value.</param>
/// <param name="expiration">Expiration.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
public async Task<bool> TrySetAsync<T>(string cacheKey, T cacheValue, TimeSpan expiration)
{
ArgumentCheck.NotNullOrWhiteSpace(cacheKey, nameof(cacheKey));
ArgumentCheck.NotNull(cacheValue, nameof(cacheValue));
ArgumentCheck.NotNegativeOrZero(expiration, nameof(expiration));

if (MaxRdSecond > 0)
{
var addSec = new Random().Next(1, MaxRdSecond);
expiration.Add(new TimeSpan(0, 0, addSec));
}

var rows = await _cache.ExecuteAsync(ConstSQL.TRYSETSQL, new
{
cachekey = cacheKey,
name = _name,
cachevalue = Newtonsoft.Json.JsonConvert.SerializeObject(cacheValue),
expiration = expiration.Ticks / 10000000
});

return rows > 0;
}
}
}
37 changes: 37 additions & 0 deletions test/EasyCaching.UnitTests/CachingTests/BaseCachingProviderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,43 @@ protected virtual void Get_Count_With_Prefix_Should_Succeed()
}
#endregion

#region TrySet
[Fact]
protected virtual void TrySet_Value_And_Get_Cached_Value_Should_Succeed()
{
var cacheKey = Guid.NewGuid().ToString();
var cacheValue1 = "value1";
var cacheValue2 = "value2";

var first = _provider.TrySet(cacheKey, cacheValue1, _defaultTs);
var second = _provider.TrySet(cacheKey, cacheValue2, _defaultTs);

Assert.True(first);
Assert.False(second);

var val = _provider.Get<string>(cacheKey);
Assert.True(val.HasValue);
Assert.Equal(cacheValue1, val.Value);
}

[Fact]
protected virtual async Task TrySet_Value_And_Get_Cached_Value_Async_Should_Succeed()
{
var cacheKey = Guid.NewGuid().ToString();
var cacheValue1 = "value1";
var cacheValue2 = "value2";

var first = await _provider.TrySetAsync(cacheKey, cacheValue1, _defaultTs);
var second = await _provider.TrySetAsync(cacheKey, cacheValue2, _defaultTs);

Assert.True(first);
Assert.False(second);

var val = _provider.Get<string>(cacheKey);
Assert.True(val.HasValue);
Assert.Equal(cacheValue1, val.Value);
}
#endregion

#region common method
protected Dictionary<string, string> GetMultiDict(string prefix = "")
Expand Down
Loading

0 comments on commit 8bd2948

Please sign in to comment.