private bool IsNotObsolete(EmailMassSendingTaskItem item) { if (item.AttemptsLeft == 0) { return(false); } if (item.WaitFor != null && DateTimeOffset.Compare(item.WaitFor.Value, DateTimeOffset.UtcNow) > 0) { return(false); } if (DateTimeOffset.Compare(item.Lifetime, DateTimeOffset.UtcNow) < 0) { return(false); } return(true); }
private async Task ProcessTaskItemAsync(EmailMassSendingTaskContext context, EmailMassSendingTaskItem item, CancellationToken cancellationToken) { item.AttemptsLeft--; item.Attempt = DateTimeOffset.UtcNow; var defaultEncoding = _configuration.Encoding == null ? Encoding.UTF8 : Encoding.GetEncoding(_configuration.Encoding); var encoding = context.GroupConfiguration.Encoding == null ? defaultEncoding : Encoding.GetEncoding(context.GroupConfiguration.Encoding); //using var client = new SmtpClient() var scope = _logger.BeginScope(context.TaskId); if (_configuration.SmtpClient.Enable ?? true) { try { using var client = new SmtpClient(); client.Host = _configuration.SmtpClient.Host; client.Port = _configuration.SmtpClient.Port ?? 25; client.EnableSsl = _configuration.SmtpClient.UseSsl ?? true; client.DeliveryMethod = SmtpDeliveryMethod.Network; client.UseDefaultCredentials = false; client.Credentials = new NetworkCredential(_configuration.SmtpClient.Username, _configuration.SmtpClient.Password); using var message = new MailMessage(); message.From = new MailAddress(_configuration.FromAddress, _configuration.FromTitle, defaultEncoding); message.BodyEncoding = encoding; message.SubjectEncoding = encoding; message.IsBodyHtml = false; message.Body = encoding.GetString(context.Text); message.Subject = context.GroupConfiguration.Subject; message.To.Add(new MailAddress(item.Receiver)); var ts = DateTime.UtcNow; await client.SendMailAsync(message, cancellationToken); _logger.LogDebug( $"Mail to `{item.Receiver}` sent ({DateTime.UtcNow.Subtract(ts).TotalSeconds} s)."); item.Failed = false; item.Failure = null; } catch (Exception e) { _logger.LogError(e, $"Email sending error (item receiver: `{item.Receiver}`)"); item.Failed = true; item.Failure = e.Message; item.WaitFor = DateTimeOffset.UtcNow.Add(_configuration.RollUpStrategy.Delay); } } else { item.Failed = false; item.Failure = "Not sent (disabled)"; } }
private bool IsReadyToProcess(EmailMassSendingTaskItem item) { return((item.Attempt == null || (item.Attempt != null && item.Failed)) && IsNotObsolete(item)); }
private async Task <EmailMassSendingTaskContext> PrepareGroupOfTasksAsync(string groupId, GroupConfiguration groupConfiguration, bool force, CancellationToken cancellationToken) { await using var file = new FileStream(groupConfiguration.PlainTextFileName, FileMode.Open, FileAccess.Read, FileShare.None); var buffer = new byte[file.Length]; await file.ReadAsync(buffer, 0, buffer.Length, cancellationToken); using var md5 = MD5.Create(); var hex = Convert.ToHexString(md5.ComputeHash(buffer)); var taskDir = _configuration.TasksPath ?? string.Empty; var taskId = $"{groupId}_{hex}.task"; var taskPath = Path.Combine(taskDir, taskId); if (!Directory.Exists(taskDir)) { Directory.CreateDirectory(taskDir); } else { if (_configuration.DeleteObsoleteTasks) { var lifetime = _configuration.TaskFileLifetime ?? TimeSpan.FromDays(1); foreach (var taskFileForDelete in Directory.GetFiles(taskDir, "*.task", SearchOption.TopDirectoryOnly)) { var fi = new FileInfo(taskFileForDelete); if (DateTime.Compare(fi.CreationTimeUtc.Add(lifetime), DateTime.UtcNow) < 0) { File.Delete(taskFileForDelete); _logger.LogDebug($"Task file `{taskFileForDelete}` was deleted as obsolete."); } } } } if (File.Exists(taskPath)) { if (!force) { _logger.LogDebug($"Task `{taskId}` already exists. Reusing."); var taskFs = new FileStream(taskPath, FileMode.Open, FileAccess.ReadWrite, FileShare.None); return(new EmailMassSendingTaskContext(taskId, taskFs, buffer, groupConfiguration)); } File.Delete(taskPath); } var newTask = new EmailMassSendingTask { TaskId = taskId, Items = new List <EmailMassSendingTaskItem>() }; if (groupConfiguration.Receivers == null) { _logger.LogWarning($"No receivers in group `{groupId}` specified."); return(null); } foreach (var receiver in groupConfiguration.Receivers.Distinct()) { var newTaskItem = new EmailMassSendingTaskItem { Receiver = receiver, Failed = false, Failure = null, Lifetime = new DateTimeOffset(DateTime.UtcNow.Add(groupConfiguration.Actuality ?? TimeSpan.FromHours(1))) }; if (_configuration.RollUpStrategy.Enable) { newTaskItem.AttemptsLeft = _configuration.RollUpStrategy.MaxCount; newTaskItem.WaitFor = DateTimeOffset.UtcNow; } newTask.Items.Add(newTaskItem); } var task2Fs = new FileStream(taskPath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None); var taskFileBody = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(newTask)); task2Fs.Position = 0; task2Fs.SetLength(taskFileBody.Length); await task2Fs.WriteAsync(taskFileBody, 0, taskFileBody.Length, cancellationToken); task2Fs.Position = 0; return(new EmailMassSendingTaskContext(taskId, task2Fs, buffer, groupConfiguration)); }