protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _logger.LogDebug("HitmanForumStatusSeekerHostedService is starting"); stoppingToken.Register(() => _logger.LogDebug("HitmanForumStatusSeekerHostedService has been canceled")); using var scope = _scopeFactory.CreateScope(); var db = scope.ServiceProvider.GetRequiredService <DatabaseContext>(); var manager = new EventManager(db, _logger, _cache); while (!stoppingToken.IsCancellationRequested) { _logger.LogDebug("HitmanForumStatusSeekerHostedService is running"); var endpointException = new EndpointStatusException(EndpointName.HitmanForum); try { EndpointStatus endpoint = await _client.GetStatusAsync(); if (endpoint.State == EndpointState.Up) { _cache.Set(CacheKeys.HitmanForumKey, endpoint, new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.NeverRemove)); manager.RemoveCache(new List <string> { CacheKeys.HitmanForumErrorCountKey, CacheKeys.HitmanForumErrorEventKey }); } else { endpointException.Status = endpoint.Status; } } catch (Exception e) { _logger.LogError(e, "Exception in the HitmanForumStatusSeekerHostedService"); endpointException.Status = "Unhandled error"; endpointException.Message = e.Message; } finally { if (!string.IsNullOrEmpty(endpointException.Status)) { _cache.Set(CacheKeys.HitmanForumExceptionKey, endpointException, new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(45))); await manager.InsertEndpointExceptionAsync(endpointException); } } await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken); } _logger.LogDebug("HitmanForumStatusSeekerHostedService has been stopped"); }
public async Task InsertEndpointExceptionAsync(EndpointStatusException endpoint) { var cacheEventKey = string.Empty; var cacheCountKey = string.Empty; switch (endpoint.Name) { case EndpointName.HitmanAuthentication: cacheCountKey = CacheKeys.HitmanErrorCountKey; cacheEventKey = CacheKeys.HitmanErrorEventKey; break; case EndpointName.HitmanForum: cacheCountKey = CacheKeys.HitmanForumErrorCountKey; cacheEventKey = CacheKeys.HitmanForumErrorEventKey; break; } if (string.IsNullOrEmpty(cacheCountKey) || string.IsNullOrEmpty(cacheEventKey)) { return; } _logger.LogDebug($"An submission request to the database has been initiated for {endpoint.Name} endpoint"); var multiplier = 2; var firstEvent = false; if (!_cache.TryGetValue(cacheCountKey, out int counter)) { counter = 1; multiplier = counter; firstEvent = true; } else { counter++; } if (!_cache.TryGetValue(cacheEventKey, out string _)) { _cache.Set(cacheCountKey, counter, new MemoryCacheEntryOptions() .SetPriority(CacheItemPriority.NeverRemove)); if (firstEvent) { _logger.LogDebug("Isolated event, waiting for the next one."); return; } var state = endpoint.State.GetAttribute <DisplayAttribute>(); var service = endpoint.Name.GetAttribute <DisplayAttribute>(); var entity = new Event() { Service = service.Name, State = state.Name, Status = endpoint.Status, Message = endpoint.Message }; try { _db.Add(entity); await _db.SaveChangesAsync(); _logger.LogDebug("Event added in the database."); } catch (Exception e) { _logger.LogError(e, "Database insert exception in InsertEndpointExceptionAsync() method"); } var delay = counter * multiplier * 60; _cache.Set(cacheEventKey, string.Empty, new MemoryCacheEntryOptions() .SetAbsoluteExpiration(TimeSpan.FromSeconds(delay))); _logger.LogDebug($"Lock database submissions for {delay} seconds " + $"({counter} (counter) * {multiplier} (multiplier) * 60)"); } else { _logger.LogDebug("Database is locked with a delay, no events submitted"); } }