Пример #1
0
        private async Task ProcessTaskItemsAsync(EmailMassSendingTaskContext context,
                                                 ICollection <EmailMassSendingTaskItem> items, CancellationToken cancellationToken)
        {
            if (!items.Any())
            {
                return;
            }

            var delay = _configuration.DelayBetweenSendsInThread ?? TimeSpan.Zero;

            var lastItem = items.Last();

            foreach (var item in items)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }
                await ProcessTaskItemAsync(context, item, cancellationToken);

                if (item != lastItem)
                {
                    await Task.Delay(delay, cancellationToken);
                }
            }
        }
Пример #2
0
        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)";
            }
        }
Пример #3
0
        private async Task <EmailMassSendingTaskContext> ProcessTaskAsync(EmailMassSendingTaskContext context, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var buffer = new byte[context.File.Length];

            context.File.Position = 0;

            await context.File.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

            var taskList = JsonConvert.DeserializeObject <EmailMassSendingTask>(Encoding.UTF8.GetString(buffer));

            var taskItems = taskList.Items ?? new List <EmailMassSendingTaskItem>();

            var allTaskItems = taskItems;

            taskItems = allTaskItems.Where(IsReadyToProcess).ToList();

            if (!taskItems.Any())
            {
                _logger.LogDebug($"No task items to process.");
                context.Success = true;
                return(context);
            }

            var partedTaskItems = new List <EmailMassSendingTaskItem> [_configuration.Threads];
            var threadsCount    = _configuration.Threads;

            for (var i = 0; i < threadsCount; i++)
            {
                partedTaskItems[i] = new List <EmailMassSendingTaskItem>();
            }

            var q = new Queue <EmailMassSendingTaskItem>(taskItems);

            for (var i = 0; i < taskItems.Count; i++)
            {
                partedTaskItems[i % threadsCount].Add(q.Dequeue());
            }

            Parallel.ForEach(partedTaskItems, new ParallelOptions
            {
                MaxDegreeOfParallelism = threadsCount
            },
                             (b) =>
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }
                ProcessTaskItemsAsync(context, b, cancellationToken).GetAwaiter().GetResult();
            });


            buffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(taskList, Formatting.Indented));

            context.File.Position = 0;
            context.File.SetLength(buffer.Length);

            await context.File.WriteAsync(buffer, 0, buffer.Length, cancellationToken);

            await context.File.FlushAsync(cancellationToken);

            context.Success = allTaskItems.All(x => !IsNotObsolete(x) || (!x.Failed && x.Attempt != null));
            context.Total   = taskItems.Count;
            context.Sent    = taskItems.Count(x => x.Attempt != null && !x.Failed);
            context.Failed  = context.Total - context.Sent;

            return(context);
        }