示例#1
0
        public void SetCacheObject(string key, object value, double seconds)
        {
            key = PrefixTenantOnKey(key);
            var timeSpan = TimeSpan.FromSeconds(seconds);
            var options  = new MemoryCacheEntryOptions {
                AbsoluteExpirationRelativeToNow = timeSpan
            };

            _cacheTelemetry.Start();
            _cache.Set(key, value, options);
            _cacheTelemetry.End(CacheTelemetryNames.SetMemory, key);
            _cacheTelemetry.Start();
            try
            {
                var db         = _cacheConnection.GetDatabase();
                var serialized = JsonConvert.SerializeObject(value);
                db.StringSet(key, serialized, timeSpan, flags: CommandFlags.FireAndForget);
                _cacheTelemetry.End(CacheTelemetryNames.SetRedis, key);
            }
            catch (Exception exc)
            {
                _cacheTelemetry.End(CacheTelemetryNames.SetRedisError, key);
                _errorLog.Log(exc, ErrorSeverity.Information);
            }
        }
示例#2
0
        public async Task SendQueuedMessages(ISettingsManager settingsManager, ISmtpWrapper smtpWrapper, IQueuedEmailMessageRepository queuedEmailRepository, IEmailQueueRepository emailQueueRepository, IErrorLog errorLog)
        {
            if (!Monitor.TryEnter(SyncRoot))
            {
                return;
            }
            try
            {
                var messageGroup = new List <QueuedEmailMessage>();
                for (var i = 1; i <= settingsManager.Current.MailerQuantity; i++)
                {
                    var payload = await emailQueueRepository.Dequeue();

                    if (payload == null)
                    {
                        break;
                    }
                    if (payload.EmailQueuePayloadType != EmailQueuePayloadType.FullMessage)
                    {
                        throw new NotImplementedException($"EmailQueuePayloadType {payload.EmailQueuePayloadType} not implemented.");
                    }
                    var queuedMessage = await queuedEmailRepository.GetMessage(payload.MessageID);

                    if (queuedMessage == null)
                    {
                        break;
                    }
                    messageGroup.Add(queuedMessage);
                    await queuedEmailRepository.DeleteMessage(queuedMessage.MessageID);
                }
                Parallel.ForEach(messageGroup, message =>
                {
                    try
                    {
                        smtpWrapper.Send(message);
                    }
                    catch (Exception exc)
                    {
                        if (message == null)
                        {
                            errorLog.Log(exc, ErrorSeverity.Email, "There was no message for the MailWorker to send.");
                        }
                        else
                        {
                            errorLog.Log(exc, ErrorSeverity.Email, $"MessageID: {message.MessageID}, To: <{message.ToEmail}> {message.ToName}, Subject: {message.Subject}");
                        }
                    }
                });
            }
            catch (Exception exc)
            {
                errorLog.Log(exc, ErrorSeverity.Error);
            }
            finally
            {
                Monitor.Exit(SyncRoot);
            }
        }
        public void ProcessOneCalculation()
        {
            var nextItem = _awardCalcRepository.Dequeue();

            if (String.IsNullOrEmpty(nextItem.Key))
            {
                return;
            }
            var eventDefinition = _eventDefinitionService.GetEventDefinition(nextItem.Key);
            var user            = _userRepository.GetUser(nextItem.Value);

            if (eventDefinition == null)
            {
                _errorLog.Log(new Exception(String.Format("Event calculation attempt on nonexistent event \"{0}\"", nextItem.Key)), ErrorSeverity.Warning);
                return;
            }
            if (user == null)
            {
                _errorLog.Log(new Exception(String.Format("Event calculation attempt on nonexistent user {0}", nextItem.Value)), ErrorSeverity.Warning);
                return;
            }
            var associatedAwards = _awardDefinitionService.GetByEventDefinitionID(eventDefinition.EventDefinitionID);

            foreach (var award in associatedAwards)
            {
                if (award.IsSingleTimeAward)
                {
                    var isAwarded = _userAwardService.IsAwarded(user, award);
                    if (isAwarded)
                    {
                        continue;
                    }
                }
                var conditions    = _awardDefinitionService.GetConditions(award.AwardDefinitionID);
                var conditionsMet = 0;
                foreach (var condition in conditions)
                {
                    var eventCount = _pointLedgerRepository.GetEntryCount(user.UserID, condition.EventDefinitionID);
                    if (eventCount >= condition.EventCount)
                    {
                        conditionsMet++;
                    }
                }
                if (conditions.Count != 0 && conditionsMet == conditions.Count)
                {
                    _userAwardService.IssueAward(user, award);
                }
            }
        }
 public void SetCacheObject(string key, object value, double seconds)
 {
     if (value == null)
     {
         return;
     }
     try
     {
         var v = JsonConvert.SerializeObject(value, _jsonSerializerSettings);
         _cache.StringSet(key, v, new TimeSpan(0, 0, 0, (int)seconds));
     }
     catch (TimeoutException exc)
     {
         _errorLog.Log(exc, ErrorSeverity.Information);
     }
 }
        public void Execute(object sender)
        {
            var interval = GetInterval();

            if (interval != Interval)
            {
                Interval = interval;
                Timer.Change(0, interval);
            }
            if (IsRunning)
            {
                var isError = false;
                try
                {
                    LastExecutionTime = DateTime.UtcNow;
                    ServiceAction();
                }
                catch (Exception exc)
                {
                    isError = true;
                    _errorCount++;
                    ErrorLog.Log(exc, ErrorSeverity.Error);
                    ExceptionMessage = exc.Message + "\r\n" + exc.StackTrace;
                }
                if (isError && _errorCount >= 10)
                {
                    Stop();
                }
                else if (!isError)
                {
                    _errorCount      = 0;
                    ExceptionMessage = String.Empty;
                }
            }
        }
        public SmtpStatusCode Send(MailMessage message)
        {
            message.Headers.Add("X-Mailer", "POP Forums v9");
            SmtpStatusCode result;
            var            settings = _settingsManager.Current;
            var            client   = new SmtpClient(settings.SmtpServer, settings.SmtpPort)
            {
                EnableSsl = settings.UseSslSmtp
            };

            if (settings.UseEsmtp)
            {
                client.Credentials = new NetworkCredential(settings.SmtpUser, settings.SmtpPassword);
            }
            try
            {
                client.Send(message);
                result = SmtpStatusCode.Ok;
            }
            catch (SmtpException exc)
            {
                result = exc.StatusCode;
                _errorLog.Log(exc, ErrorSeverity.Email, String.Format("To: {0}, Subject: {1}", message.To[0].Address, message.Subject));
            }
            finally
            {
                client.Dispose();
            }
            return(result);
        }
