mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Improved the Azure database cache provider.
This commit is contained in:

committed by
Sebastien Ros

parent
8020447191
commit
a690b9cc66
@@ -9,12 +9,13 @@ namespace Orchard.Azure.Services.Caching.Database {
|
|||||||
|
|
||||||
public class AzureCacheClient : ICache {
|
public class AzureCacheClient : ICache {
|
||||||
|
|
||||||
public AzureCacheClient(string cacheHostIdentifier, string cacheName, string region) {
|
public AzureCacheClient(string cacheHostIdentifier, string cacheName, string region, bool enableCompression, TimeSpan? expirationTime) {
|
||||||
|
|
||||||
var dataCacheFactoryConfiguration = new DataCacheFactoryConfiguration() {
|
var dataCacheFactoryConfiguration = new DataCacheFactoryConfiguration() {
|
||||||
AutoDiscoverProperty = new DataCacheAutoDiscoverProperty(true, cacheHostIdentifier),
|
AutoDiscoverProperty = new DataCacheAutoDiscoverProperty(true, cacheHostIdentifier),
|
||||||
MaxConnectionsToServer = 32,
|
MaxConnectionsToServer = 32,
|
||||||
UseLegacyProtocol = false
|
UseLegacyProtocol = false,
|
||||||
|
IsCompressionEnabled = enableCompression
|
||||||
};
|
};
|
||||||
|
|
||||||
var dataCacheFactory = new DataCacheFactory(dataCacheFactoryConfiguration);
|
var dataCacheFactory = new DataCacheFactory(dataCacheFactoryConfiguration);
|
||||||
@@ -29,6 +30,8 @@ namespace Orchard.Azure.Services.Caching.Database {
|
|||||||
// region strings yielding the same transformed region string.
|
// region strings yielding the same transformed region string.
|
||||||
_regionAlphaNumeric = new String(Array.FindAll(_region.ToCharArray(), c => Char.IsLetterOrDigit(c))) + _region.GetHashCode().ToString();
|
_regionAlphaNumeric = new String(Array.FindAll(_region.ToCharArray(), c => Char.IsLetterOrDigit(c))) + _region.GetHashCode().ToString();
|
||||||
|
|
||||||
|
_expirationTime = expirationTime;
|
||||||
|
|
||||||
if (_logger.IsDebugEnabled)
|
if (_logger.IsDebugEnabled)
|
||||||
_logger.DebugFormat("Creating cache with CacheName='{0}' and Region='{1}' (original Region='{2}').", cacheName, _regionAlphaNumeric, _region);
|
_logger.DebugFormat("Creating cache with CacheName='{0}' and Region='{1}' (original Region='{2}').", cacheName, _regionAlphaNumeric, _region);
|
||||||
|
|
||||||
@@ -39,17 +42,18 @@ namespace Orchard.Azure.Services.Caching.Database {
|
|||||||
|
|
||||||
_cache.CreateRegion(_regionAlphaNumeric);
|
_cache.CreateRegion(_regionAlphaNumeric);
|
||||||
|
|
||||||
_lockHandleDictionary = new ConcurrentDictionary<object, DataCacheLockHandle>();
|
//_lockHandleDictionary = new ConcurrentDictionary<object, DataCacheLockHandle>();
|
||||||
_lockTimeout = TimeSpan.FromSeconds(30);
|
//_lockTimeout = TimeSpan.FromSeconds(30);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const string _defaultRegion = "NHibernate";
|
private const string _defaultRegion = "NHibernate";
|
||||||
private readonly IInternalLogger _logger;
|
private readonly IInternalLogger _logger;
|
||||||
private readonly string _region;
|
private readonly string _region;
|
||||||
private readonly string _regionAlphaNumeric;
|
private readonly string _regionAlphaNumeric;
|
||||||
|
private readonly TimeSpan? _expirationTime;
|
||||||
private readonly DataCache _cache;
|
private readonly DataCache _cache;
|
||||||
private readonly ConcurrentDictionary<object, DataCacheLockHandle> _lockHandleDictionary;
|
//private readonly ConcurrentDictionary<object, DataCacheLockHandle> _lockHandleDictionary;
|
||||||
private readonly TimeSpan _lockTimeout;
|
//private readonly TimeSpan _lockTimeout;
|
||||||
|
|
||||||
#region ICache Members
|
#region ICache Members
|
||||||
|
|
||||||
@@ -72,7 +76,10 @@ namespace Orchard.Azure.Services.Caching.Database {
|
|||||||
if (_logger.IsDebugEnabled)
|
if (_logger.IsDebugEnabled)
|
||||||
_logger.DebugFormat("Put() invoked with key='{0}' and value='{1}' in region '{2}'.", key, value, _regionAlphaNumeric);
|
_logger.DebugFormat("Put() invoked with key='{0}' and value='{1}' in region '{2}'.", key, value, _regionAlphaNumeric);
|
||||||
|
|
||||||
_cache.Put(key.ToString(), value, _regionAlphaNumeric);
|
if (_expirationTime.HasValue)
|
||||||
|
_cache.Put(key.ToString(), value, _expirationTime.Value, _regionAlphaNumeric);
|
||||||
|
else
|
||||||
|
_cache.Put(key.ToString(), value, _regionAlphaNumeric);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove(object key) {
|
public void Remove(object key) {
|
||||||
@@ -112,44 +119,44 @@ namespace Orchard.Azure.Services.Caching.Database {
|
|||||||
|
|
||||||
// TODO: Try to understand how it's used, and make locking more robust.
|
// TODO: Try to understand how it's used, and make locking more robust.
|
||||||
public void Lock(object key) {
|
public void Lock(object key) {
|
||||||
if (key == null)
|
//if (key == null)
|
||||||
throw new ArgumentNullException("key", "The parameter 'key' must not be null.");
|
// throw new ArgumentNullException("key", "The parameter 'key' must not be null.");
|
||||||
|
|
||||||
if (_logger.IsDebugEnabled)
|
//if (_logger.IsDebugEnabled)
|
||||||
_logger.DebugFormat("Lock() invoked with key='{0}' in region '{1}'.", key, _regionAlphaNumeric);
|
// _logger.DebugFormat("Lock() invoked with key='{0}' in region '{1}'.", key, _regionAlphaNumeric);
|
||||||
|
|
||||||
try {
|
//try {
|
||||||
DataCacheLockHandle lockHandle = null;
|
// DataCacheLockHandle lockHandle = null;
|
||||||
_cache.GetAndLock(key.ToString(), _lockTimeout, out lockHandle, _regionAlphaNumeric);
|
// _cache.GetAndLock(key.ToString(), _lockTimeout, out lockHandle, _regionAlphaNumeric);
|
||||||
_lockHandleDictionary.TryAdd(key, lockHandle);
|
// _lockHandleDictionary.TryAdd(key, lockHandle);
|
||||||
}
|
//}
|
||||||
catch (Exception ex) {
|
//catch (Exception ex) {
|
||||||
if (_logger.IsErrorEnabled)
|
// if (_logger.IsErrorEnabled)
|
||||||
_logger.Error("Exception thrown while trying to lock object in cache.", ex);
|
// _logger.Error("Exception thrown while trying to lock object in cache.", ex);
|
||||||
|
|
||||||
throw;
|
// throw;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Try to understand how it's used, and make locking more robust.
|
// TODO: Try to understand how it's used, and make locking more robust.
|
||||||
public void Unlock(object key) {
|
public void Unlock(object key) {
|
||||||
if (key == null)
|
//if (key == null)
|
||||||
throw new ArgumentNullException("key", "The parameter 'key' must not be null.");
|
// throw new ArgumentNullException("key", "The parameter 'key' must not be null.");
|
||||||
|
|
||||||
if (_logger.IsDebugEnabled)
|
//if (_logger.IsDebugEnabled)
|
||||||
_logger.DebugFormat("Unlock() invoked with key='{0}' in region '{1}'.", key, _regionAlphaNumeric);
|
// _logger.DebugFormat("Unlock() invoked with key='{0}' in region '{1}'.", key, _regionAlphaNumeric);
|
||||||
|
|
||||||
try {
|
//try {
|
||||||
DataCacheLockHandle lockHandle = null;
|
// DataCacheLockHandle lockHandle = null;
|
||||||
if (_lockHandleDictionary.TryRemove(key, out lockHandle))
|
// if (_lockHandleDictionary.TryRemove(key, out lockHandle))
|
||||||
_cache.Unlock(key.ToString(), lockHandle, _regionAlphaNumeric);
|
// _cache.Unlock(key.ToString(), lockHandle, _regionAlphaNumeric);
|
||||||
}
|
//}
|
||||||
catch (Exception ex) {
|
//catch (Exception ex) {
|
||||||
if (_logger.IsErrorEnabled)
|
// if (_logger.IsErrorEnabled)
|
||||||
_logger.Error("Exception thrown while trying to unlock object in cache.", ex);
|
// _logger.Error("Exception thrown while trying to unlock object in cache.", ex);
|
||||||
|
|
||||||
throw;
|
// throw;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Try to understand what this is for and how it's used.
|
// TODO: Try to understand what this is for and how it's used.
|
||||||
@@ -163,7 +170,8 @@ namespace Orchard.Azure.Services.Caching.Database {
|
|||||||
// TODO: Try to understand what this is for and how it's used.
|
// TODO: Try to understand what this is for and how it's used.
|
||||||
public int Timeout {
|
public int Timeout {
|
||||||
get {
|
get {
|
||||||
return Timestamper.OneMs * (int)_lockTimeout.TotalMilliseconds;
|
//return Timestamper.OneMs * (int)_lockTimeout.TotalMilliseconds;
|
||||||
|
return Timestamper.OneMs * 60000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.WindowsAzure.ServiceRuntime;
|
using Microsoft.WindowsAzure.ServiceRuntime;
|
||||||
using NHibernate.Cache;
|
using NHibernate.Cache;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Orchard.Azure.Services.Caching.Database {
|
namespace Orchard.Azure.Services.Caching.Database {
|
||||||
|
|
||||||
@@ -9,7 +10,17 @@ namespace Orchard.Azure.Services.Caching.Database {
|
|||||||
#region ICacheProvider Members
|
#region ICacheProvider Members
|
||||||
|
|
||||||
public ICache BuildCache(string regionName, IDictionary<string, string> properties) {
|
public ICache BuildCache(string regionName, IDictionary<string, string> properties) {
|
||||||
return new AzureCacheClient(AzureCacheConfiguration.CacheHostIdentifier, AzureCacheConfiguration.CacheName, regionName);
|
bool enableCompression = false;
|
||||||
|
string enableCompressionString;
|
||||||
|
if (properties.TryGetValue("compression_enabled", out enableCompressionString))
|
||||||
|
enableCompression = Boolean.Parse(enableCompressionString);
|
||||||
|
|
||||||
|
TimeSpan? expiration = null;
|
||||||
|
string expirationString;
|
||||||
|
if (properties.TryGetValue("expiration", out expirationString) || properties.TryGetValue(global::NHibernate.Cfg.Environment.CacheDefaultExpiration, out expirationString))
|
||||||
|
expiration = TimeSpan.FromSeconds(Int32.Parse(expirationString));
|
||||||
|
|
||||||
|
return new AzureCacheClient(AzureCacheConfiguration.CacheHostIdentifier, AzureCacheConfiguration.CacheName, regionName, enableCompression, expiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long NextTimestamp() {
|
public long NextTimestamp() {
|
||||||
|
Reference in New Issue
Block a user