private Task InitializePersonTypeValueMaps(IdentityValueMaps entry, string personType, string context) { // Validate Person type if (!PersonEntitySpecification.IsPersonEntity(personType)) { throw new ArgumentException( string.Format( "Invalid person type '{0}'. Valid person types are: {1}", personType, "'" + string.Join("','", PersonEntitySpecification.ValidPersonTypes) + "'")); } // In web application scenarios, copy pertinent context from HttpContext to CallContext if (HttpContextStorageTransfer != null) { HttpContextStorageTransfer.TransferContext(); } var task = InitializePersonTypeValueMapsAsync(entry, personType, context); if (task.Status == TaskStatus.Created) { task.Start(); } return(task); }
private bool TryGetIdentityValueMaps(string personType, string context, out IdentityValueMaps identityValueMaps) { object personCacheAsObject; string cacheKey = GetPersonTypeIdentifiersCacheKey(personType, context); if (!_cacheProvider.TryGetCachedObject(cacheKey, out personCacheAsObject)) { // Make sure there is only one cache set being initialized at a time lock (_identityValueMapsLock) { // Make sure that the entry still doesn't exist yet if (!_cacheProvider.TryGetCachedObject(cacheKey, out personCacheAsObject)) { var newValueMaps = new IdentityValueMaps(); //Put the initialization task on the cached object so that we know the initialization status by cache entry key //Even if/when the cache provider storage changes context newValueMaps.InitializationTask = InitializePersonTypeValueMaps(newValueMaps, personType, context); //Initial Insert is for while async initialization is running. _cacheProvider.Insert(cacheKey, newValueMaps, DateTime.MaxValue, TimeSpan.FromMinutes(5)); _cacheProvider.TryGetCachedObject(cacheKey, out personCacheAsObject); } } } identityValueMaps = personCacheAsObject as IdentityValueMaps; if (identityValueMaps == null) { return(false); } if (_synchronousInitialization && (identityValueMaps.UniqueIdByUsi == null || identityValueMaps.UsiByUniqueId == null)) { // Wait for the initialization task to complete identityValueMaps.InitializationTask.WaitSafely(); //If initialization failed, return false. if (identityValueMaps.UniqueIdByUsi == null || identityValueMaps.UsiByUniqueId == null) { return(false); } // With initialization complete, try again (using a single recursive call) return(TryGetIdentityValueMaps(personType, context, out identityValueMaps)); } return(true); }
private async Task InitializePersonTypeValueMapsAsync(IdentityValueMaps entry, string personType, string context) { // Un-handled exceptions here will take down the ASP.NET process try { // Start building the data var uniqueIdByUsi = new ConcurrentDictionary <string, string>(); var usiByUniqueId = new ConcurrentDictionary <string, int>(); Stopwatch stopwatch = null; if (_logger.IsDebugEnabled) { stopwatch = new Stopwatch(); stopwatch.Start(); } foreach ( var valueMap in await _personIdentifiersProvider.GetAllPersonIdentifiers(personType)) { string key = GetUniqueIdByUsiCacheKey(personType, valueMap.Usi, context); uniqueIdByUsi.TryAdd(key, valueMap.UniqueId); string key2 = GetUsiByUniqueIdCacheKey(personType, valueMap.UniqueId, context); usiByUniqueId.TryAdd(key2, valueMap.Usi); } if (_logger.IsDebugEnabled) { stopwatch.Stop(); _logger.DebugFormat( "UniqueId/USI cache for {0} initialized {1:n0} entries in {2:n0} milliseconds.", personType, uniqueIdByUsi.Count, stopwatch.ElapsedMilliseconds); } entry.SetMaps(usiByUniqueId, uniqueIdByUsi); string cacheKey = GetPersonTypeIdentifiersCacheKey(personType, context); //Now that it's loaded extend the cache expiration. _cacheProvider.Insert(cacheKey, entry, GetAbsoluteExpiration(), _slidingExpiration); } catch (Exception ex) { _logger.ErrorFormat( "An exception occurred while trying to warm the PersonCache. UniqueIds will be retrieved individually.\r\n{0}", ex); } }