示例#7
0
 public void IndexNextTopic(IErrorLog errorLog, ISearchIndexSubsystem searchIndexSubsystem, ISearchService searchService, ITenantService tenantService)
 {
     if (!Monitor.TryEnter(_syncRoot, 5000))
     {
         return;
     }
     try
     {
         var topicID = searchService.GetNextTopicIDForIndexing().Result;
         if (topicID == 0)
         {
             return;
         }
         var tenantID = tenantService.GetTenant();
         searchIndexSubsystem.DoIndex(topicID, tenantID);
     }
     catch (Exception exc)
     {
         errorLog.Log(exc, ErrorSeverity.Error);
     }
     finally
     {
         Monitor.Exit(_syncRoot);
     }
 }
        public async Task ProcessCalculation(string eventDefinitionID, int userID)
        {
            var eventDefinition = await _eventDefinitionService.GetEventDefinition(eventDefinitionID);

            var user = await _userRepository.GetUser(userID);

            if (eventDefinition == null)
            {
                _errorLog.Log(new Exception($"Event calculation attempt on nonexistent event \"{eventDefinitionID}\""), ErrorSeverity.Warning);
                return;
            }
            if (user == null)
            {
                _errorLog.Log(new Exception($"Event calculation attempt on nonexistent user {userID}"), ErrorSeverity.Warning);
                return;
            }
            var associatedAwards = await _awardDefinitionService.GetByEventDefinitionID(eventDefinition.EventDefinitionID);

            foreach (var award in associatedAwards)
            {
                if (award.IsSingleTimeAward)
                {
                    var isAwarded = await _userAwardService.IsAwarded(user, award);

                    if (isAwarded)
                    {
                        continue;
                    }
                }
                var conditions = await _awardDefinitionService.GetConditions(award.AwardDefinitionID);

                var conditionsMet = 0;
                foreach (var condition in conditions)
                {
                    var eventCount = await _pointLedgerRepository.GetEntryCount(user.UserID, condition.EventDefinitionID);

                    if (eventCount >= condition.EventCount)
                    {
                        conditionsMet++;
                    }
                }
                if (conditions.Count != 0 && conditionsMet == conditions.Count)
                {
                    await _userAwardService.IssueAward(user, award);
                }
            }
        }
