/// <summary> /// Add or update a mapping in cache. /// </summary> /// <param name="sm">Storage mapping object.</param> /// <param name="policy">Policy to use for preexisting cache entries during update.</param> internal override void AddOrUpdate(IStoreMapping sm, CacheStoreMappingUpdatePolicy policy) { // Make key out of mapping key. ShardKey key = ShardKey.FromRawValue(this.KeyType, sm.MinValue); CacheMapping cm; // We need to update TTL and update entry if: // a) We are in update TTL mode // b) Mapping exists and same as the one we already have // c) Entry is beyond the TTL limit if (policy == CacheStoreMappingUpdatePolicy.UpdateTimeToLive && _mappingsByKey.TryGetValue(key, out cm) && cm.Mapping.Id == sm.Id /*&& * TimerUtils.ElapsedMillisecondsSince(cm.CreationTime) >= cm.TimeToLiveMilliseconds */) { cm = new CacheMapping(sm, CacheMapper.CalculateNewTimeToLiveMilliseconds(cm)); } else { cm = new CacheMapping(sm); } // Remove existing entry. this.Remove(sm); // Add the entry to lookup table by Key. _mappingsByKey.Add(key, cm); }
/// <summary> /// Invoked for refreshing mapping in cache from store. /// </summary> /// <param name="mapping">Storage representation of mapping.</param> /// <param name="policy">Policy to use for preexisting cache entries during update.</param> public virtual void AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) { using (ReadLockScope rls = _cacheRoot.GetReadLockScope(false)) { CacheShardMap csm = _cacheRoot.LookupById(mapping.ShardMapId); if (csm != null) { using (WriteLockScope wlscsm = csm.GetWriteLockScope()) { csm.Mapper.AddOrUpdate(mapping, policy); /* * // Update perf counters for add or update operation and mappings count. * csm.IncrementPerformanceCounter(PerformanceCounterName.MappingsAddOrUpdatePerSec); * csm.SetPerformanceCounter(PerformanceCounterName.MappingsCount, csm.Mapper.GetMappingsCount()); */ Tracer.TraceVerbose( TraceSourceConstants.ComponentNames.ShardMapManager, "OnAddOrUpdateMapping", "Cache Add/Update mapping complete. Mapping Id: {0}", mapping.Id); } } } }
/// <summary> /// Invoked for refreshing mapping in cache from store. /// </summary> /// <param name="mapping">Storage representation of mapping.</param> /// <param name="policy">Policy to use for preexisting cache entries during update.</param> public virtual void AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) { using (ReadLockScope rls = _cacheRoot.GetReadLockScope(false)) { CacheShardMap csm = _cacheRoot.LookupById(mapping.ShardMapId); if (csm != null) { using (WriteLockScope wlscsm = csm.GetWriteLockScope()) { csm.Mapper.AddOrUpdate(mapping, policy); // Update perf counters for add or update operation and mappings count. csm.IncrementPerformanceCounter(PerformanceCounterName.MappingsAddOrUpdatePerSec); csm.SetPerformanceCounter(PerformanceCounterName.MappingsCount, csm.Mapper.GetMappingsCount()); Tracer.TraceVerbose( TraceSourceConstants.ComponentNames.ShardMapManager, "OnAddOrUpdateMapping", "Cache Add/Update mapping complete. Mapping Id: {0}", mapping.Id); } } } }
/// <summary> /// Add or update a mapping in cache. /// </summary> /// <param name="sm">Storage mapping object.</param> /// <param name="policy">Policy to use for preexisting cache entries during update.</param> internal override void AddOrUpdate(IStoreMapping sm, CacheStoreMappingUpdatePolicy policy) { ShardKey min = ShardKey.FromRawValue(this.KeyType, sm.MinValue); // Make range out of mapping key ranges. ShardRange range = new ShardRange( min, ShardKey.FromRawValue(this.KeyType, sm.MaxValue)); CacheMapping cm; ICacheStoreMapping csm; IStoreMapping smDummy; // We need to update TTL and update entry if: // a) We are in update TTL mode // b) Mapping exists and same as the one we already have // c) Entry is beyond the TTL limit if (policy == CacheStoreMappingUpdatePolicy.UpdateTimeToLive && (csm = this.LookupByKey(min, out smDummy)) != null && csm.Mapping.Id == sm.Id /*&& TimerUtils.ElapsedMillisecondsSince(csm.CreationTime) >= csm.TimeToLiveMilliseconds */) { cm = new CacheMapping(sm, CacheMapper.CalculateNewTimeToLiveMilliseconds(csm)); } else { cm = new CacheMapping(sm); } this.Remove(sm); // Add the entry to lookup table by Range. _mappingsByRange.Add(range, cm); }
/// <summary> /// Add or update a mapping in cache. /// </summary> /// <param name="sm">Storage mapping object.</param> /// <param name="policy">Policy to use for preexisting cache entries during update.</param> internal override void AddOrUpdate(IStoreMapping sm, CacheStoreMappingUpdatePolicy policy) { // Make key out of mapping key. ShardKey key = ShardKey.FromRawValue(this.KeyType, sm.MinValue); CacheMapping cm; // We need to update TTL and update entry if: // a) We are in update TTL mode // b) Mapping exists and same as the one we already have // c) Entry is beyond the TTL limit if (policy == CacheStoreMappingUpdatePolicy.UpdateTimeToLive && _mappingsByKey.TryGetValue(key, out cm) && cm.Mapping.Id == sm.Id /*&& TimerUtils.ElapsedMillisecondsSince(cm.CreationTime) >= cm.TimeToLiveMilliseconds */) { cm = new CacheMapping(sm, CacheMapper.CalculateNewTimeToLiveMilliseconds(cm)); } else { cm = new CacheMapping(sm); } // Remove existing entry. this.Remove(sm); // Add the entry to lookup table by Key. _mappingsByKey.Add(key, cm); }
/// <summary> /// Add or update a mapping in cache. /// </summary> /// <param name="sm">Storage mapping object.</param> /// <param name="policy">Policy to use for preexisting cache entries during update.</param> internal override void AddOrUpdate(IStoreMapping sm, CacheStoreMappingUpdatePolicy policy) { ShardKey min = ShardKey.FromRawValue(this.KeyType, sm.MinValue); // Make range out of mapping key ranges. ShardRange range = new ShardRange( min, ShardKey.FromRawValue(this.KeyType, sm.MaxValue)); CacheMapping cm; ICacheStoreMapping csm; IStoreMapping smDummy; // We need to update TTL and update entry if: // a) We are in update TTL mode // b) Mapping exists and same as the one we already have // c) Entry is beyond the TTL limit if (policy == CacheStoreMappingUpdatePolicy.UpdateTimeToLive && (csm = this.LookupByKey(min, out smDummy)) != null && csm.Mapping.Id == sm.Id /*&& * TimerUtils.ElapsedMillisecondsSince(csm.CreationTime) >= csm.TimeToLiveMilliseconds */) { cm = new CacheMapping(sm, CacheMapper.CalculateNewTimeToLiveMilliseconds(csm)); } else { cm = new CacheMapping(sm); } this.Remove(sm); // Add the entry to lookup table by Range. _mappingsByRange.Add(range, cm); }
/// <summary> /// Asynchronously finds the mapping in store for OpenConnectionForKey operation. /// </summary> /// <param name="sk">Key to find.</param> /// <param name="policy">Cache update policy.</param> /// <param name="errorCategory">Error category.</param> /// <returns>Task with the Mapping corresponding to the given key if found as the result.</returns> private async Task <IStoreMapping> LookupMappingForOpenConnectionForKeyAsync( ShardKey sk, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory) { IStoreResults gsmResult; Stopwatch stopwatch = Stopwatch.StartNew(); using (IStoreOperationGlobal op = this.Manager.StoreOperationFactory.CreateFindMappingByKeyGlobalOperation( this.Manager, "Lookup", this.ShardMap.StoreShardMap, sk, policy, errorCategory, true, false)) { gsmResult = await op.DoAsync().ConfigureAwait(false); } stopwatch.Stop(); Tracer.TraceVerbose( TraceSourceConstants.ComponentNames.BaseShardMapper, "LookupMappingForOpenConnectionForKeyAsync", "Lookup key from GSM complete; Key type : {0}; Result: {1}; Duration: {2}", sk.DataType, gsmResult.Result, stopwatch.Elapsed); // If we could not locate the mapping, we throw. if (gsmResult.Result == StoreResult.MappingNotFoundForKey) { throw new ShardManagementException( errorCategory, ShardManagementErrorCode.MappingNotFoundForKey, Errors._Store_ShardMapper_MappingNotFoundForKeyGlobal, this.ShardMap.Name, StoreOperationRequestBuilder.SpFindShardMappingByKeyGlobal, "LookupMappingForOpenConnectionForKeyAsync"); } else { return(gsmResult.StoreMappings.Single()); } }
/// <summary> /// Sets the stub of CacheStore.AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) /// </summary> public override void AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) { Action <IStoreMapping, CacheStoreMappingUpdatePolicy> action1 = this.AddOrUpdateMappingIStoreMappingCacheStoreMappingUpdatePolicy; if (action1 != null) { action1(mapping, policy); } else if (this.___callBase) { base.AddOrUpdateMapping(mapping, policy); } else { this.InstanceBehavior.VoidResult <StubCacheStore>(this, "AddOrUpdateMapping"); } }
/// <summary> /// Constructs request for obtaining mapping from GSM based on given key. /// </summary> /// <param name="shardMapManager">Shard map manager.</param> /// <param name="operationName">Operation being executed.</param> /// <param name="shardMap">Local shard map.</param> /// <param name="key">Key for lookup operation.</param> /// <param name="policy">Policy for cache update.</param> /// <param name="errorCategory">Error category.</param> /// <param name="cacheResults">Whether to cache the results of the operation.</param> /// <param name="ignoreFailure">Ignore shard map not found error.</param> protected internal FindMappingByKeyGlobalOperation( ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure) : base(shardMapManager.Credentials, shardMapManager.RetryPolicy, operationName) { _manager = shardMapManager; _shardMap = shardMap; _key = key; _policy = policy; _errorCategory = errorCategory; _cacheResults = cacheResults; _ignoreFailure = ignoreFailure; }
/// <summary> /// Constructs request for obtaining mapping from GSM based on given key. /// </summary> /// <param name="shardMapManager">Shard map manager.</param> /// <param name="operationName">Operation being executed.</param> /// <param name="shardMap">Local shard map.</param> /// <param name="key">Key for lookup operation.</param> /// <param name="policy">Policy for cache update.</param> /// <param name="errorCategory">Error category.</param> /// <param name="cacheResults">Whether to cache the results of the operation.</param> /// <param name="ignoreFailure">Ignore shard map not found error.</param> /// <returns>The store operation.</returns> public virtual IStoreOperationGlobal CreateFindMappingByKeyGlobalOperation( ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure) { return(new FindMappingByKeyGlobalOperation( shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure)); }
/// <summary> /// Invoked for refreshing mapping in cache from store. /// </summary> /// <param name="mapping">Storage representation of mapping.</param> /// <param name="policy">Policy to use for preexisting cache entries during update.</param> public virtual void AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) { using (ReadLockScope rls = _cacheRoot.GetReadLockScope(false)) { CacheShardMap csm = _cacheRoot.LookupById(mapping.ShardMapId); if (csm != null) { using (WriteLockScope wlscsm = csm.GetWriteLockScope()) { csm.Mapper.AddOrUpdate(mapping, policy); Tracer.TraceVerbose( TraceSourceConstants.ComponentNames.ShardMapManager, "OnAddOrUpdateMapping", "Cache Add/Update mapping complete. Mapping Id: {0}", mapping.Id); } } } }
public virtual void AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) { this.inner.AddOrUpdateMapping(mapping, policy); }
public override void AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) { this.AddMappingCount++; base.AddOrUpdateMapping(mapping, policy); }
/// <summary> /// Constructs request for obtaining mapping from GSM based on given key. /// </summary> /// <param name="shardMapManager">Shard map manager.</param> /// <param name="operationName">Operation being executed.</param> /// <param name="shardMap">Local shard map.</param> /// <param name="key">Key for lookup operation.</param> /// <param name="policy">Policy for cache update.</param> /// <param name="errorCategory">Error category.</param> /// <param name="cacheResults">Whether to cache the results of the operation.</param> /// <param name="ignoreFailure">Ignore shard map not found error.</param> /// <returns>The store operation.</returns> public virtual IStoreOperationGlobal CreateFindMappingByKeyGlobalOperation( ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure) { return new FindMappingByKeyGlobalOperation( shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure); }
/// <summary> /// Sets the stub of StoreOperationFactory.CreateFindMappingByKeyGlobalOperation(ShardMapManager shardMapManager, String operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, Boolean cacheResults, Boolean ignoreFailure) /// </summary> public override IStoreOperationGlobal CreateFindMappingByKeyGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure) { Func<ShardMapManager, string, IStoreShardMap, ShardKey, CacheStoreMappingUpdatePolicy, ShardManagementErrorCategory, bool, bool, IStoreOperationGlobal> func1 = this.CreateFindMappingByKeyGlobalOperationShardMapManagerStringIStoreShardMapShardKeyCacheStoreMappingUpdatePolicyShardManagementErrorCategoryBooleanBoolean; if (func1 != null) return func1(shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure); if (this.___callBase) return base.CreateFindMappingByKeyGlobalOperation(shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure); return this.InstanceBehavior.Result<StubStoreOperationFactory, IStoreOperationGlobal>(this, "CreateFindMappingByKeyGlobalOperation"); }
/// <summary> /// Add or update a mapping in cache. /// </summary> /// <param name="sm">Storage mapping object.</param> /// <param name="policy">Policy to use for preexisting cache entries during update.</param> internal abstract void AddOrUpdate(IStoreMapping sm, CacheStoreMappingUpdatePolicy policy);
/// <summary> /// Given a key value, asynchronously obtains a SqlConnection to the shard in the mapping /// that contains the key value. /// </summary> /// <typeparam name="TMapping">Mapping type.</typeparam> /// <typeparam name="TKey">Key type.</typeparam> /// <param name="key">Input key value.</param> /// <param name="constructMapping">Delegate to construct a mapping object.</param> /// <param name="errorCategory">Error category.</param> /// <param name="connectionString"> /// Connection string with credential information, the DataSource and Database are /// obtained from the results of the lookup operation for key. /// </param> /// <param name="secureCredential">Secure SQL Credential.</param> /// <param name="options">Options for validation operations to perform on opened connection.</param> /// <returns>A task encapsulating an opened SqlConnection as the result.</returns> protected async Task <SqlConnection> OpenConnectionForKeyAsync <TMapping, TKey>( TKey key, Func <ShardMapManager, ShardMap, IStoreMapping, TMapping> constructMapping, ShardManagementErrorCategory errorCategory, string connectionString, SqlCredential secureCredential, ConnectionOptions options = ConnectionOptions.Validate) where TMapping : class, IShardProvider { ShardKey sk = new ShardKey(ShardKey.ShardKeyTypeFromType(typeof(TKey)), key); // Try to find the mapping within the cache. ICacheStoreMapping csm = this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk); IStoreMapping sm; if (csm != null) { sm = csm.Mapping; } else { sm = await this.LookupMappingForOpenConnectionForKeyAsync( sk, CacheStoreMappingUpdatePolicy.OverwriteExisting, errorCategory).ConfigureAwait(false); } SqlConnection result; bool lookupMappingOnEx = false; CacheStoreMappingUpdatePolicy cacheUpdatePolicyOnEx = CacheStoreMappingUpdatePolicy.OverwriteExisting; try { // Initially attempt to connect based on lookup results from either cache or GSM. result = await this.ShardMap.OpenConnectionAsync( constructMapping(this.Manager, this.ShardMap, sm), connectionString, secureCredential, options).ConfigureAwait(false); csm.ResetTimeToLiveIfNecessary(); return(result); } catch (ShardManagementException smme) { // If we hit a validation failure due to stale version of mapping, we will perform one more attempt. if (((options & ConnectionOptions.Validate) == ConnectionOptions.Validate) && smme.ErrorCategory == ShardManagementErrorCategory.Validation && smme.ErrorCode == ShardManagementErrorCode.MappingDoesNotExist) { // Assumption here is that this time the attempt should succeed since the cache entry // has already been either evicted, or updated based on latest data from the server. lookupMappingOnEx = true; cacheUpdatePolicyOnEx = CacheStoreMappingUpdatePolicy.OverwriteExisting; } else { // The error was not due to validation but something else e.g. // 1) Shard map does not exist // 2) Mapping could not be found. throw; } } catch (SqlException) { // We failed to connect. If we were trying to connect from an entry in cache and mapping expired in cache. if (csm != null && csm.HasTimeToLiveExpired()) { using (IdLock _idLock = new IdLock(csm.Mapping.StoreShard.Id)) { // Similar to DCL pattern, we need to refresh the mapping again to see if we still need to go to the store // to lookup the mapping after acquiring the shard lock. It might be the case that a fresh version has already // been obtained by some other thread. csm = this.Manager.Cache.LookupMappingByKey(this.ShardMap.StoreShardMap, sk); // Only go to store if the mapping is stale even after refresh. if (csm == null || csm.HasTimeToLiveExpired()) { // Refresh the mapping in cache. And try to open the connection after refresh. lookupMappingOnEx = true; cacheUpdatePolicyOnEx = CacheStoreMappingUpdatePolicy.UpdateTimeToLive; } else { sm = csm.Mapping; } } } else { // Either: // 1) The mapping is still within the TTL. No refresh. // 2) Mapping was not in cache, we originally did a lookup for mapping in GSM and even then could not connect. throw; } } if (lookupMappingOnEx) { sm = await this.LookupMappingForOpenConnectionForKeyAsync( sk, cacheUpdatePolicyOnEx, errorCategory).ConfigureAwait(false); } // One last attempt to open the connection after a cache refresh result = await this.ShardMap.OpenConnectionAsync( constructMapping(this.Manager, this.ShardMap, sm), connectionString, secureCredential, options).ConfigureAwait(false); // Reset TTL on successful connection. csm.ResetTimeToLiveIfNecessary(); return(result); }
/// <summary> /// Sets the stub of CacheStore.AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) /// </summary> public override void AddOrUpdateMapping(IStoreMapping mapping, CacheStoreMappingUpdatePolicy policy) { Action<IStoreMapping, CacheStoreMappingUpdatePolicy> action1 = this.AddOrUpdateMappingIStoreMappingCacheStoreMappingUpdatePolicy; if (action1 != null) action1(mapping, policy); else if (this.___callBase) base.AddOrUpdateMapping(mapping, policy); else this.InstanceBehavior.VoidResult<StubCacheStore>(this, "AddOrUpdateMapping"); }
/// <summary> /// Initializes a new instance /// </summary> public StubFindMappingByKeyGlobalOperation(ShardMapManager shardMapManager, string operationName, IStoreShardMap shardMap, ShardKey key, CacheStoreMappingUpdatePolicy policy, ShardManagementErrorCategory errorCategory, bool cacheResults, bool ignoreFailure) : base(shardMapManager, operationName, shardMap, key, policy, errorCategory, cacheResults, ignoreFailure) { this.InitializeStub(); }