Skip to content

Commit

Permalink
1. optimize Cache
Browse files Browse the repository at this point in the history
2. optimize Redis.Paramter.DatabaseId
3. add Redis.expiryInterval
  • Loading branch information
Ahoo-Wang committed Dec 5, 2018
1 parent 9bd86bb commit f42c66a
Show file tree
Hide file tree
Showing 18 changed files with 103 additions and 51 deletions.
11 changes: 6 additions & 5 deletions doc/Schemas/SmartSqlMap.xsd
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://SmartSql.net/schemas/SmartSqlMap.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://SmartSql.net/schemas/SmartSqlMap.xsd"
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://SmartSql.net/schemas/SmartSqlMap.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://SmartSql.net/schemas/SmartSqlMap.xsd"
xmlns:vs="http://schemas.microsoft.com/Visual-Studio-Intellisense" vs:friendlyname="SmartSqlMap Configuration Schema" vs:ishtmlschema="false" vs:iscasesensitive="true" vs:requireattributequotes="true" vs:defaultnamespacequalifier="" vs:defaultnsprefix="">

<xs:simpleType name="CSharpType">
Expand Down Expand Up @@ -38,7 +38,7 @@
<xs:enumeration value="Read"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Transaction">
<xs:simpleType name="Transaction">
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="Unspecified"/>
<xs:enumeration value="Chaos"/>
Expand Down Expand Up @@ -74,9 +74,10 @@
<xs:attribute name="Id" type="xs:string" use="required" />
<xs:attribute name="Type" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:restriction base="xs:string">
<xs:enumeration value="Lru"/>
<xs:enumeration value="Fifo"/>
<xs:enumeration value="SmartSql.Cache.Redis.RedisCacheProvider,SmartSql.Cache.Redis"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
Expand Down
48 changes: 28 additions & 20 deletions src/SmartSql.Cache.Redis/RedisCacheProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,80 +6,88 @@
using StackExchange.Redis;
using Newtonsoft.Json;
using SmartSql.Exceptions;
using System.Linq;
using SmartSql.Configuration;

namespace SmartSql.Cache.Redis
{
public class RedisCacheProvider : ICacheProvider
{
private String _connStr;
private ConnectionMultiplexer _redis;
private ConnectionMultiplexer _redis => RedisManager.Instance.GetRedis(_connStr);
private int _databaseId = 0;
private IDatabase CacheDB { get { return _redis.GetDatabase(_databaseId); } }
private String _prefix;

private TimeSpan? _expiryInterval;
public void Initialize(IDictionary properties)
{
_connStr = properties["ConnectionString"]?.ToString();
if (String.IsNullOrEmpty(_connStr))
{
throw new SmartSqlException("SmartSql.Cache.Redis.ConnectionString string can't empty.");
}
_prefix = properties["Cache.Id"]?.ToString();

String databaseIdStr = properties["DatabaseId"]?.ToString();
if (String.IsNullOrEmpty(databaseIdStr))
if (!String.IsNullOrEmpty(databaseIdStr))
{
throw new SmartSqlException("SmartSql.Cache.Redis.DatabaseId string can't empty.");
Int32.TryParse(databaseIdStr, out _databaseId);
}
else
var prefixStr = properties["Prefix"]?.ToString();
if (!String.IsNullOrEmpty(prefixStr))
{
if (!Int32.TryParse(databaseIdStr, out _databaseId))
{
throw new SmartSqlException("SmartSql.Cache.Redis.DatabaseId string is not int.");
}
_prefix = prefixStr;
}
_prefix = properties["Prefix"]?.ToString();
if (String.IsNullOrEmpty(_prefix))
if (properties["FlushInterval"] is FlushInterval flushInterval)
{
throw new SmartSqlException("SmartSql.Cache.Redis.Prefix string can't empty.");
_expiryInterval = flushInterval.Interval;
}
}

_redis = RedisManager.Instance.GetRedis(_connStr);
private string GetRedisCacheKey(CacheKey key)
{
return $"{_prefix}:{key.Key}";
}

public object this[CacheKey key, Type type]
{
get
{
string cacheStr = CacheDB.StringGet(key.Key);
string cacheStr = CacheDB.StringGet(GetRedisCacheKey(key));
if (String.IsNullOrEmpty(cacheStr)) { return null; }
return JsonConvert.DeserializeObject(cacheStr, type);
}
set
{
string cacheStr = JsonConvert.SerializeObject(value);
CacheDB.StringSet(key.Key, cacheStr);
CacheDB.StringSet(GetRedisCacheKey(key), cacheStr, _expiryInterval);
}
}

public void Flush()
{
var serverEndPoint = _redis.GetEndPoints()[0];
IServer servier = _redis.GetServer(serverEndPoint);
var keys = servier.Keys(_databaseId, pattern: $"{_prefix}*");
foreach (string key in keys)
var keys = servier.Keys(_databaseId, pattern: $"{_prefix}*").ToArray();
if (keys.Length > 0)
{
CacheDB.KeyDelete(key);
CacheDB.KeyDelete(keys.ToArray());
}
}

public bool Remove(CacheKey key)
{
return CacheDB.KeyDelete(key.Key);
return CacheDB.KeyDelete(GetRedisCacheKey(key));
}

public bool Contains(CacheKey key)
{
return CacheDB.KeyExists(key.Key);
return CacheDB.KeyExists(GetRedisCacheKey(key));
}

public void Dispose()
{
_redis.Dispose();
}
}
}
25 changes: 21 additions & 4 deletions src/SmartSql.Cache.Redis/RedisManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,35 @@ private RedisManager() { }