示例#9
0
 public void SendQueuedMessages(ISettingsManager settingsManager, ISmtpWrapper smtpWrapper, IQueuedEmailMessageRepository queuedEmailRepository, IErrorLog errorLog)
 {
     if (!Monitor.TryEnter(_syncRoot))
     {
         return;
     }
     try
     {
         var messageGroup = new List <QueuedEmailMessage>();
         for (var i = 1; i <= settingsManager.Current.MailerQuantity; i++)
         {
             var queuedMessage = queuedEmailRepository.GetOldestQueuedEmailMessage();
             if (queuedMessage == null)
             {
                 break;
             }
             messageGroup.Add(queuedMessage);
             queuedEmailRepository.DeleteMessage(queuedMessage.MessageID);
         }
         Parallel.ForEach(messageGroup, message =>
         {
             try
             {
                 smtpWrapper.Send(message);
             }
             catch (Exception exc)
             {
                 if (message == null)
                 {
                     errorLog.Log(exc, ErrorSeverity.Email, "There was no message for the MailWorker to send.");
                 }
                 else
                 {
                     errorLog.Log(exc, ErrorSeverity.Email, String.Format("MessageID: {0}, To: <{1}> {2}, Subject: {3}", message.MessageID, message.ToEmail, message.ToName, message.Subject));
                 }
             }
         });
     }
     catch (Exception exc)
     {
         errorLog.Log(exc, ErrorSeverity.Error);
     }
     finally
     {
         Monitor.Exit(_syncRoot);
     }
 }
示例#10
0
        public Response <IEnumerable <int> > SearchTopicsWithIDs(string searchTerm, List <int> hiddenForums, SearchType searchType, int startRow, int pageSize, out int topicCount)
        {
            Func <SortDescriptor <SearchTopic>, IPromise <IList <ISort> > > sortSelector;

            switch (searchType)
            {
            case SearchType.Date:
                sortSelector = sort => sort.Descending(d => d.LastPostTime);
                break;

            case SearchType.Name:
                sortSelector = sort => sort.Ascending(d => d.StartedByName).Descending(SortSpecialField.Score);
                break;

            case SearchType.Replies:
                sortSelector = sort => sort.Descending(d => d.Replies);
                break;

            case SearchType.Title:
                sortSelector = sort => sort.Ascending(d => d.Title);
                break;

            default:
                sortSelector = sort => sort.Descending(SortSpecialField.Score);
                break;
            }

            var tenantID = _tenantService.GetTenant();

            startRow--;
            var searchResponse = _client.Search <SearchTopic>(s => s
                                                              .Source(sf => sf.Includes(i => i.Fields(f => f.Id)))
                                                              .Query(q =>
                                                                     !q.Terms(set => set.Field(field => field.ForumID).Terms(hiddenForums)) &&
                                                                     q.Bool(bb => bb.Must(tt => tt.Term(ff => ff.TenantID, tenantID))) &&
                                                                     q.MultiMatch(m => m.Query(searchTerm)
                                                                                  .Fields(f => f
                                                                                          .Field(x => x.Title, boost: 5)
                                                                                          .Field(x => x.FirstPost, boost: 2)
                                                                                          .Field(x => x.Posts))))
                                                              .Sort(sortSelector)
                                                              .Take(pageSize)
                                                              .Skip(startRow));
            Response <IEnumerable <int> > result;

            if (!searchResponse.IsValid)
            {
                _errorLog.Log(searchResponse.OriginalException, ErrorSeverity.Error, $"Debugging info: {searchResponse.DebugInformation}");
                result     = new Response <IEnumerable <int> >(null, false, searchResponse.OriginalException, searchResponse.DebugInformation);
                topicCount = 0;
                return(result);
            }
            var ids = searchResponse.Documents.Select(d => Convert.ToInt32(d.Id));

            topicCount = (int)searchResponse.Total;
            result     = new Response <IEnumerable <int> >(ids);
            return(result);
        }
