// Update the local cache with current regulations from the database for a specific customer public void UpdateMemAndXmlCacheForCustomerFromDB(int customerID, bool forceUpdateIfCacheNotExpiredYet) { // Get the current cache expiration for this customer DateTime _cacheExpireTime = GetCacheExpirationForCustomer(customerID); // Only update the cache if it is expired, or we have been explicitly told to do so if ((DateTime.UtcNow >= _cacheExpireTime) || (forceUpdateIfCacheNotExpiredYet)) { // Protect this section with our ReadWriterLockAlt that handles concurrency issues for us using (_cacheReadWriteLocker.WriteLock()) { // If multiple threads were calling this same routine, we might've had to wait around awhile, so we // will check the cache expiration again (unless we are in the "force update" mode) _cacheExpireTime = GetCacheExpirationForCustomer(customerID); if ((!forceUpdateIfCacheNotExpiredYet) && (DateTime.UtcNow >= _cacheExpireTime)) { // Gather the regulations for current customer from the database List <RegulatedHours_ExperimentalDBSchemaV1DTO> customerRegsFromDB = GetRegulatedHoursForCustomerFromDB(customerID); // Create cache object if doesn't exist yet if (_cachedRegulations == null) { _cachedRegulations = new List <RegulatedHours_ExperimentalDBSchemaV1DTO>(); } // Remove existing items from memory cache for the current customer RegulatedHours_ExperimentalDBSchemaV1DTOPredicate predicate = new RegulatedHours_ExperimentalDBSchemaV1DTOPredicate(customerID, null, null); List <RegulatedHours_ExperimentalDBSchemaV1DTO> cachedCustomerRegulations = _cachedRegulations.FindAll(predicate.CompareCustomerID); foreach (RegulatedHours_ExperimentalDBSchemaV1DTO nextReg in cachedCustomerRegulations) { _cachedRegulations.Remove(nextReg); } // Add the customer regulations that were obtained from the physical database _cachedRegulations.AddRange(customerRegsFromDB); // Now rewrite the XML cache RewriteXmlCache_WriteLockAlreadyAcquired(); // Finally, we will update the cache expiration for this customer so the cache won't try to be // updated again for this customer until another hour from now. Note that we need to be thread-safe // in upating the expiration time, because another thread might be trying to read it lock (_cacheExpirationsByCustomerId) { _cacheExpirationsByCustomerId[customerID] = DateTime.UtcNow.AddHours(1); } } else { System.Diagnostics.Debug.WriteLine("Cache not expired yet, no need to update"); } } } else { /*System.Diagnostics.Debug.WriteLine("Cache not expired yet, no need to update");*/ } }
// Return a list of all regulations for a given customer, meter, bay, or combination of such parameters (from cache) public List <RegulatedHours_ExperimentalDBSchemaV1DTO> GetRegulationsWithSameScope(int?cid, int?bayNumber, int?mid) { // Update the cache in background thread. The update routine will return immediately if the cache isn't expired yet if (cid.HasValue) { // Run this async so that the main thread can continue var task = new Task(() => { UpdateMemAndXmlCacheForCustomerFromDB(cid.Value, false); }); task.Start(); } RegulatedHours_ExperimentalDBSchemaV1DTOPredicate predicate = new RegulatedHours_ExperimentalDBSchemaV1DTOPredicate(cid, bayNumber, mid); List <RegulatedHours_ExperimentalDBSchemaV1DTO> result = null; // Protect this section with our ReadWriterLockAlt that handles concurrency issues for us using (_cacheReadWriteLocker.ReadLock()) { result = _cachedRegulations.FindAll(predicate.CompareVariableScope); } return(result); }