public ConnectionMultiplexer GetRedis(String connStr)
{
ConnectionMultiplexer redis;
if (_redises.ContainsKey(connStr))
{
return _redises[connStr];
redis = _redises[connStr];
if (redis.IsConnected)
{
return redis;
}
}
lock (this)
{
if (_redises.ContainsKey(connStr))
{
return _redises[connStr];
redis = _redises[connStr];
if (redis.IsConnected)
{
return redis;
}
}
redis = ConnectionMultiplexer.Connect(connStr);
if (_redises.ContainsKey(connStr))
{
_redises[connStr] = redis;
}
else
{
_redises.Add(connStr, redis);
}
var redis = ConnectionMultiplexer.Connect(connStr);
_redises.Add(connStr, redis);

return redis;
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/SmartSql.Cache.Redis/SmartSql.Cache.Redis.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<Description>Redis Cache For SmartSql</Description>
<Authors>Ahoo Wang</Authors>
<Company>Ahoo Wang</Company>
Expand All @@ -10,11 +10,12 @@
<RepositoryUrl>https://github.com/Ahoo-Wang/SmartSql</RepositoryUrl>
<PackageTags>SmartSql Dapper MyBatis ORM Redis Cache</PackageTags>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<Version>3.1.0</Version>
<Version>3.2.0</Version>
<PackageIconUrl>https://raw.githubusercontent.com/Ahoo-Wang/SmartSql/master/SmartSql.png</PackageIconUrl>
<PackageLicenseUrl>https://raw.githubusercontent.com/Ahoo-Wang/SmartSql/master/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>
1. fix the cache penetration problem with the cache value of null
1. optimize Paramter.DatabaseId
2. add expiryInterval
</PackageReleaseNotes>
</PropertyGroup>

Expand All @@ -28,7 +29,7 @@

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
<PackageReference Include="StackExchange.Redis" Version="1.2.1" />
<PackageReference Include="StackExchange.Redis" Version="2.0.519" />
</ItemGroup>

<ItemGroup>
Expand Down
13 changes: 10 additions & 3 deletions src/SmartSql.UTests/DyRepository/DyRepository_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,25 @@
using System.Threading.Tasks;
using Xunit;
using Microsoft.Extensions.Logging;
using SmartSql.Abstractions;

namespace SmartSql.UTests.DyRepository
{
public class DyRepository_Tests : TestBase
{
IEntityRepository _repository;
ISmartSqlMapper _sqlMapper;
public DyRepository_Tests()
{
string scope_template = "I{Scope}Repository";
var builder = new RepositoryBuilder(scope_template, null, LoggerFactory.CreateLogger<RepositoryBuilder>());
var factory = new RepositoryFactory(builder, LoggerFactory.CreateLogger<RepositoryFactory>());
var sqlMapper = MapperContainer.Instance.GetSqlMapper();
_repository = factory.CreateInstance<IEntityRepository>(sqlMapper);
_sqlMapper = MapperContainer.Instance.GetSqlMapper(new SmartSqlOptions
{
Alias = "DyRepository_Tests",
ConfigPath = Consts.DEFAULT_SMARTSQL_CONFIG_PATH
});
_repository = factory.CreateInstance<IEntityRepository>(_sqlMapper);
}

[Fact]
Expand Down Expand Up @@ -238,7 +245,7 @@ public async Task QueryAsync()

public void Dispose()
{
MapperContainer.Instance.Dispose();
_sqlMapper.Dispose();
}

public class QueryByPageRequest
Expand Down
4 changes: 2 additions & 2 deletions src/SmartSql.UTests/Maps/T_Entity.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
</Switch>
</IsNotEmpty>
<For Prepend="And" Key="Key" Open="T.FLong In (" Close=")" Property="Ids" Separator=",">
@Key
@Key,@Key
</For>
<For Prepend="And" Key="LikeKey" Open="(" Close=")" Property="FStrings" Separator="Or">
T.FString Like Concat(@LikeKey,'%')
Expand Down Expand Up @@ -218,7 +218,7 @@
(10)
</IsNull>-->
T.* From T_Entity T With(NoLock)
<Include RefId="QueryPs"/>
<Include RefId="QueryParams"/>
<Switch Prepend="Order By" Property="OrderBy">
<Default>
T.FLong Desc
Expand Down
1 change: 1 addition & 0 deletions src/SmartSql.UTests/SmartSql.UTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<ProjectReference Include="..\SmartSql.Batch.SqlServer\SmartSql.Batch.SqlServer.csproj" />
<ProjectReference Include="..\SmartSql.Batch.PostgreSql\SmartSql.Batch.PostgreSql.csproj" />
<ProjectReference Include="..\SmartSql.Batch\SmartSql.Batch.csproj" />
<ProjectReference Include="..\SmartSql.Cache.Redis\SmartSql.Cache.Redis.csproj" />
<ProjectReference Include="..\SmartSql.Extensions\SmartSql.Extensions.csproj" />
<ProjectReference Include="..\SmartSql.DapperDeserializer\SmartSql.DapperDeserializer.csproj" />
<ProjectReference Include="..\SmartSql.DIExtension\SmartSql.DIExtension.csproj" />
Expand Down
1 change: 1 addition & 0 deletions src/SmartSql.UTests/SmartSqlContext_Test.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Logging;
using SmartSql.Abstractions.Config;
using System;
using Xunit;

namespace SmartSql.UTests
Expand Down
2 changes: 1 addition & 1 deletion src/SmartSql.UTests/SmartSqlMapConfig.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<SmartSqlMapConfig xmlns="http://SmartSql.net/schemas/SmartSqlMapConfig.xsd">
<Settings IsWatchConfigFile="false" IgnoreParameterCase="false" ParameterPrefix="$" IsCacheEnabled="false"/>
<Settings IsWatchConfigFile="false" IgnoreParameterCase="false" ParameterPrefix="$" IsCacheEnabled="true"/>
<Database>
<!--ParameterPrefix:[SqlServer:@ | MySQL:? |Oracle::] -->
<DbProvider Name="SqlClientFactory" ParameterPrefix="@" Type="System.Data.SqlClient.SqlClientFactory,System.Data.SqlClient" />
Expand Down
6 changes: 5 additions & 1 deletion src/SmartSql.UTests/SmartSqlMapper_Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ public class SmartSqlMapper_Test : TestBase, IDisposable
ISmartSqlMapper _sqlMapper;
public SmartSqlMapper_Test()
{
_sqlMapper = MapperContainer.Instance.GetSqlMapper();
_sqlMapper = MapperContainer.Instance.GetSqlMapper(new SmartSqlOptions
{
Alias = "SmartSqlMapper_Test",
ConfigPath = Consts.DEFAULT_SMARTSQL_CONFIG_PATH
});
}

public void Dispose()
Expand Down
5 changes: 0 additions & 5 deletions src/SmartSql/Abstractions/Cache/CacheKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ namespace SmartSql.Abstractions.Cache
{
public class CacheKey
{
/// <summary>
/// 缓存前缀
/// </summary>
public String Prefix { get; set; } = "SmartSql-Cache";

public String Key { get; private set; }
public CacheKey(RequestContext context)
{
Expand Down
2 changes: 1 addition & 1 deletion src/SmartSql/Abstractions/Cache/ICacheProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace SmartSql.Abstractions.Cache
{
public interface ICacheProvider
public interface ICacheProvider : IDisposable
{
void Initialize(IDictionary properties);
object this[CacheKey key, Type type]
Expand Down
6 changes: 4 additions & 2 deletions src/SmartSql/Cache/CacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ private void FlushInterval()
catch (Exception ex)
{
_logger.LogError(new EventId(ex.HResult), ex, ex.Message);

}

}

private void FlushOnExecute(RequestContext requestContext)
Expand Down Expand Up @@ -144,6 +142,10 @@ private void UpdateCacheFlushTime(string cacheId, DateTime flushTime)
public void Dispose()
{
_timer.Dispose();
foreach (var cacheKV in _smartSqlContext.MappedCache)
{
cacheKV.Value.Provider.Dispose();
}
}

public bool TryGet<T>(RequestContext context, out T cachedResult)
Expand Down
3 changes: 3 additions & 0 deletions src/SmartSql/Cache/FifoCacheProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ public void Initialize(IDictionary properties)
}
}

public void Dispose()
{

}
}
}
4 changes: 4 additions & 0 deletions src/SmartSql/Cache/LruCacheProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,9 @@ public void Initialize(IDictionary properties)
}
}

public void Dispose()
{

}
}
}
5 changes: 5 additions & 0 deletions src/SmartSql/Cache/NoneCacheProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public bool Contains(CacheKey key)
return false;
}

public void Dispose()
{

}

public void Flush()
{

Expand Down
Loading

0 comments on commit f42c66a

Please sign in to comment.