Skip to content

Commit

Permalink
Escl: Improve timeout handling
Browse files Browse the repository at this point in the history
  • Loading branch information
cyanfish committed Jul 6, 2024
1 parent 29530c9 commit bbe4cc7
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
6 changes: 2 additions & 4 deletions NAPS2.Escl.Server/EsclApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public async Task GetScannerCapabilities()
new XElement(ScanNs + "UUID", caps.Uuid),
new XElement(ScanNs + "AdminURI", ""),
new XElement(ScanNs + "IconURI", iconUri),
new XElement(ScanNs + "Naps2Extensions", "Progress;ErrorDetails"),
new XElement(ScanNs + "Naps2Extensions", "Progress;ErrorDetails;ShortTimeout"),
new XElement(ScanNs + "Platen",
new XElement(ScanNs + "PlatenInputCaps", GetCommonInputCaps())),
new XElement(ScanNs + "Adf",
Expand Down Expand Up @@ -293,9 +293,7 @@ private async Task WaitForAndWriteNextDocument(JobInfo jobInfo)
// If we already have a document (i.e. if a connection error occured during the previous NextDocument
// request), we stay at that same document and don't advance
var cts = new CancellationTokenSource();
// TODO: Cancel this after a short interval.
// TODO: This is going to break clients that don't have 503 support, so we'll launch that first and keep this change for 7.5.0+
// cts.CancelAfter(1000);
cts.CancelAfter(1000);
jobInfo.NextDocumentReady = jobInfo.NextDocumentReady || await jobInfo.Job.WaitForNextDocument(cts.Token);
}
catch (TaskCanceledException)
Expand Down
20 changes: 17 additions & 3 deletions NAPS2.Escl/Client/EsclClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public class EsclClient
{
Timeout = TimeSpan.FromSeconds(10)
};
private static readonly HttpClient LongTimeoutVerifiedHttpClient = new(VerifiedHttpClientHandler)
{
Timeout = TimeSpan.FromSeconds(120)
};

// Client that doesn't verify HTTPS certificates
private static readonly HttpMessageHandler UnverifiedHttpClientHandler = new StandardSocketsHttpHandler
Expand All @@ -41,6 +45,10 @@ public class EsclClient
{
Timeout = TimeSpan.FromSeconds(10)
};
private static readonly HttpClient LongTimeoutUnverifiedHttpClient = new(UnverifiedHttpClientHandler)
{
Timeout = TimeSpan.FromSeconds(120)
};

private readonly EsclService _service;
private bool _httpFallback;
Expand All @@ -60,6 +68,11 @@ public EsclClient(EsclService service)
? VerifiedHttpClient
: UnverifiedHttpClient;

private HttpClient LongTimeoutHttpClient =>
SecurityPolicy.HasFlag(EsclSecurityPolicy.ClientRequireTrustedCertificate)
? LongTimeoutVerifiedHttpClient
: LongTimeoutUnverifiedHttpClient;

public async Task<EsclCapabilities> GetCapabilities()
{
var doc = await DoRequest("ScannerCapabilities");
Expand Down Expand Up @@ -143,13 +156,13 @@ public async Task<EsclJob> CreateScanJob(EsclScanSettings settings)
return new XElement(elementName, value);
}

public async Task<RawDocument?> NextDocument(EsclJob job, Action<double>? pageProgress = null)
public async Task<RawDocument?> NextDocument(EsclJob job, Action<double>? pageProgress = null, bool shortTimeout = false)
{
var progressCts = new CancellationTokenSource();
if (pageProgress != null)
{
var progressUrl = GetUrl($"{job.UriPath}/Progress");
var progressResponse = await HttpClient.GetStreamAsync(progressUrl);
var progressResponse = await LongTimeoutHttpClient.GetStreamAsync(progressUrl);
var streamReader = new StreamReader(progressResponse);
_ = Task.Run(async () =>
{
Expand Down Expand Up @@ -178,7 +191,8 @@ public async Task<EsclJob> CreateScanJob(EsclScanSettings settings)
url =>
{
Logger.LogDebug("ESCL GET {Url}", url);
return HttpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
var client = shortTimeout ? HttpClient : LongTimeoutHttpClient;
return client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
});
if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
{
Expand Down
9 changes: 5 additions & 4 deletions NAPS2.Sdk/Scan/Internal/Escl/EsclScanDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public async Task Scan(ScanOptions options, CancellationToken cancelToken, IScan
var scanSettings = GetScanSettings(options, caps);
bool hasProgressExtension = caps.Naps2Extensions?.Contains("Progress") ?? false;
bool hasErrorDetailsExtension = caps.Naps2Extensions?.Contains("ErrorDetails") ?? false;
bool hasShortTimeoutExtension = caps.Naps2Extensions?.Contains("ShortTimeout") ?? false;
Action<double>? progressCallback = hasProgressExtension ? scanEvents.PageProgress : null;

if (cancelToken.IsCancellationRequested) return;
Expand All @@ -120,7 +121,7 @@ public async Task Scan(ScanOptions options, CancellationToken cancelToken, IScan
{
scanEvents.PageStart();
}
var doc = await GetNextDocumentWithRetries(client, job, progressCallback);
var doc = await GetNextDocumentWithRetries(client, job, progressCallback, hasShortTimeoutExtension);
if (doc == null) break;
foreach (var image in GetImagesFromRawDocument(options, doc))
{
Expand Down Expand Up @@ -176,15 +177,15 @@ private async Task<EsclJob> CreateScanJobAndCorrectInvalidSettings(EsclClient cl
return job;
}

private async Task<RawDocument?> GetNextDocumentWithRetries(
EsclClient client, EsclJob job, Action<double>? progress)
private async Task<RawDocument?> GetNextDocumentWithRetries(EsclClient client, EsclJob job,
Action<double>? progress, bool shortTimeout)
{
int retries = 0;
while (true)
{
try
{
return await client.NextDocument(job, progress);
return await client.NextDocument(job, progress, shortTimeout);
}
catch (Exception ex)
{
Expand Down

0 comments on commit bbe4cc7

Please sign in to comment.