Пример #1
0
        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);
            }
        }
Пример #2
0
        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();
            });
        }
Пример #3
0
        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;
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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();
                }
            });
        }
Пример #6
0
        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);
        }