public HomeController(IMailDemonDatabaseProvider dbProvider, IMailCreator mailCreator, IMailSender mailSender, IBulkMailSender bulkMailSender, IAuthority authority) { this.dbProvider = dbProvider; this.mailCreator = mailCreator ?? throw new ArgumentNullException(nameof(mailCreator)); this.mailSender = mailSender ?? throw new ArgumentNullException(nameof(mailSender)); this.bulkMailSender = bulkMailSender; this.authority = authority; }
public GlobalExceptionHandler( IHostingEnvironment hostingEnvironment, IMailManager mailManager, IMailCreator mailCreator ) { _hostingEnvironment = hostingEnvironment; _mailManager = mailManager; _mailCreator = mailCreator; }
public async Task SendBulkMail(MailList list, IMailCreator mailCreator, IMailSender mailSender, ExpandoObject viewBag, bool all, string fullTemplateName, string unsubscribeUrl) { MailDemonLog.Warn("Started bulk send for {0}", fullTemplateName); DateTime now = DateTime.UtcNow; int successCount = 0; int failCount = 0; List <Task> pendingTasks = new List <Task>(); Stopwatch timer = Stopwatch.StartNew(); using (var db = dbProvider.GetDatabase()) { void callbackHandler(MailListSubscription _sub, string error) { lock (db) { // although this is slow, it is required as we do not want to double email people in the event // that server reboots, loses power, etc. for every message we have to mark that person // with the correct status immediately _sub.Result = error; _sub.ResultTimestamp = DateTime.UtcNow; db.Update(_sub); db.SaveChanges(); if (string.IsNullOrWhiteSpace(error)) { successCount++; } else { failCount++; } } } // use a separate database instance to do the query, that way we can update records in our other database instance // preventing locking errors, especially with sqlite drivers MailDemonLog.Warn("Begin bulk send"); using (var dbBulk = dbProvider.GetDatabase()) { IEnumerable <KeyValuePair <string, IEnumerable <MailListSubscription> > > pendingSubs = dbBulk.GetBulkEmailSubscriptions(list, unsubscribeUrl, all); foreach (KeyValuePair <string, IEnumerable <MailListSubscription> > sub in pendingSubs) { now = DateTime.UtcNow; try { IAsyncEnumerable <MailToSend> messagesToSend = GetMessages(sub.Value, mailCreator, list, viewBag, fullTemplateName, callbackHandler); Task task = mailSender.SendMailAsync(sub.Key, messagesToSend); pendingTasks.Add(task); } catch (Exception ex) { MailDemonLog.Error(ex); } } } await Task.WhenAll(pendingTasks); MailDemonLog.Warn("Finished bulk send for {0}, {1} messages succeeded, {2} messages failed in {3:0.00} seconds.", fullTemplateName, successCount, failCount, timer.Elapsed.TotalSeconds); } GC.Collect(); }
private async IAsyncEnumerable <MailToSend> GetMessages(IEnumerable <MailListSubscription> subs, IMailCreator mailCreator, MailList list, ExpandoObject viewBag, string fullTemplateName, Action <MailListSubscription, string> callback) { foreach (MailListSubscription sub in subs) { MimeMessage message; try { message = await mailCreator.CreateMailAsync(fullTemplateName, sub, viewBag, null); } catch (Exception ex) { MailDemonLog.Error(ex); continue; } message.From.Clear(); message.To.Clear(); if (string.IsNullOrWhiteSpace(list.FromEmailName)) { message.From.Add(MailboxAddress.Parse(list.FromEmailAddress)); } else { message.From.Add(new MailboxAddress(list.FromEmailName, list.FromEmailAddress)); } message.To.Add(MailboxAddress.Parse(sub.EmailAddress)); yield return(new MailToSend { Subscription = sub, Message = message, Callback = callback }); } }
public ConnectionCreator(IMailCreator mailCreator) => _mailCreator = mailCreator;