示例#11
0
        public void SetCacheObject(string key, object value, double seconds)
        {
            var timeSpan = TimeSpan.FromSeconds(seconds);
            var options  = new MemoryCacheEntryOptions {
                AbsoluteExpirationRelativeToNow = timeSpan
            };

            _cache.Set(key, value, options);
            try
            {
                var db         = _cacheConnection.GetDatabase();
                var serialized = JsonConvert.SerializeObject(value);
                db.StringSet(key, serialized, timeSpan, flags: CommandFlags.FireAndForget);
            }
            catch (Exception exc)
            {
                _errorLog.Log(exc, ErrorSeverity.Error);
            }
        }
        public void DoIndex(ISearchService searchService, ISettingsManager settingsManager, IPostService postService,
                            IConfig config, ITopicService topicService, IErrorLog errorLog)
        {
            var topic = searchService.GetNextTopicForIndexing();

            if (topic != null)
            {
                var serviceClient = new SearchServiceClient(config.SearchUrl, new SearchCredentials(config.SearchKey));
                if (!serviceClient.Indexes.Exists(IndexName))
                {
                    CreateIndex(serviceClient);
                }

                var posts       = postService.GetPosts(topic, false).ToArray();
                var parsedPosts = posts.Select(x =>
                {
                    var parsedText = _textParsingService.ClientHtmlToForumCode(x.FullText);
                    parsedText     = _textParsingService.RemoveForumCode(parsedText);
                    return(parsedText);
                }).ToArray();
                var searchTopic = new SearchTopic
                {
                    TopicID       = topic.TopicID.ToString(),
                    ForumID       = topic.ForumID,
                    Title         = topic.Title,
                    LastPostTime  = topic.LastPostTime,
                    StartedByName = topic.StartedByName,
                    Replies       = topic.ReplyCount,
                    Views         = topic.ViewCount,
                    IsClosed      = topic.IsClosed,
                    IsPinned      = topic.IsPinned,
                    UrlName       = topic.UrlName,
                    LastPostName  = topic.LastPostName,
                    Posts         = parsedPosts
                };

                var actions =
                    new IndexAction <SearchTopic>[]
                {
                    IndexAction.Upload(searchTopic)
                };
                try
                {
                    var serviceIndexClient = serviceClient.Indexes.GetClient(IndexName);
                    var batch = IndexBatch.New(actions);
                    serviceIndexClient.Documents.Index(batch);
                    searchService.MarkTopicAsIndexed(topic);
                }
                catch (Exception exc)
                {
                    errorLog.Log(exc, ErrorSeverity.Error);
                    topicService.MarkTopicForIndexing(topic.TopicID);
                }
            }
        }
示例#13
0
        public void DoIndex(int topicID, string tenantID)
        {
            var topic = _topicService.Get(topicID);

            if (topic != null)
            {
                var serviceClient = new SearchServiceClient(_config.SearchUrl, new SearchCredentials(_config.SearchKey));
                if (!serviceClient.Indexes.Exists(IndexName))
                {
                    CreateIndex(serviceClient);
                }

                var posts       = _postService.GetPosts(topic, false).ToArray();
                var parsedPosts = posts.Select(x =>
                {
                    var parsedText = _textParsingService.ClientHtmlToForumCode(x.FullText);
                    parsedText     = _textParsingService.RemoveForumCode(parsedText);
                    return(parsedText);
                }).ToArray();
                var searchTopic = new SearchTopic
                {
                    TopicID       = topic.TopicID.ToString(),
                    ForumID       = topic.ForumID,
                    Title         = topic.Title,
                    LastPostTime  = topic.LastPostTime,
                    StartedByName = topic.StartedByName,
                    Replies       = topic.ReplyCount,
                    Views         = topic.ViewCount,
                    IsClosed      = topic.IsClosed,
                    IsPinned      = topic.IsPinned,
                    UrlName       = topic.UrlName,
                    LastPostName  = topic.LastPostName,
                    Posts         = parsedPosts,
                    TenantID      = tenantID
                };

                var actions =
                    new[]
                {
                    IndexAction.Upload(searchTopic)
                };
                try
                {
                    var serviceIndexClient = serviceClient.Indexes.GetClient(IndexName);
                    var batch = IndexBatch.New(actions);
                    serviceIndexClient.Documents.Index(batch);
                }
                catch (Exception exc)
                {
                    _errorLog.Log(exc, ErrorSeverity.Error);
                    _topicService.QueueTopicForIndexing(topic.TopicID);
                }
            }
        }
