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);
        }
Beispiel #2
0
        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());
            }
        }
Beispiel #3
0
        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);
        }