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); } }
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); }
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); } } }
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); } }
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); }
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); } } }
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); } } }
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); } }
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); } }
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); } }
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); } }
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; }
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); } }
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); } }
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 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); } }
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(); }
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); } }
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); } }
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>()); } }
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); } }