示例#14
0
		public void SendQueuedMessages(ISettingsManager settingsManager, ISmtpWrapper smtpWrapper, IQueuedEmailMessageRepository queuedEmailRepository, IErrorLog errorLog)
		{
			if (!Monitor.TryEnter(_syncRoot))
			{
				return;
			}
			try
			{
				var messageGroup = new List<QueuedEmailMessage>();
				for (var i = 1; i <= settingsManager.Current.MailerQuantity; i++)
				{
					var queuedMessage = queuedEmailRepository.GetOldestQueuedEmailMessage();
					if (queuedMessage == null)
						break;
					messageGroup.Add(queuedMessage);
					queuedEmailRepository.DeleteMessage(queuedMessage.MessageID);
				}
				Parallel.ForEach(messageGroup, message =>
				{
					try
					{
						smtpWrapper.Send(message);
					}
					catch (Exception exc)
					{
						if (message == null)
							errorLog.Log(exc, ErrorSeverity.Email, "There was no message for the MailWorker to send.");
						else
							errorLog.Log(exc, ErrorSeverity.Email, String.Format("MessageID: {0}, To: <{1}> {2}, Subject: {3}", message.MessageID, message.ToEmail, message.ToName, message.Subject));
					}
				});
			}
			catch (Exception exc)
			{
				errorLog.Log(exc, ErrorSeverity.Error);
			}
			finally
			{
				Monitor.Exit(_syncRoot);
			}
		}
示例#15
0
        public SmtpStatusCode?Send(EmailMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            var            parsedMessage = ConvertEmailMessage(message);
            var            settings      = _settingsManager.Current;
            SmtpStatusCode?result        = SmtpStatusCode.Ok;

            using (var client = new SmtpClient())
            {
                client.Connect(settings.SmtpServer, settings.SmtpPort, settings.UseSslSmtp ? SecureSocketOptions.StartTls : SecureSocketOptions.None);
                if (settings.UseEsmtp)
                {
                    client.Authenticate(settings.SmtpUser, settings.SmtpPassword);
                }
                try
                {
                    client.Send(parsedMessage);
                }
                catch (SmtpCommandException exc)
                {
                    var statusCode = (int)exc.StatusCode;
                    result = (SmtpStatusCode)statusCode;
                    _errorLog.Log(exc, ErrorSeverity.Email, String.Format("To: {0}, Subject: {1}", message.ToEmail, message.Subject));
                }
                catch (Exception exc)
                {
                    result = null;
                    _errorLog.Log(exc, ErrorSeverity.Email, String.Format("To: {0}, Subject: {1}", message.ToEmail, message.Subject));
                }
                finally
                {
                    client.Disconnect(true);
                }
            }
            return(result);
        }
		public void ProcessCalculation(IAwardCalculator calculator, IErrorLog errorLog)
		{
			if (!Monitor.TryEnter(_syncRoot)) return;
			try
			{
				calculator.ProcessOneCalculation();
			}
			catch (Exception exc)
			{
				errorLog.Log(exc, ErrorSeverity.Error);
			}
			finally
			{
				Monitor.Exit(_syncRoot);
			}
		}
示例#17
0
		public void IndexNextTopic(ISearchService searchService, ISettingsManager settingsManager, IPostService postService, IErrorLog errorLog)
		{
			if (!Monitor.TryEnter(_syncRoot)) return;
			try
			{
				DoIndex(searchService, settingsManager, postService);
			}
			catch (Exception exc)
			{
				errorLog.Log(exc, ErrorSeverity.Error);
			}
			finally
			{
				Monitor.Exit(_syncRoot);
			}
		}
		public void CleanUpExpiredSessions(IUserSessionService sessionService, IErrorLog errorLog)
		{
			if (!Monitor.TryEnter(_syncRoot)) return;
			try
			{
				sessionService.CleanUpExpiredSessions();
			}
			catch (Exception exc)
			{
				errorLog.Log(exc, ErrorSeverity.Error);
			}
			finally
			{
				Monitor.Exit(_syncRoot);
			}
		}
示例#19
0
        public async Task ProcessCalculation(IAwardCalculator calculator, IAwardCalculationQueueRepository awardCalculationQueueRepository, IErrorLog errorLog)
        {
            try
            {
                var nextItem = await awardCalculationQueueRepository.Dequeue();

                if (string.IsNullOrEmpty(nextItem.Key))
                {
                    return;
                }
                await calculator.ProcessCalculation(nextItem.Key, nextItem.Value);
            }
            catch (Exception exc)
            {
                errorLog.Log(exc, ErrorSeverity.Error);
            }
        }
