141 lines
5.3 KiB
C#
141 lines
5.3 KiB
C#
using System;
|
|
using AAIntegration.SimmonsBank.API.Configs;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Options;
|
|
using AAIntegration.SimmonsBank.API.Processes;
|
|
using AAIntegration.SimmonsBank.API.Services;
|
|
using AAIntegration.SimmonsBank.API.Entities;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
|
|
namespace AAIntegration.SimmonsBank.API.Workers;
|
|
|
|
public class PuppeteerWorker : BackgroundService
|
|
{
|
|
private readonly PuppeteerConfig _config;
|
|
private readonly IPuppeteerProcess _puppeteerProcess;
|
|
private readonly ILogger<PuppeteerWorker> _logger;
|
|
private readonly IMemoryCache _memoryCache;
|
|
private readonly IServiceScopeFactory _serviceScopeFactory;
|
|
|
|
public PuppeteerWorker(
|
|
IOptions<PuppeteerConfig> config,
|
|
IPuppeteerProcess puppeteerProcess,
|
|
ILogger<PuppeteerWorker> logger,
|
|
IMemoryCache memoryCache,
|
|
IServiceScopeFactory serviceScopeFactory)
|
|
{
|
|
_config = config.Value;
|
|
_puppeteerProcess = puppeteerProcess;
|
|
_logger = logger;
|
|
_memoryCache = memoryCache;
|
|
_serviceScopeFactory = serviceScopeFactory;
|
|
}
|
|
|
|
private IUserService _userService;
|
|
|
|
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
{
|
|
DateTime? lastExecutedOn = null;
|
|
bool operationOccurred = false;
|
|
|
|
using (var scope = _serviceScopeFactory.CreateScope())
|
|
{
|
|
_userService = scope.ServiceProvider.GetService<IUserService>();
|
|
_puppeteerProcess.SetStoppingToken(stoppingToken);
|
|
|
|
// This is how we keep the app running (in the background)
|
|
while (!stoppingToken.IsCancellationRequested)
|
|
{
|
|
// Keep Alive processing
|
|
operationOccurred = await ProcessUsersKeepalive();
|
|
|
|
|
|
_logger.LogInformation($"Operation occurred? {operationOccurred}");
|
|
|
|
// If no operation occurred, waits before looping again
|
|
if (lastExecutedOn != null && operationOccurred == false)
|
|
{
|
|
await Task.Delay(TimeSpan.FromMinutes(_config.TaskCheckIntervalMinutes), stoppingToken);
|
|
}
|
|
|
|
lastExecutedOn = DateTime.UtcNow;
|
|
_logger.LogInformation("PuppeteerWorker executed at: {time}", DateTimeOffset.Now);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task<bool> ProcessUsersKeepalive()
|
|
{
|
|
bool operationOccurred = false;
|
|
|
|
foreach (User user in _userService.GetAll().ToList())
|
|
{
|
|
int ka = _config.KeepAliveIntervalMinutes;
|
|
int uka = (int)DateTime.UtcNow.Subtract(GetUserLastExecution(PuppeteerConfigConstants.KeepAliveIntervalMinutes, user.Id)).TotalMinutes;
|
|
|
|
//_logger.LogInformation($"KeepAlive configured to {ka}. This user hasn't been kept alive in {uka} minute(s).");
|
|
|
|
if (_config.KeepAliveIntervalMinutes <= (int)DateTime.UtcNow.Subtract(GetUserLastExecution(PuppeteerConfigConstants.KeepAliveIntervalMinutes, user.Id)).TotalMinutes)
|
|
{
|
|
await _puppeteerProcess.StayLoggedIn(user);
|
|
SetUserLastExecution(PuppeteerConfigConstants.KeepAliveIntervalMinutes, user.Id, DateTime.UtcNow);
|
|
operationOccurred = true;
|
|
_logger.LogInformation($"Operation set to true because of user {user.Id}");
|
|
}
|
|
}
|
|
|
|
return operationOccurred;
|
|
}
|
|
|
|
private DateTime GetUserLastExecution(string cacheKey, int userId)
|
|
{
|
|
var internalKeys = GetLastExecutionCachedDictionary(cacheKey);
|
|
|
|
if (!internalKeys.TryGetValue(userId, out var lastExecution))
|
|
{
|
|
_logger.LogInformation($"Could not find userId in '{cacheKey}' cache. Returning '{DateTime.MinValue}'.");
|
|
return DateTime.MinValue;
|
|
}
|
|
|
|
_logger.LogInformation($"Just got user {userId} from cache with value {lastExecution}");
|
|
return lastExecution;
|
|
}
|
|
|
|
private void SetUserLastExecution(string cacheKey, int userId, DateTime lastExecution)
|
|
{
|
|
var internalKeys = GetLastExecutionCachedDictionary(cacheKey);
|
|
|
|
if (internalKeys.ContainsKey(userId))
|
|
internalKeys[userId] = lastExecution;
|
|
else
|
|
internalKeys.Add(userId, lastExecution);
|
|
|
|
_memoryCache.Set(cacheKey, internalKeys);
|
|
_logger.LogInformation($"Just set user {userId} into cache with value {lastExecution}");
|
|
}
|
|
|
|
private Dictionary<int, DateTime> GetLastExecutionCachedDictionary(string cacheKey)
|
|
{
|
|
// Sets cache if no dictionary is found
|
|
if (!_memoryCache.TryGetValue<Dictionary<int, DateTime>>(cacheKey, out var internalKeys))
|
|
{
|
|
internalKeys = _userService.GetAll()
|
|
.ToDictionary(u => u.Id, u => DateTime.MinValue);
|
|
_memoryCache.Set(cacheKey, internalKeys);
|
|
_logger.LogInformation($"Updated users in '{cacheKey}' cache with new id list.");
|
|
}
|
|
|
|
return internalKeys;
|
|
}
|
|
|
|
private void PrintCacheValues(string cacheKey)
|
|
{
|
|
_logger.LogInformation($"Printing cache values from '{cacheKey}'");
|
|
Dictionary<int, DateTime> internalKeys = GetLastExecutionCachedDictionary(cacheKey);
|
|
foreach (KeyValuePair<int, DateTime> entry in internalKeys)
|
|
{
|
|
_logger.LogInformation($" {entry.Key} <=> {entry.Value}");
|
|
}
|
|
}
|
|
}
|