aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-04-11 18:00:41 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-04-11 18:00:41 +0200
commit60e01e1f22fa6fc3505469abd96d85d64b05fac1 (patch)
treed39c4ffea1c36735013f95ef69d20536ad354a42 /src
parente0f50f504afe5713f64d644a464f39e903d9ef6b (diff)
Apply review suggestions
Diffstat (limited to 'src')
-rw-r--r--src/Jellyfin.LiveTv/Guide/GuideManager.cs8
-rw-r--r--src/Jellyfin.LiveTv/Listings/SchedulesDirect.cs26
2 files changed, 29 insertions, 5 deletions
diff --git a/src/Jellyfin.LiveTv/Guide/GuideManager.cs b/src/Jellyfin.LiveTv/Guide/GuideManager.cs
index a659cc020b..556516674b 100644
--- a/src/Jellyfin.LiveTv/Guide/GuideManager.cs
+++ b/src/Jellyfin.LiveTv/Guide/GuideManager.cs
@@ -738,6 +738,14 @@ public class GuideManager : IGuideManager
_cacheParallelOptions,
async (program, cancellationToken) =>
{
+ // Re-check: limit may have been set by a parallel task since the LINQ filter ran.
+ if (_schedulesDirectService.IsImageDailyLimitActive()
+ && program.ImageInfos.All(
+ img => img.IsLocalFile || img.Path.Contains("schedulesdirect", StringComparison.OrdinalIgnoreCase)))
+ {
+ return;
+ }
+
for (var i = 0; i < program.ImageInfos.Length; i++)
{
if (cancellationToken.IsCancellationRequested)
diff --git a/src/Jellyfin.LiveTv/Listings/SchedulesDirect.cs b/src/Jellyfin.LiveTv/Listings/SchedulesDirect.cs
index 7b97dcc8db..3aa0f0408b 100644
--- a/src/Jellyfin.LiveTv/Listings/SchedulesDirect.cs
+++ b/src/Jellyfin.LiveTv/Listings/SchedulesDirect.cs
@@ -45,8 +45,8 @@ namespace Jellyfin.LiveTv.Listings
private readonly ConcurrentDictionary<string, NameValuePair> _tokens = new();
private readonly JsonSerializerOptions _jsonOptions = JsonDefaults.Options;
- private DateTime _lastErrorResponse;
- private bool _accountError;
+ private long _lastErrorResponseTicks;
+ private volatile bool _accountError;
private bool _disposed = false;
private byte[] _countriesCache;
@@ -594,7 +594,7 @@ namespace Jellyfin.LiveTv.Listings
}
// Avoid hammering SD after transient login failures (e.g. max attempts / temporary lockout)
- if ((DateTime.UtcNow - _lastErrorResponse).TotalMinutes < 30)
+ if ((DateTime.UtcNow - new DateTime(Interlocked.Read(ref _lastErrorResponseTicks), DateTimeKind.Utc)).TotalMinutes < 30)
{
return null;
}
@@ -635,7 +635,7 @@ namespace Jellyfin.LiveTv.Listings
&& (int)ex.StatusCode.Value < 500)
{
_tokens.Clear();
- _lastErrorResponse = DateTime.UtcNow;
+ Interlocked.Exchange(ref _lastErrorResponseTicks, DateTime.UtcNow.Ticks);
}
throw;
@@ -695,7 +695,7 @@ namespace Jellyfin.LiveTv.Listings
{
// Transient login errors — back off for 30 minutes, then allow retry.
_tokens.Clear();
- _lastErrorResponse = DateTime.UtcNow;
+ Interlocked.Exchange(ref _lastErrorResponseTicks, DateTime.UtcNow.Ticks);
}
else if (sdCode is SdErrorCode.MaxImageDownloads)
{
@@ -877,6 +877,22 @@ namespace Jellyfin.LiveTv.Listings
}
/// <inheritdoc />
+ public bool IsServiceAvailable()
+ {
+ if (_accountError)
+ {
+ return false;
+ }
+
+ if ((DateTime.UtcNow - new DateTime(Interlocked.Read(ref _lastErrorResponseTicks), DateTimeKind.Utc)).TotalMinutes < 30)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <inheritdoc />
public bool IsImageDailyLimitActive()
{
if (!_imageLimitHitDate.HasValue)