示例#20
0
        private void LoadSettings()
        {
            var dictionary = _settingsRepository.Get();
            var settings   = new Settings();

            foreach (var setting in dictionary.Keys)
            {
                var property = settings.GetType().GetProperty(setting);
                if (property == null)
                {
                    _errorLog.Log(null, ErrorSeverity.Warning, String.Format("Settings repository returned a setting called {0}, which does not exist in code.", setting));
                }
                else
                {
                    switch (property.PropertyType.FullName)
                    {
                    case "System.Boolean":
                        property.SetValue(settings, Convert.ToBoolean(dictionary[setting]), null);
                        break;

                    case "System.String":
                        property.SetValue(settings, dictionary[setting], null);
                        break;

                    case "System.Int32":
                        property.SetValue(settings, Convert.ToInt32(dictionary[setting]), null);
                        break;

                    case "System.Double":
                        property.SetValue(settings, Convert.ToDouble(dictionary[setting]), null);
                        break;

                    case "System.DateTime":
                        property.SetValue(settings, Convert.ToDateTime(dictionary[setting]), null);
                        break;

                    default:
                        throw new Exception(String.Format("Settings loader not coded to convert values of type {0}", property.PropertyType.FullName));
                    }
                }
            }

            _settings = settings;
            _lastLoad = DateTime.UtcNow;
        }
示例#21
0
 public void IndexNextTopic(ISearchService searchService, ISettingsManager settingsManager, IPostService postService, IErrorLog errorLog, ISearchIndexSubsystem searchIndexSubsystem, IConfig config, ITopicService topicService)
 {
     if (!Monitor.TryEnter(_syncRoot))
     {
         return;
     }
     try
     {
         searchIndexSubsystem.DoIndex(searchService, settingsManager, postService, config, topicService, errorLog);
     }
     catch (Exception exc)
     {
         errorLog.Log(exc, ErrorSeverity.Error);
     }
     finally
     {
         Monitor.Exit(_syncRoot);
     }
 }
示例#22
0
 public void ProcessCalculation(IAwardCalculator calculator, IErrorLog errorLog)
 {
     if (!Monitor.TryEnter(_syncRoot))
     {
         return;
     }
     try
     {
         calculator.ProcessOneCalculation();
     }
     catch (Exception exc)
     {
         errorLog.Log(exc, ErrorSeverity.Error);
     }
     finally
     {
         Monitor.Exit(_syncRoot);
     }
 }
示例#23
0
 public void IndexNextTopic(ISearchService searchService, ISettingsManager settingsManager, IPostService postService, IErrorLog errorLog)
 {
     if (!Monitor.TryEnter(_syncRoot))
     {
         return;
     }
     try
     {
         DoIndex(searchService, settingsManager, postService);
     }
     catch (Exception exc)
     {
         errorLog.Log(exc, ErrorSeverity.Error);
     }
     finally
     {
         Monitor.Exit(_syncRoot);
     }
 }
示例#24
0
 public void CloseOldTopics(ITopicService topicService, IErrorLog errorLog)
 {
     if (!Monitor.TryEnter(_syncRoot))
     {
         return;
     }
     try
     {
         topicService.CloseAgedTopics();
     }
     catch (Exception exc)
     {
         errorLog.Log(exc, ErrorSeverity.Error);
     }
     finally
     {
         Monitor.Exit(_syncRoot);
     }
 }
示例#25
0
 public void MailUsers(string subject, string body, string htmlBody, Func <User, string> unsubscribeLinkGenerator)
 {
     _mailWorker = new Thread(() =>
     {
         var users = _userService.GetSubscribedUsers();
         foreach (var user in users)
         {
             var unsubLink = unsubscribeLinkGenerator(user);
             try
             {
                 _mailingListComposer.ComposeAndQueue(user, subject, body, htmlBody, unsubLink);
             }
             catch (Exception exc)
             {
                 _errorLog.Log(exc, ErrorSeverity.Error, "UserID: " + user.UserID);
             }
         }
     });
     _mailWorker.Start();
 }
示例#26
0
 public void ProcessCalculation(IAwardCalculator calculator, IAwardCalculationQueueRepository awardCalculationQueueRepository, IErrorLog errorLog)
 {
     if (!Monitor.TryEnter(_syncRoot))
     {
         return;
     }
     try
     {
         var nextItem = awardCalculationQueueRepository.Dequeue();
         if (string.IsNullOrEmpty(nextItem.Key))
         {
             return;
         }
         calculator.ProcessCalculation(nextItem.Key, nextItem.Value);
     }
     catch (Exception exc)
     {
         errorLog.Log(exc, ErrorSeverity.Error);
     }
     finally
     {
         Monitor.Exit(_syncRoot);
     }
 }
