private static void WriteResults(MassMail massMail, IEnumerable <DataTable> results) { try { var dataTable = new DataTable(); foreach (var result in results) { dataTable.Merge(result); } massMail.UpdateBlock(dataTable); } catch (Exception ex) { Logger.Log.Error("Unable to write batch: {0}", ex.Message); } }
public void Init() { _massMail = new MassMail(Config.BlockSize, Config.UserAgent, Config.ConnectionString, Config.Mode); _templateCache = new ConcurrentDictionary<long, Lazy<Template>>(); _attachmentCache = new ConcurrentDictionary<long, Lazy<Attach>>(); _dkimSignerCache = new ConcurrentDictionary<string, DkimSigner>(); _domailKeySignerCache = new ConcurrentDictionary<string, DomainKeySigner>(); //Get all private keys GetDkimSigners(); //*** Create pipeline *** //Create TransformBlock that gets table of client data and make a list of objects from them. _parseXmlDataBlock = new TransformBlock<DataTable, List<Mail>>(sendData => ParseXmlData(sendData), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Config.ParseXmlMaxdop, BoundedCapacity = Config.ParseXmlBufferSize }); //Create TransformBlock that gets a list of client objects, send them email, and stores result in DataTable. _sendEmailsBlock = new TransformBlock<List<Mail>, DataTable>(mails => SendEmails(_massMail, mails), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Config.SendEmailsMaxdop, BoundedCapacity = Config.SendEmailsMaxdop }); //Create BatchBlock that holds several DataTable and then propagates them out as an array. _batchResultBlock = new BatchBlock<DataTable>(Config.BatchSize, new GroupingDataflowBlockOptions { BoundedCapacity = Config.BatchSize }); //Create ActionBlock that writes result into DB _writeResultsBlock = new ActionBlock<DataTable[]>(results => WriteResults(_massMail, results), new ExecutionDataflowBlockOptions { BoundedCapacity = 1 }); //*** Build pipeline *** // POST --> _parseXmlDataBlock --> _sendEmailsBlock --> _batchResultBlock --> _writeResultsBlock _parseXmlDataBlock.LinkTo(_sendEmailsBlock); _sendEmailsBlock.LinkTo(_batchResultBlock); _batchResultBlock.LinkTo(_writeResultsBlock); _parseXmlDataBlock.Completion.ContinueWith(t => { if (t.IsFaulted) ((IDataflowBlock)_sendEmailsBlock).Fault(t.Exception); else _sendEmailsBlock.Complete(); }); _sendEmailsBlock.Completion.ContinueWith(t => { if (t.IsFaulted) ((IDataflowBlock)_batchResultBlock).Fault(t.Exception); else _batchResultBlock.Complete(); }); _batchResultBlock.Completion.ContinueWith(t => { if (t.IsFaulted) ((IDataflowBlock)_writeResultsBlock).Fault(t.Exception); else _writeResultsBlock.Complete(); }); }
private DataTable SendEmails(MassMail massMail, IEnumerable<Mail> mails) { var mailClient = new DKIM.SmtpClient(Config.MailServer, Config.MailPort); var resultTable = new DataTable(); var processedCount = 0; var errorCount = 0; resultTable.Columns.Add("ID"); resultTable.Columns.Add("Status"); resultTable.Columns.Add("SendMoment"); foreach (var mail in mails) { var result = 0; var attachs = new List<Attach>(); try { if (mail.Model == null) throw new XmlException(String.Format("error when creating model for ID:[{0}]", mail.Id)); //Load template var id = mail.TemplateId; var template = _templateCache.GetOrAdd(id, new Lazy<Template>(() => massMail.GetTemplate(id))).Value; var body = Functions.RazorGetText(template.Body, template.Guid, mail.Model); //Parse subject var subject = mail.Subject; if (!mail.StaticSubject) subject = Functions.RazorGetText(mail.Subject, Functions.GetMd5(mail.Subject), mail.Model); //Get attachments if (mail.HasAttachment) // ReSharper disable once LoopCanBeConvertedToQuery foreach (DataRow attachRow in massMail.GetAttachments(mail.Id).Rows) { var attachId = (long)attachRow["AttachmentID"]; attachs.Add(_attachmentCache.GetOrAdd(attachId, new Lazy<Attach>(() => massMail.GetAttachment(attachId))).Value); } result = SendMail(mailClient, mail.From, mail.To, mail.Cc, subject, mail.ListId, body, template.IsHtml, attachs); processedCount++; } catch (XmlException ex) { Logger.Log.Error("Unable to parse xml: {0}", ex.Message); errorCount++; result = (int)MailStatusCode.XMLERROR; } catch (RazorException ex) { Logger.Log.Error("Razor error: {0}", ex.Message); errorCount++; result = (int)MailStatusCode.RAZORERROR; } catch (SmtpFailedRecipientsException ex) { Logger.Log.Error("SMTP exception: {0}", ex.Message); errorCount++; result = (int)ex.StatusCode; } catch (Exception ex) { Logger.Log.Error("Unable to send email: {0}", ex.Message); errorCount++; result = (int)MailStatusCode.FAILED; } finally { resultTable.Rows.Add(new object[] { mail.Id, result, DateTime.Now }); } } MessagesSend(processedCount, errorCount); mailClient.Dispose(); return resultTable; }
private static void WriteResults(MassMail massMail, IEnumerable<DataTable> results) { try { var dataTable = new DataTable(); foreach (var result in results) dataTable.Merge(result); massMail.UpdateBlock(dataTable); } catch (Exception ex) { Logger.Log.Error("Unable to write batch: {0}", ex.Message); } }
public void Init() { _massMail = new MassMail(Config.BlockSize, Config.UserAgent, Config.ConnectionString, Config.Mode); _templateCache = new ConcurrentDictionary <long, Lazy <Template> >(); _attachmentCache = new ConcurrentDictionary <long, Lazy <Attach> >(); _dkimSignerCache = new ConcurrentDictionary <string, DkimSigner>(); _domailKeySignerCache = new ConcurrentDictionary <string, DomainKeySigner>(); //Get all private keys GetDkimSigners(); //*** Create pipeline *** //Create TransformBlock that gets table of client data and make a list of objects from them. _parseXmlDataBlock = new TransformBlock <DataTable, List <Mail> >(sendData => ParseXmlData(sendData), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Config.ParseXmlMaxdop, BoundedCapacity = Config.ParseXmlBufferSize }); //Create TransformBlock that gets a list of client objects, send them email, and stores result in DataTable. _sendEmailsBlock = new TransformBlock <List <Mail>, DataTable>(mails => SendEmails(_massMail, mails), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Config.SendEmailsMaxdop, BoundedCapacity = Config.SendEmailsMaxdop }); //Create BatchBlock that holds several DataTable and then propagates them out as an array. _batchResultBlock = new BatchBlock <DataTable>(Config.BatchSize, new GroupingDataflowBlockOptions { BoundedCapacity = Config.BatchSize }); //Create ActionBlock that writes result into DB _writeResultsBlock = new ActionBlock <DataTable[]>(results => WriteResults(_massMail, results), new ExecutionDataflowBlockOptions { BoundedCapacity = 1 }); //*** Build pipeline *** // POST --> _parseXmlDataBlock --> _sendEmailsBlock --> _batchResultBlock --> _writeResultsBlock _parseXmlDataBlock.LinkTo(_sendEmailsBlock); _sendEmailsBlock.LinkTo(_batchResultBlock); _batchResultBlock.LinkTo(_writeResultsBlock); _parseXmlDataBlock.Completion.ContinueWith(t => { if (t.IsFaulted) { ((IDataflowBlock)_sendEmailsBlock).Fault(t.Exception); } else { _sendEmailsBlock.Complete(); } }); _sendEmailsBlock.Completion.ContinueWith(t => { if (t.IsFaulted) { ((IDataflowBlock)_batchResultBlock).Fault(t.Exception); } else { _batchResultBlock.Complete(); } }); _batchResultBlock.Completion.ContinueWith(t => { if (t.IsFaulted) { ((IDataflowBlock)_writeResultsBlock).Fault(t.Exception); } else { _writeResultsBlock.Complete(); } }); }
private DataTable SendEmails(MassMail massMail, IEnumerable <Mail> mails) { var mailClient = new DKIM.SmtpClient(Config.MailServer, Config.MailPort); var resultTable = new DataTable(); var processedCount = 0; var errorCount = 0; resultTable.Columns.Add("ID"); resultTable.Columns.Add("Status"); resultTable.Columns.Add("SendMoment"); foreach (var mail in mails) { var result = 0; var attachs = new List <Attach>(); try { if (mail.Model == null) { throw new XmlException(String.Format("error when creating model for ID:[{0}]", mail.Id)); } //Load template var id = mail.TemplateId; var template = _templateCache.GetOrAdd(id, new Lazy <Template>(() => massMail.GetTemplate(id))).Value; var body = Functions.RazorGetText(template.Body, template.Guid, mail.Model); //Parse subject var subject = mail.Subject; if (!mail.StaticSubject) { subject = Functions.RazorGetText(mail.Subject, Functions.GetMd5(mail.Subject), mail.Model); } //Get attachments if (mail.HasAttachment) { // ReSharper disable once LoopCanBeConvertedToQuery foreach (DataRow attachRow in massMail.GetAttachments(mail.Id).Rows) { var attachId = (long)attachRow["AttachmentID"]; attachs.Add(_attachmentCache.GetOrAdd(attachId, new Lazy <Attach>(() => massMail.GetAttachment(attachId))).Value); } } result = SendMail(mailClient, mail.From, mail.To, mail.Cc, subject, mail.ListId, body, template.IsHtml, attachs); processedCount++; } catch (XmlException ex) { Logger.Log.Error("Unable to parse xml: {0}", ex.Message); errorCount++; result = (int)MailStatusCode.XMLERROR; } catch (RazorException ex) { Logger.Log.Error("Razor error: {0}", ex.Message); errorCount++; result = (int)MailStatusCode.RAZORERROR; } catch (SmtpFailedRecipientsException ex) { Logger.Log.Error("SMTP exception: {0}", ex.Message); errorCount++; result = (int)ex.StatusCode; } catch (Exception ex) { Logger.Log.Error("Unable to send email: {0}", ex.Message); errorCount++; result = (int)MailStatusCode.FAILED; } finally { resultTable.Rows.Add(new object[] { mail.Id, result, DateTime.Now }); } } MessagesSend(processedCount, errorCount); mailClient.Dispose(); return(resultTable); }