This commit is contained in:
2026-04-09 00:51:24 +02:00
parent 633da52880
commit 854adc32c1
11 changed files with 366 additions and 45 deletions

View File

@@ -13,6 +13,7 @@ public class PollingService
private System.Threading.Timer? _timer;
private bool _isProcessing;
private DateTime _pollStartedAt;
private int _totalPrinted;
private readonly object _lock = new();
@@ -61,13 +62,27 @@ public class PollingService
{
lock (_lock)
{
if (_isProcessing) return;
if (_isProcessing)
{
if (DateTime.UtcNow - _pollStartedAt > TimeSpan.FromSeconds(60))
{
LogForm.Log("WATCHDOG: wymuszony reset _isProcessing po 60s");
_isProcessing = false;
}
else
{
return;
}
}
_isProcessing = true;
_pollStartedAt = DateTime.UtcNow;
}
try
{
var jobs = await _apiClient.GetPendingJobsAsync();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(45));
var jobs = await _apiClient.GetPendingJobsAsync(cts.Token);
LogForm.Log($"Polling: znaleziono {jobs.Count} zleceń");
if (jobs.Count == 0)
@@ -85,7 +100,7 @@ public class PollingService
try
{
LogForm.Log($"Job {job.Id}: pobieranie etykiety...");
var labelBytes = await _apiClient.DownloadLabelAsync(job.Id);
var labelBytes = await _apiClient.DownloadLabelAsync(job.Id, cts.Token);
LogForm.Log($"Job {job.Id}: pobrano {labelBytes.Length} bajtów");
if (labelBytes.Length == 0)
@@ -101,7 +116,7 @@ public class PollingService
if (success)
{
await _apiClient.MarkCompleteAsync(job.Id);
await _apiClient.MarkCompleteAsync(job.Id, cts.Token);
printed++;
_totalPrinted++;
LogForm.Log($"Job {job.Id}: wydrukowano i oznaczono jako complete ✓");
@@ -140,8 +155,9 @@ public class PollingService
{
_onError($"API niedostępne: {ex.Message}");
}
catch (TaskCanceledException)
catch (OperationCanceledException)
{
LogForm.Log("Timeout: poll anulowany przez CancellationToken");
_onError("Timeout połączenia z API");
}
catch (Exception ex)

View File

@@ -18,26 +18,26 @@ public class PrintApiClient : IDisposable
_httpClient.DefaultRequestHeaders.Add("X-Api-Key", apiKey);
}
public async Task<List<PrintJob>> GetPendingJobsAsync()
public async Task<List<PrintJob>> GetPendingJobsAsync(CancellationToken cancellationToken = default)
{
var response = await _httpClient.GetAsync("api/print/jobs/pending");
var response = await _httpClient.GetAsync("api/print/jobs/pending", cancellationToken);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var json = await response.Content.ReadAsStringAsync(cancellationToken);
var result = JsonSerializer.Deserialize<PendingJobsResponse>(json);
return result?.Jobs ?? new List<PrintJob>();
}
public async Task<byte[]> DownloadLabelAsync(int jobId)
public async Task<byte[]> DownloadLabelAsync(int jobId, CancellationToken cancellationToken = default)
{
var response = await _httpClient.GetAsync($"api/print/jobs/{jobId}/download");
var response = await _httpClient.GetAsync($"api/print/jobs/{jobId}/download", cancellationToken);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsByteArrayAsync();
return await response.Content.ReadAsByteArrayAsync(cancellationToken);
}
public async Task<bool> MarkCompleteAsync(int jobId)
public async Task<bool> MarkCompleteAsync(int jobId, CancellationToken cancellationToken = default)
{
var response = await _httpClient.PostAsync($"api/print/jobs/{jobId}/complete", null);
var response = await _httpClient.PostAsync($"api/print/jobs/{jobId}/complete", null, cancellationToken);
return response.IsSuccessStatusCode;
}