Merge pull request #1640 from rmcrackan/rmcrackan/lucene-exp-backoff

Lucene search engine retries to use exponential backoff
This commit is contained in:
rmcrackan
2026-03-02 08:05:21 -05:00
committed by GitHub

View File

@@ -81,10 +81,12 @@ public class SearchEngine
public void CreateNewIndex(IEnumerable<LibraryBook> library, bool overwrite = true)
{
const int maxRetries = 5;
const int retryDelayMs = 400;
const int baseDelayMs = 400;
var libraryList = library.ToList();
for (var attempt = 0; attempt < maxRetries; attempt++)
// Exponential backoff retry: 400 ms, 800 ms, 1600 ms, etc
// Total wait time before giving up: 12.4 sec
for (var attempt = 0; attempt < maxRetries; attempt++)
{
try
{
@@ -93,15 +95,17 @@ public class SearchEngine
}
catch (IOException ex) when (attempt < maxRetries - 1)
{
var delayMs = baseDelayMs * (1 << attempt);
// write.lock can be held by another process (e.g. second Libation instance, antivirus) or a prior writer that did not release. Retry after delay.
Serilog.Log.Logger.Warning(ex, "Search index lock conflict (attempt {Attempt}/{Max}), retrying in {Delay}ms", attempt + 1, maxRetries, retryDelayMs);
Thread.Sleep(retryDelayMs);
Serilog.Log.Logger.Warning(ex, "Search index lock conflict (attempt {Attempt}/{Max}), retrying in {Delay}ms", attempt + 1, maxRetries, delayMs);
Thread.Sleep(delayMs);
}
catch (UnauthorizedAccessException ex) when (attempt < maxRetries - 1)
{
var delayMs = baseDelayMs * (1 << attempt);
// Windows may report "file in use" as UnauthorizedAccessException
Serilog.Log.Logger.Warning(ex, "Search index lock conflict (attempt {Attempt}/{Max}), retrying in {Delay}ms", attempt + 1, maxRetries, retryDelayMs);
Thread.Sleep(retryDelayMs);
Serilog.Log.Logger.Warning(ex, "Search index lock conflict (attempt {Attempt}/{Max}), retrying in {Delay}ms", attempt + 1, maxRetries, delayMs);
Thread.Sleep(delayMs);
}
}
}