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");
        }
Exemplo n.º 2
0
        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");
            }
        }