示例#27
0
        public async Task <Tuple <Response <List <Topic> >, PagerContext> > GetTopics(string searchTerm, SearchType searchType, User user, bool includeDeleted, int pageIndex)
        {
            var nonViewableForumIDs = await _forumService.GetNonViewableForumIDs(user);

            var pageSize   = _settingsManager.Current.TopicsPerPage;
            var startRow   = ((pageIndex - 1) * pageSize) + 1;
            var topicCount = 0;
            Response <List <Topic> > topics;
            PagerContext             pagerContext;

            if (string.IsNullOrEmpty(searchTerm))
            {
                topics = new Response <List <Topic> >(new List <Topic>(), true);
            }
            else
            {
                (topics, topicCount) = await _searchRepository.SearchTopics(searchTerm, nonViewableForumIDs, searchType, startRow, pageSize);
            }
            if (topics.IsValid)
            {
                var totalPages = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(topicCount) / Convert.ToDouble(pageSize)));
                pagerContext = new PagerContext {
                    PageCount = totalPages, PageIndex = pageIndex, PageSize = pageSize
                };
            }
            else
            {
                topics       = new Response <List <Topic> >(new List <Topic>(), false);
                pagerContext = new PagerContext {
                    PageCount = 1, PageIndex = 1, PageSize = 1
                };
                var exc = new Exception($"Search service error: {topics.Exception?.Message}");
                _errorLog.Log(exc, ErrorSeverity.Warning, topics.DebugInfo);
            }
            return(Tuple.Create(topics, pagerContext));
        }
 public void IndexNextTopic(IErrorLog errorLog, ISearchIndexSubsystem searchIndexSubsystem, ISearchService searchService, ITenantService tenantService)
 {
     if (!Monitor.TryEnter(_syncRoot, 5000))
     {
         return;
     }
     try
     {
         var payload = searchService.GetNextTopicForIndexing().Result;
         if (payload == null)
         {
             return;
         }
         searchIndexSubsystem.DoIndex(payload.TopicID, payload.TenantID, payload.IsForRemoval);
     }
     catch (Exception exc)
     {
         errorLog.Log(exc, ErrorSeverity.Error);
     }
     finally
     {
         Monitor.Exit(_syncRoot);
     }
 }
        public void DoIndex(int topicID, string tenantID, bool isForRemoval)
        {
            if (isForRemoval)
            {
                RemoveIndex(topicID, tenantID);
                return;
            }

            var topic = _topicService.Get(topicID).Result;

            if (topic == null)
            {
                return;
            }

            _elasticSearchClientWrapper.VerifyIndexCreate();

            var posts = _postService.GetPosts(topic, false).Result;

            if (posts.Count == 0)
            {
                throw new Exception($"TopicID {topic.TopicID} has no posts to index.");
            }
            var firstPost = _textParsingService.ClientHtmlToForumCode(posts[0].FullText);

            firstPost = _textParsingService.RemoveForumCode(firstPost);
            posts.RemoveAt(0);
            var parsedPosts = posts.Select(x =>
            {
                var parsedText = _textParsingService.ClientHtmlToForumCode(x.FullText);
                parsedText     = _textParsingService.RemoveForumCode(parsedText);
                return(parsedText);
            }).ToArray();
            var searchTopic = new SearchTopic
            {
                Id            = $"{tenantID}-{topic.TopicID}",
                TopicID       = topic.TopicID,
                ForumID       = topic.ForumID,
                Title         = topic.Title,
                LastPostTime  = topic.LastPostTime,
                StartedByName = topic.StartedByName,
                Replies       = topic.ReplyCount,
                Views         = topic.ViewCount,
                IsClosed      = topic.IsClosed,
                IsPinned      = topic.IsPinned,
                UrlName       = topic.UrlName,
                LastPostName  = topic.LastPostName,
                FirstPost     = firstPost,
                Posts         = parsedPosts,
                TenantID      = tenantID
            };

            try
            {
                var policy = Polly.Policy.HandleResult <IndexResponse>(x => !x.IsValid)
                             .WaitAndRetry(new[]
                {
                    TimeSpan.FromSeconds(1),
                    TimeSpan.FromSeconds(5),
                    TimeSpan.FromSeconds(30)
                }, (exception, timeSpan) => {
                    _errorLog.Log(exception.Result.OriginalException, ErrorSeverity.Error, $"Retry after {timeSpan.Seconds}: {exception.Result.DebugInformation}");
                });
                policy.Execute(() =>
                {
                    var indexResult = _elasticSearchClientWrapper.IndexTopic(searchTopic);
                    return(indexResult);
                });
            }
            catch (Exception exc)
            {
                _errorLog.Log(exc, ErrorSeverity.Error);
            }
        }
