feat: add configurable multi-threaded parallel scanning for library tasks
Build and Release Plugin / release (push) Successful in 33s

This commit is contained in:
2026-09-18 00:14:20 +02:00
parent d88f910b58
commit efd0f14278
5 changed files with 47 additions and 20 deletions
@@ -42,19 +42,28 @@ namespace JellyfinPlugin.Tasks
.ToList();
int total = items.Count;
if (total == 0) return;
int processed = 0;
int maxParallel = Math.Clamp(config.MaxParallelScans, 1, 16);
foreach (var item in items)
var parallelOptions = new ParallelOptions
{
cancellationToken.ThrowIfCancellationRequested();
MaxDegreeOfParallelism = maxParallel,
CancellationToken = cancellationToken
};
_logger.LogInformation("Starting Retroactive Scan of {Total} items with {MaxParallel} parallel workers.", total, maxParallel);
await Parallel.ForEachAsync(items, parallelOptions, async (item, ct) =>
{
if (item.ProviderIds != null &&
item.ProviderIds.TryGetValue("BlackBarCrop", out string? existingCrop) &&
!string.IsNullOrEmpty(existingCrop))
{
processed++;
progress.Report((processed / (double)total) * 100);
continue;
int currentSkipped = Interlocked.Increment(ref processed);
progress.Report((currentSkipped / (double)total) * 100);
return;
}
var path = item.Path;
@@ -71,7 +80,7 @@ namespace JellyfinPlugin.Tasks
item.ProviderIds = new Dictionary<string, string>();
}
item.ProviderIds["BlackBarCrop"] = cropData;
await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, cancellationToken);
await _libraryManager.UpdateItemAsync(item, item, ItemUpdateType.MetadataEdit, ct);
_logger.LogInformation("Found black bars {Crop} in {Path}", cropData, path);
}
}
@@ -81,9 +90,9 @@ namespace JellyfinPlugin.Tasks
}
}
processed++;
progress.Report((processed / (double)total) * 100);
}
int currentDone = Interlocked.Increment(ref processed);
progress.Report((currentDone / (double)total) * 100);
});
}
public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()