New: Configurable per-indexer query timeout

This commit is contained in:
Simone Filippini 2026-03-12 01:32:26 +01:00
parent 43aca69840
commit 11f6483d19
3 changed files with 23 additions and 2 deletions

View file

@ -526,7 +526,8 @@ protected virtual async Task<IndexerPageableQueryResult> FetchReleases(Func<IInd
catch (TaskCanceledException ex)
{
_indexerStatusService.RecordFailure(Definition.Id);
_logger.Warn(ex, "Unable to connect to indexer, possibly due to a timeout. [{0}]", url);
var timeoutMs = Settings.BaseSettings?.QueryTimeout ?? 100000;
_logger.Warn(ex, "Unable to connect to indexer, possibly due to a timeout ({0} ms). [{1}]", timeoutMs, url);
}
catch (Exception ex)
{
@ -661,6 +662,11 @@ protected virtual async Task<IndexerResponse> FetchIndexerResponse(IndexerReques
request.HttpRequest.SuppressHttpError = true;
request.HttpRequest.Encoding ??= Encoding;
if (request.HttpRequest.RequestTimeout == TimeSpan.Zero && Settings.BaseSettings != null)
{
request.HttpRequest.RequestTimeout = TimeSpan.FromMilliseconds(Settings.BaseSettings.QueryTimeout);
}
var response = await RetryStrategy
.ExecuteAsync(static async (state, _) => await state._httpClient.ExecuteProxiedAsync(state.HttpRequest, state.Definition), (_httpClient, request.HttpRequest, Definition))
.ConfigureAwait(false);
@ -836,8 +842,14 @@ protected virtual async Task<ValidationFailure> TestConnection()
return new ValidationFailure(string.Empty, "Unable to connect to indexer connection failure. Check your connection to the indexer's server and DNS." + webException.Message);
}
if (webException.Message.Contains("timed out"))
{
var timeoutMs = Settings.BaseSettings?.QueryTimeout ?? 100000;
return new ValidationFailure(string.Empty, "Unable to connect to indexer, request timed out after " + timeoutMs + " ms. Consider increasing the Query Timeout in the indexer advanced settings. " + webException.Message);
}
if (webException.Message.Contains("502") || webException.Message.Contains("503") ||
webException.Message.Contains("504") || webException.Message.Contains("timed out"))
webException.Message.Contains("504"))
{
return new ValidationFailure(string.Empty, "Unable to connect to indexer, indexer's server is unavailable. Try again later. " + webException.Message);
}

View file

@ -16,6 +16,10 @@ public IndexerCommonSettingsValidator()
.GreaterThan(0)
.When(c => c.GrabLimit.HasValue)
.WithMessage("Should be greater than zero");
RuleFor(c => c.QueryTimeout)
.InclusiveBetween(50, 600000)
.WithMessage("Must be between 50 ms and 600000 ms (10 minutes)");
}
}
@ -29,6 +33,9 @@ public class IndexerBaseSettings
[FieldDefinition(3, Type = FieldType.Select, Label = "IndexerSettingsLimitsUnit", SelectOptions = typeof(IndexerLimitsUnit), HelpText = "IndexerSettingsLimitsUnitHelpText", Advanced = true)]
public int LimitsUnit { get; set; } = (int)IndexerLimitsUnit.Day;
[FieldDefinition(4, Type = FieldType.Number, Label = "IndexerSettingsQueryTimeout", Unit = "ms", HelpText = "IndexerSettingsQueryTimeoutHelpText", Advanced = true)]
public int QueryTimeout { get; set; } = 100000;
}
public enum IndexerLimitsUnit

View file

@ -428,6 +428,8 @@
"IndexerSettingsPreferMagnetUrlHelpText": "When enabled, this indexer will prefer the use of magnet URLs for grabs with fallback to torrent links",
"IndexerSettingsQueryLimit": "Query Limit",
"IndexerSettingsQueryLimitHelpText": "The number of max queries as specified by the respective unit that {appName} will allow to the site",
"IndexerSettingsQueryTimeout": "Query Timeout",
"IndexerSettingsQueryTimeoutHelpText": "Query timeout in milliseconds for this indexer. Default is 100000 ms (100s). Increase for slow indexers, decrease for faster failure detection",
"IndexerSettingsRssKey": "RSS Key",
"IndexerSettingsSeedRatio": "Seed Ratio",
"IndexerSettingsSeedRatioHelpText": "The ratio a torrent should reach before stopping, empty uses the download client's default. Ratio should be at least 1.0 and follow the indexers rules",