private static MailboxState GetMailboxState(MailBoxData mailbox, ILog log) { try { log.Debug("GetMailBoxState()"); var engine = new EngineFactory(-1); var status = engine.MailboxEngine.GetMailboxStatus(new СoncreteUserMailboxExp(mailbox.MailBoxId, mailbox.TenantId, mailbox.UserId)); if (mailbox.BeginDate != status.BeginDate) { mailbox.BeginDateChanged = true; mailbox.BeginDate = status.BeginDate; return(MailboxState.DateChanged); } if (status.IsRemoved) { return(MailboxState.Deleted); } if (!status.Enabled) { return(MailboxState.Disabled); } } catch (Exception exGetMbInfo) { log.InfoFormat("GetMailBoxState(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}", mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, exGetMbInfo.Message); } return(MailboxState.NoChanges); }
private void NotifySignalrIfNeed(MailBoxData mailbox, ILog log) { if (!_tasksConfig.EnableSignalr) { log.Debug("Skip NotifySignalrIfNeed: EnableSignalr == false"); return; } var now = DateTime.UtcNow; try { if (mailbox.LastSignalrNotify.HasValue && !((now - mailbox.LastSignalrNotify.Value).TotalSeconds > SIGNALR_WAIT_SECONDS)) { mailbox.LastSignalrNotifySkipped = true; log.InfoFormat( "Skip NotifySignalrIfNeed: last notification has occurend less then {0} seconds ago", SIGNALR_WAIT_SECONDS); return; } if (_signalrWorker == null) { throw new NullReferenceException("_signalrWorker"); } _signalrWorker.AddMailbox(mailbox); log.InfoFormat("NotifySignalrIfNeed(UserId = {0} TenantId = {1}) has been succeeded", mailbox.UserId, mailbox.TenantId); } catch (Exception ex) { log.ErrorFormat("NotifySignalrIfNeed(UserId = {0} TenantId = {1}) Exception: {2}", mailbox.UserId, mailbox.TenantId, ex.ToString()); } mailbox.LastSignalrNotify = now; mailbox.LastSignalrNotifySkipped = false; }
private void DoOptionalOperations(MailMessageData message, MimeMessage mimeMessage, MailBoxData mailbox, MailFolder folder, ILog log) { var factory = new EngineFactory(mailbox.TenantId, mailbox.UserId, log); var tagIds = new List <int>(); if (folder.Tags.Any()) { log.Debug("DoOptionalOperations->GetOrCreateTags()"); tagIds = factory.TagEngine.GetOrCreateTags(mailbox.TenantId, mailbox.UserId, folder.Tags); } log.Debug("DoOptionalOperations->IsCrmAvailable()"); if (IsCrmAvailable(mailbox, log)) { log.Debug("DoOptionalOperations->GetCrmTags()"); var crmTagIds = factory.TagEngine.GetCrmTags(message.FromEmail); if (crmTagIds.Any()) { if (tagIds == null) { tagIds = new List <int>(); } tagIds.AddRange(crmTagIds.Select(t => t.Id)); } } if (tagIds.Any()) { if (message.TagIds == null || !message.TagIds.Any()) { message.TagIds = tagIds; } else { message.TagIds.AddRange(tagIds); } message.TagIds = message.TagIds.Distinct().ToList(); } log.Debug("DoOptionalOperations->AddMessageToIndex()"); var wrapper = message.ToMailWrapper(mailbox.TenantId, new Guid(mailbox.UserId)); factory.IndexEngine.Add(wrapper); foreach (var tagId in tagIds) { try { log.DebugFormat("DoOptionalOperations->SetMessagesTag(tagId: {0})", tagId); factory.TagEngine.SetMessagesTag(new List <int> { message.Id }, tagId); } catch (Exception e) { log.ErrorFormat( "SetMessagesTag(tenant={0}, userId='{1}', messageId={2}, tagid = {3}) Exception:\r\n{4}\r\n", mailbox.TenantId, mailbox.UserId, message.Id, e.ToString(), tagIds != null ? string.Join(",", tagIds) : "null"); } } log.Debug("DoOptionalOperations->AddRelationshipEventForLinkedAccounts()"); factory.CrmLinkEngine.AddRelationshipEventForLinkedAccounts(mailbox, message, _tasksConfig.DefaultApiSchema); log.Debug("DoOptionalOperations->SaveEmailInData()"); factory.EmailInEngine.SaveEmailInData(mailbox, message, _tasksConfig.DefaultApiSchema); log.Debug("DoOptionalOperations->SendAutoreply()"); factory.AutoreplyEngine.SendAutoreply(mailbox, message, _tasksConfig.DefaultApiSchema, log); log.Debug("DoOptionalOperations->UploadIcsToCalendar()"); factory .CalendarEngine .UploadIcsToCalendar(mailbox, message.CalendarId, message.CalendarUid, message.CalendarEventIcs, message.CalendarEventCharset, message.CalendarEventMimeType, mailbox.EMail.Address, _tasksConfig.DefaultApiSchema); if (_tasksConfig.SaveOriginalMessage) { log.Debug("DoOptionalOperations->StoreMailEml()"); StoreMailEml(mailbox.TenantId, mailbox.UserId, message.StreamId, mimeMessage, log); } log.Debug("DoOptionalOperations->ApplyFilters()"); var filters = GetFilters(factory, log); factory.FilterEngine.ApplyFilters(message, mailbox, folder, filters); log.Debug("DoOptionalOperations->NotifySignalrIfNeed()"); NotifySignalrIfNeed(mailbox, log); }
private void workTimer_Elapsed(object state) { _log.Debug("Timer->workTimer_Elapsed"); var cancelToken = state as CancellationToken? ?? new CancellationToken(); try { if (_isFirstTime) { _queueManager.LoadMailboxesFromDump(); if (_queueManager.ProcessingCount > 0) { _log.InfoFormat("Found {0} tasks to release", _queueManager.ProcessingCount); _queueManager.ReleaseAllProcessingMailboxes(); } _queueManager.LoadTenantsFromDump(); _isFirstTime = false; } if (cancelToken.IsCancellationRequested) { _log.Debug("Timer->workTimer_Elapsed: IsCancellationRequested. Quit."); return; } if (_workTimer == null) { _log.Debug("Timer->workTimer_Elapsed: _workTimer == null. Quit."); OnStop(); return; } StopTimer(); var tasks = CreateTasks(_tasksConfig.MaxTasksAtOnce, cancelToken); // ***Add a loop to process the tasks one at a time until none remain. while (tasks.Any()) { // Identify the first task that completes. var indexTask = Task.WaitAny(tasks.Select(t => t.Task).ToArray(), (int)_tsTaskStateCheckInterval.TotalMilliseconds, cancelToken); if (indexTask > -1) { // ***Remove the selected task from the list so that you don't // process it more than once. var outTask = tasks[indexTask]; FreeTask(outTask, tasks); } else { _log.InfoFormat("Task.WaitAny timeout. Tasks count = {0}\r\nTasks:\r\n{1}", tasks.Count, string.Join("\r\n", tasks.Select( t => string.Format("Id: {0} Status: {1}, MailboxId: {2} Address: '{3}'", t.Task.Id, t.Task.Status, t.Mailbox.MailBoxId, t.Mailbox.EMail)))); } var tasks2Free = tasks.Where( t => t.Task.Status == TaskStatus.Canceled || t.Task.Status == TaskStatus.Faulted || t.Task.Status == TaskStatus.RanToCompletion).ToList(); if (tasks2Free.Any()) { _log.InfoFormat("Need free next tasks = {0}: ({1})", tasks2Free.Count, string.Join(",", tasks2Free.Select(t => t.Task.Id.ToString(CultureInfo.InvariantCulture)))); tasks2Free.ForEach(task => FreeTask(task, tasks)); } var difference = _tasksConfig.MaxTasksAtOnce - tasks.Count; if (difference <= 0) { continue; } var newTasks = CreateTasks(difference, cancelToken); tasks.AddRange(newTasks); _log.InfoFormat("Total tasks count = {0} ({1}).", tasks.Count, string.Join(",", tasks.Select(t => t.Task.Id))); } _log.Info("All mailboxes were processed. Go back to timer."); } catch (Exception ex) { if (ex is AggregateException) { ex = ((AggregateException)ex).GetBaseException(); } if (ex is TaskCanceledException || ex is OperationCanceledException) { _log.Info("Execution was canceled."); _queueManager.ReleaseAllProcessingMailboxes(); _queueManager.CancelHandler.Set(); return; } _log.ErrorFormat("Timer->workTimer_Elapsed. Exception:\r\n{0}\r\n", ex.ToString()); if (_queueManager.ProcessingCount != 0) { _queueManager.ReleaseAllProcessingMailboxes(); } } _queueManager.CancelHandler.Set(); StartTimer(); }