/// <summary> /// Processes the instruction batch and checks for errors. /// </summary> /// <param name="processed"> /// Tracks which instructions have already been processed to avoid duplicates /// </param> /// Returns true if all instructions in the batch were processed, otherwise false if they could not be due to the app being shut down /// </returns> private bool ProcessDatabaseInstructions( CacheRefresherCollection cacheRefreshers, IReadOnlyCollection <RefreshInstruction> instructionBatch, CacheInstruction instruction, HashSet <RefreshInstruction> processed, CancellationToken cancellationToken, ref int lastId) { // Execute remote instructions & update lastId. try { var result = NotifyRefreshers(cacheRefreshers, instructionBatch, processed, cancellationToken); if (result) { // If all instructions were processed, set the last id. lastId = instruction.Id; } return(result); } catch (Exception ex) { _logger.LogError( ex, "DISTRIBUTED CACHE IS NOT UPDATED. Failed to execute instructions ({DtoId}: '{DtoInstructions}'). Instruction is being skipped/ignored", instruction.Id, instruction.Instructions); // We cannot throw here because this invalid instruction will just keep getting processed over and over and errors // will be thrown over and over. The only thing we can do is ignore and move on. lastId = instruction.Id; return(false); } }
public static CacheInstructionDto BuildDto(CacheInstruction entity) => new CacheInstructionDto { Id = entity.Id, UtcStamp = entity.UtcStamp, Instructions = entity.Instructions, OriginIdentity = entity.OriginIdentity, InstructionCount = entity.InstructionCount, };
/// <inheritdoc/> public void DeliverInstructions(IEnumerable <RefreshInstruction> instructions, string localIdentity) { CacheInstruction entity = CreateCacheInstruction(instructions, localIdentity); using (IScope scope = ScopeProvider.CreateScope()) { _cacheInstructionRepository.Add(entity); scope.Complete(); } }
/// <inheritdoc/> public void DeliverInstructionsInBatches(IEnumerable <RefreshInstruction> instructions, string localIdentity) { // Write the instructions but only create JSON blobs with a max instruction count equal to MaxProcessingInstructionCount. using (IScope scope = ScopeProvider.CreateScope()) { foreach (IEnumerable <RefreshInstruction> instructionsBatch in instructions.InGroupsOf(_globalSettings.DatabaseServerMessenger.MaxProcessingInstructionCount)) { CacheInstruction entity = CreateCacheInstruction(instructionsBatch, localIdentity); _cacheInstructionRepository.Add(entity); } scope.Complete(); } }
public CacheConfiguration BuildConfiguration() { var fixedForOneHour = new CacheInstruction(CacheType.Fixed, TimeSpan.FromHours(1)); var cacheConfig = new CacheConfiguration(); cacheConfig.ApplyCachingOn(x => x.DeclaringType.Name.EndsWith("Repository"), fixedForOneHour) .InvalidateOn(x => x.Name.StartsWith("Save")) .InvalidateOn(x => x.Name.StartsWith("Delete")) .InvalidateOn(x => x.Name.StartsWith("Update")); //apply exceptions //cacheConfig // .ExceptFor<IPersonRepository>(x => x.GetByName(null)) // .InvalidateOn<IPersonRepository>(x => x.Save(null)); return cacheConfig; }
/// <summary> /// Attempts to deserialize the instructions to a JArray. /// </summary> private bool TryDeserializeInstructions(CacheInstruction instruction, out JArray jsonInstructions) { try { jsonInstructions = JsonConvert.DeserializeObject <JArray>(instruction.Instructions); return(true); } catch (JsonException ex) { _logger.LogError(ex, "Failed to deserialize instructions ({DtoId}: '{DtoInstructions}').", instruction.Id, instruction.Instructions); jsonInstructions = null; return(false); } }
public AcceptInstruction(Func<MemberInfo, bool> acceptCriteria, CacheInstruction instruction) { _acceptCriteria = acceptCriteria; _instruction = instruction; }