using FabApprovalWorkerService.Models; using FabApprovalWorkerService.Services; using Infineon.Monitoring.MonA; using Quartz; using System.Text; namespace FabApprovalWorkerService.Workers; public class UserCertificationWorker : IJob { private static readonly int MAX_RETRIES = 3; private static readonly int BACKOFF_SECONDS = 30; private readonly ILogger _logger; private readonly IUserService _userService; private readonly IMonInClient _monInClient; public UserCertificationWorker(ILogger logger, IUserService userService, IMonInClient monInClient) { _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _userService = userService ?? throw new ArgumentNullException("IUserService not injected"); _monInClient = monInClient ?? throw new ArgumentNullException("IMonInClient not injected"); } public async Task Execute(IJobExecutionContext context) { DateTime start = DateTime.Now; bool isInternalError = false; string metricName = "UserCertificationWorker"; try { int remainingRetries = MAX_RETRIES; bool isSuccessful = false; while (!isSuccessful && remainingRetries > 0) { await Task.Delay((MAX_RETRIES - remainingRetries--) * BACKOFF_SECONDS); _logger.LogInformation($"Attempting to update user certification data. Remaining retries: {remainingRetries}"); IEnumerable certRecords = await _userService.GetUserCertificationRecords(); isSuccessful = await _userService.UpdateUserCertificationData(certRecords); } if (isSuccessful) { _logger.LogInformation("Successfully updated user certification data."); } else { throw new Exception("Unable to update user certification data."); } } catch (Exception ex) { StringBuilder errMsgBuilder = new(); errMsgBuilder.Append("An exception occurred when attempting to update user certification data. "); errMsgBuilder.Append($"Exception: {ex.Message}"); _logger.LogError(errMsgBuilder.ToString()); isInternalError = true; } finally { DateTime end = DateTime.Now; double latencyInMS = (end - start).TotalMilliseconds; _monInClient.PostMetric(metricName + "Latency", latencyInMS); if (isInternalError) { _monInClient.PostStatus(metricName, State.Critical); } else { _monInClient.PostStatus(metricName, State.Ok); } } } }