private List <TaskData> CreateTasks(int needCount, CancellationToken cancelToken) { _log.InfoFormat("CreateTasks(need {0} tasks).", needCount); var mailboxes = _queueManager.GetLockedMailboxes(needCount); var tasks = new List <TaskData>(); foreach (var mailbox in mailboxes) { var timeoutCancel = new CancellationTokenSource(_taskSecondsLifetime); var commonCancelToken = CancellationTokenSource.CreateLinkedTokenSource(cancelToken, timeoutCancel.Token).Token; var taskLogger = LogManager.GetLogger(string.Format("ASC.Mail Mbox_{0}", mailbox.MailBoxId)); taskLogger.InfoFormat("CreateMailClient(Tenant = {0} MailboxId = {1}, Address = '{2}')", mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail); var client = CreateMailClient(mailbox, taskLogger, commonCancelToken); if (client == null || !client.IsConnected || !client.IsAuthenticated) { if (client != null) { taskLogger.InfoFormat("Client -> Could not connect: {0} | Not authenticated: {1}.", !client.IsConnected ? "Yes" : "No", !client.IsAuthenticated ? "Yes" : "No"); } else { taskLogger.InfoFormat("Client was null"); } taskLogger.InfoFormat("ReleaseMailbox(Tenant = {0} MailboxId = {1}, Address = '{2}')", mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail); ReleaseMailbox(mailbox); continue; } var task = _taskFactory.StartNew(() => ProcessMailbox(client, _tasksConfig), commonCancelToken); tasks.Add(new TaskData(mailbox, task)); } if (tasks.Any()) { _log.InfoFormat("Created {0} tasks.", tasks.Count); } else { _log.Info("No more mailboxes for processing."); } return(tasks); }
public AggregatorService(Options options) { ServiceName = ASC_MAIL_COLLECTION_SERVICE_NAME; EventLog.Log = "Application"; // These Flags set whether or not to handle that specific // type of event. Set to true if you need it, false otherwise. CanHandlePowerEvent = false; CanHandleSessionChangeEvent = false; CanPauseAndContinue = false; CanShutdown = true; CanStop = true; try { _log = LogManager.GetLogger("ASC.Mail.MainThread"); _logStat = LogManager.GetLogger("ASC.Mail.Stat"); _tasksConfig = TasksConfig.FromConfig; var mailSettings = new MailQueueItemSettings(); _tasksConfig.DefaultFolders = mailSettings.DefaultFolders; _tasksConfig.ImapFlags = mailSettings.ImapFlags; _tasksConfig.SkipImapFlags = mailSettings.SkipImapFlags; _tasksConfig.SpecialDomainFolders = mailSettings.SpecialDomainFolders; if (options.OnlyUsers != null) { _tasksConfig.WorkOnUsersOnly.AddRange(options.OnlyUsers.ToList()); } if (options.NoMessagesLimit) { _tasksConfig.MaxMessagesPerSession = -1; } _taskSecondsLifetime = TimeSpan.FromSeconds(ConfigurationManager.AppSettings["mail.task-process-lifetime-seconds"] != null ? Convert.ToInt32(ConfigurationManager.AppSettings["mail.task-process-lifetime-seconds"]) : 300); _queueManager = new QueueManager(_tasksConfig, _log); _resetEvent = new ManualResetEvent(false); _cancelTokenSource = new CancellationTokenSource(); _taskFactory = new TaskFactory(); _tsTaskStateCheckInterval = ConfigurationManager.AppSettings["mail.task-check-state-seconds"] != null ? TimeSpan.FromSeconds( Convert.ToInt32(ConfigurationManager.AppSettings["mail.task-check-state-seconds"])) : TimeSpan.FromSeconds(30); if (_tasksConfig.EnableSignalr) { _signalrWorker = new SignalrWorker(); } _workTimer = new Timer(workTimer_Elapsed, _cancelTokenSource.Token, Timeout.Infinite, Timeout.Infinite); Filters = new ConcurrentDictionary <string, List <MailSieveFilterData> >(); _log.Info("Service is ready."); } catch (Exception ex) { _log.FatalFormat("CollectorService error under construct: {0}", ex.ToString()); } }
private void ProcessMailbox(MailClient client, TasksConfig tasksConfig) { var mailbox = client.Account; Stopwatch watch = null; if (_tasksConfig.CollectStatistics) { watch = new Stopwatch(); watch.Start(); } var failed = false; var taskLogger = LogManager.GetLogger(string.Format("ASC.Mail Mbox_{0} Task_{1}", mailbox.MailBoxId, Task.CurrentId)); taskLogger.InfoFormat( "ProcessMailbox(Tenant = {0}, MailboxId = {1} Address = '{2}') Is {3}", mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, mailbox.Active ? "Active" : "Inactive"); try { client.Log = taskLogger; client.GetMessage += ClientOnGetMessage; client.Aggregate(tasksConfig, tasksConfig.MaxMessagesPerSession); } catch (OperationCanceledException) { taskLogger.InfoFormat( "[CANCEL] ProcessMailbox(Tenant = {0}, MailboxId = {1}, Address = '{2}')", mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail); NotifySignalrIfNeed(mailbox, taskLogger); } catch (Exception ex) { taskLogger.ErrorFormat( "ProcessMailbox(Tenant = {0}, MailboxId = {1}, Address = '{2}')\r\nException: {3}\r\n", mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, ex is ImapProtocolException || ex is Pop3ProtocolException ? ex.Message : ex.ToString()); failed = true; } finally { CloseMailClient(client, mailbox, _log); if (_tasksConfig.CollectStatistics && watch != null) { watch.Stop(); LogStat(PROCESS_MAILBOX, mailbox, watch.Elapsed, failed); } } var state = GetMailboxState(mailbox, taskLogger); switch (state) { case MailboxState.NoChanges: taskLogger.InfoFormat("MailBox with id={0} not changed.", mailbox.MailBoxId); break; case MailboxState.Disabled: taskLogger.InfoFormat("MailBox with id={0} is deactivated.", mailbox.MailBoxId); break; case MailboxState.Deleted: taskLogger.InfoFormat("MailBox with id={0} is removed.", mailbox.MailBoxId); try { taskLogger.InfoFormat("RemoveMailBox(id={0}) >> Try clear new data from removed mailbox", mailbox.MailBoxId); var engine = new EngineFactory(mailbox.TenantId, mailbox.UserId); engine.MailboxEngine.RemoveMailBox(mailbox); } catch (Exception exRem) { taskLogger.InfoFormat( "[REMOVE] ProcessMailbox->RemoveMailBox(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}", mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, exRem.Message); } break; case MailboxState.DateChanged: taskLogger.InfoFormat("MailBox with id={0}: beginDate was changed.", mailbox.MailBoxId); break; default: throw new ArgumentOutOfRangeException(); } taskLogger.InfoFormat("Mailbox '{0}' has been processed.", mailbox.EMail); }