示例#30
0
        public override List <Topic> SearchTopics(string searchTerm, List <int> hiddenForums, SearchType searchType, int startRow, int pageSize, out int topicCount)
        {
            var serviceIndexClient = new SearchIndexClient(_config.SearchUrl, SearchIndexSubsystem.IndexName, new SearchCredentials(_config.SearchKey));

            try
            {
                var parameters = new SearchParameters();
                switch (searchType)
                {
                case SearchType.Date:
                    parameters.OrderBy = new List <string> {
                        "lastPostTime desc"
                    };
                    break;

                case SearchType.Name:
                    parameters.OrderBy = new List <string> {
                        "startedByName"
                    };
                    break;

                case SearchType.Replies:
                    parameters.OrderBy = new List <string> {
                        "replies desc"
                    };
                    break;

                case SearchType.Title:
                    parameters.OrderBy = new List <string> {
                        "title"
                    };
                    break;

                default:
                    break;
                }
                if (startRow > 1)
                {
                    parameters.Skip = startRow - 1;
                }
                parameters.Top = pageSize;
                if (hiddenForums != null && hiddenForums.Any())
                {
                    var neConditions = hiddenForums.Select(x => "forumID ne " + x);
                    parameters.Filter = string.Join(" and ", neConditions);
                }
                parameters.IncludeTotalResultCount = true;
                parameters.Select = new [] { "topicID" };
                var result   = serviceIndexClient.Documents.Search <SearchTopic>(searchTerm, parameters);
                var topicIDs = result.Results.Select(x => Convert.ToInt32(x.Document.TopicID));
                var topics   = _topicRepository.Get(topicIDs);
                topicCount = Convert.ToInt32(result.Count);
                return(topics);
            }
            catch (CloudException cloudException)
            {
                _errorLog.Log(cloudException, ErrorSeverity.Error);
                topicCount = 0;
                return(new List <Topic>());
            }
        }
示例#31
0
        public void DoIndex(int topicID, string tenantID)
        {
            var topic = _topicService.Get(topicID).Result;

            if (topic == null)
            {
                return;
            }

            _elasticSearchClientWrapper.VerifyIndexCreate();

            var posts = _postService.GetPosts(topic, false).Result;

            if (posts.Count == 0)
            {
                throw new Exception($"TopicID {topic.TopicID} has no posts to index.");
            }
            var firstPost = _textParsingService.ClientHtmlToForumCode(posts[0].FullText);

            firstPost = _textParsingService.RemoveForumCode(firstPost);
            posts.RemoveAt(0);
            var parsedPosts = posts.Select(x =>
            {
                var parsedText = _textParsingService.ClientHtmlToForumCode(x.FullText);
                parsedText     = _textParsingService.RemoveForumCode(parsedText);
                return(parsedText);
            }).ToArray();
            var searchTopic = new SearchTopic
            {
                Id            = $"{tenantID}-{topic.TopicID}",
                TopicID       = topic.TopicID,
                ForumID       = topic.ForumID,
                Title         = topic.Title,
                LastPostTime  = topic.LastPostTime,
                StartedByName = topic.StartedByName,
                Replies       = topic.ReplyCount,
                Views         = topic.ViewCount,
                IsClosed      = topic.IsClosed,
                IsPinned      = topic.IsPinned,
                UrlName       = topic.UrlName,
                LastPostName  = topic.LastPostName,
                FirstPost     = firstPost,
                Posts         = parsedPosts,
                TenantID      = tenantID
            };

            try
            {
                var indexResult = _elasticSearchClientWrapper.IndexTopic(searchTopic);
                if (indexResult.Result != Result.Created && indexResult.Result != Result.Updated)
                {
                    _errorLog.Log(indexResult.OriginalException, ErrorSeverity.Error, $"Debug information: {indexResult.DebugInformation}");
                    // TODO: Replace this with some Polly or get real about queues/deadletter
                    _topicService.QueueTopicForIndexing(topic.TopicID);
                }
            }
            catch (Exception exc)
            {
                _errorLog.Log(exc, ErrorSeverity.Error);
                // TODO: Replace this with some Polly or get real about queues/deadletter
                _topicService.QueueTopicForIndexing(topic.TopicID);
            }
        }