Skip to content

DNN-21973: retry the search when there have exception throw during search process. #2198

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ internal static class Constants
internal const string SearchLastSuccessIndexName = "Search_LastSuccessfulIndexedOn";
internal const string SearchOptimizeFlagName = "Search_OptimizeIndex";
internal const string SearchCustomAnalyzer = "Search_CustomAnalyzer";
internal const string SearchRetryTimesKey = "Search_RetryTimes";

// misc.
internal const string TlsSearchInfo = "TLS_SEARCH_INFO";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ internal class LuceneControllerImpl : ILuceneController, IDisposable
private const string DefaultSearchFolder = @"App_Data\Search";
private const string WriteLockFile = "write.lock";
internal const int DefaultRereadTimeSpan = 30; // in seconds
private const int DefaultSearchRetryTimes = 5;
private const int DISPOSED = 1;
private const int UNDISPOSED = 0;
#endregion
Expand All @@ -74,6 +75,7 @@ internal class LuceneControllerImpl : ILuceneController, IDisposable
private FastVectorHighlighter _fastHighlighter;
private readonly object _writerLock = new object();
private readonly double _readerTimeSpan; // in seconds
private readonly int _searchRetryTimes; //search retry times if exception thrown during search process
private readonly List<CachedReader> _oldReaders = new List<CachedReader>();
private int _isDisposed = UNDISPOSED;

Expand All @@ -92,6 +94,7 @@ public LuceneControllerImpl()
if (string.IsNullOrEmpty(folder)) folder = DefaultSearchFolder;
IndexFolder = Path.Combine(Globals.ApplicationMapPath, folder);
_readerTimeSpan = hostController.GetDouble(Constants.SearchReaderRefreshTimeKey, DefaultRereadTimeSpan);
_searchRetryTimes = hostController.GetInteger(Constants.SearchRetryTimesKey, DefaultSearchRetryTimes);
}

private void CheckDisposed()
Expand Down Expand Up @@ -274,40 +277,61 @@ public LuceneResults Search(LuceneSearchContext searchContext)
var maxResults = searchContext.LuceneQuery.PageIndex * searchContext.LuceneQuery.PageSize;
var minResults = maxResults - searchContext.LuceneQuery.PageSize + 1;

var searcher = GetSearcher();
var searchSecurityTrimmer = new SearchSecurityTrimmer(new SearchSecurityTrimmerContext
{
Searcher = searcher,
SecurityChecker = searchContext.SecurityCheckerDelegate,
LuceneQuery = searchContext.LuceneQuery,
SearchQuery = searchContext.SearchQuery
});
searcher.Search(searchContext.LuceneQuery.Query, null, searchSecurityTrimmer);
luceneResults.TotalHits = searchSecurityTrimmer.TotalHits;

if (Logger.IsDebugEnabled)
for (var i = 0; i < _searchRetryTimes; i++)
{
var sb = GetSearcResultExplanation(searchContext.LuceneQuery, searchSecurityTrimmer.ScoreDocs, searcher);
Logger.Trace(sb);
}
try
{
var searcher = GetSearcher();
var searchSecurityTrimmer = new SearchSecurityTrimmer(new SearchSecurityTrimmerContext
{
Searcher = searcher,
SecurityChecker = searchContext.SecurityCheckerDelegate,
LuceneQuery = searchContext.LuceneQuery,
SearchQuery = searchContext.SearchQuery
});
searcher.Search(searchContext.LuceneQuery.Query, null, searchSecurityTrimmer);
luceneResults.TotalHits = searchSecurityTrimmer.TotalHits;

if (Logger.IsDebugEnabled)
{
var sb = GetSearcResultExplanation(searchContext.LuceneQuery, searchSecurityTrimmer.ScoreDocs, searcher);
Logger.Trace(sb);
}

//Page doesn't exist
if (luceneResults.TotalHits < minResults)
return luceneResults;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why increase the nesting depth with this change from a return if the total hits were less than mins?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not a new change in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zyhfish Yes, this is a change in this PR. You removed the old process which returned early, to an inversed logic that increases the IL nesting depth of the code

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's amusing that with the logical expression reversed the comment above is not incorrect :)

//Page doesn't exist
if (luceneResults.TotalHits < minResults)
break;

luceneResults.Results = searchSecurityTrimmer.ScoreDocs.Select(match =>
new LuceneResult
luceneResults.Results = searchSecurityTrimmer.ScoreDocs.Select(match =>
new LuceneResult
{
Document = searcher.Doc(match.Doc),
Score = match.Score,
DisplayScore = GetDisplayScoreFromMatch(match.ToString()),
TitleSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.TitleTag, searchContext.LuceneQuery.TitleSnippetLength),
BodySnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.BodyTag, searchContext.LuceneQuery.BodySnippetLength),
DescriptionSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.DescriptionTag, searchContext.LuceneQuery.TitleSnippetLength),
TagSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.Tag, searchContext.LuceneQuery.TitleSnippetLength),
AuthorSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.AuthorNameTag, searchContext.LuceneQuery.TitleSnippetLength),
ContentSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.ContentTag, searchContext.LuceneQuery.TitleSnippetLength)
}).ToList();
break;
}
catch (IOException ex)
{
DisposeReaders();

if (i == _searchRetryTimes - 1)
{
Document = searcher.Doc(match.Doc),
Score = match.Score,
DisplayScore = GetDisplayScoreFromMatch(match.ToString()),
TitleSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.TitleTag, searchContext.LuceneQuery.TitleSnippetLength),
BodySnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.BodyTag, searchContext.LuceneQuery.BodySnippetLength),
DescriptionSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.DescriptionTag, searchContext.LuceneQuery.TitleSnippetLength),
TagSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.Tag, searchContext.LuceneQuery.TitleSnippetLength),
AuthorSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.AuthorNameTag, searchContext.LuceneQuery.TitleSnippetLength),
ContentSnippet = GetHighlightedText(highlighter, fieldQuery, searcher, match, Constants.ContentTag, searchContext.LuceneQuery.TitleSnippetLength)
}).ToList();
throw;
}

Logger.Error(ex);
Logger.Error($"Search Index Folder Is Not Available: {ex.Message}, Retry {i + 1} time(s).");
Thread.Sleep(100);
}
}

return luceneResults;
}

Expand Down