fix errors; add nouveau vaapi driver option (#692)

* fix service shutdown errors

* add nouveau vaapi driver option
This commit is contained in:
Jason Dove
2022-03-10 12:19:30 -06:00
committed by GitHub
parent f0670b345f
commit 6be5111195
10 changed files with 274 additions and 215 deletions
+51 -44
View File
@@ -26,61 +26,68 @@ public class EmbyService : BackgroundService
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
if (!File.Exists(FileSystemLayout.EmbySecretsPath))
try
{
await File.WriteAllTextAsync(FileSystemLayout.EmbySecretsPath, "{}", cancellationToken);
}
_logger.LogInformation(
"Emby service started; secrets are at {EmbySecretsPath}",
FileSystemLayout.EmbySecretsPath);
// synchronize sources on startup
await SynchronizeSources(new SynchronizeEmbyMediaSources(), cancellationToken);
await foreach (IEmbyBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken))
{
try
if (!File.Exists(FileSystemLayout.EmbySecretsPath))
{
Task requestTask;
switch (request)
{
case SynchronizeEmbyMediaSources synchronizeEmbyMediaSources:
requestTask = SynchronizeSources(synchronizeEmbyMediaSources, cancellationToken);
break;
// case SynchronizeEmbyAdminUserId synchronizeEmbyAdminUserId:
// requestTask = SynchronizeAdminUserId(synchronizeEmbyAdminUserId, cancellationToken);
// break;
case SynchronizeEmbyLibraries synchronizeEmbyLibraries:
requestTask = SynchronizeLibraries(synchronizeEmbyLibraries, cancellationToken);
break;
case ISynchronizeEmbyLibraryById synchronizeEmbyLibraryById:
requestTask = SynchronizeEmbyLibrary(synchronizeEmbyLibraryById, cancellationToken);
break;
default:
throw new NotSupportedException($"Unsupported request type: {request.GetType().Name}");
}
await requestTask;
await File.WriteAllTextAsync(FileSystemLayout.EmbySecretsPath, "{}", cancellationToken);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to process Emby background service request");
_logger.LogInformation(
"Emby service started; secrets are at {EmbySecretsPath}",
FileSystemLayout.EmbySecretsPath);
// synchronize sources on startup
await SynchronizeSources(new SynchronizeEmbyMediaSources(), cancellationToken);
await foreach (IEmbyBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken))
{
try
{
using (IServiceScope scope = _serviceScopeFactory.CreateScope())
Task requestTask;
switch (request)
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
case SynchronizeEmbyMediaSources synchronizeEmbyMediaSources:
requestTask = SynchronizeSources(synchronizeEmbyMediaSources, cancellationToken);
break;
// case SynchronizeEmbyAdminUserId synchronizeEmbyAdminUserId:
// requestTask = SynchronizeAdminUserId(synchronizeEmbyAdminUserId, cancellationToken);
// break;
case SynchronizeEmbyLibraries synchronizeEmbyLibraries:
requestTask = SynchronizeLibraries(synchronizeEmbyLibraries, cancellationToken);
break;
case ISynchronizeEmbyLibraryById synchronizeEmbyLibraryById:
requestTask = SynchronizeEmbyLibrary(synchronizeEmbyLibraryById, cancellationToken);
break;
default:
throw new NotSupportedException($"Unsupported request type: {request.GetType().Name}");
}
await requestTask;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to process Emby background service request");
try
{
using (IServiceScope scope = _serviceScopeFactory.CreateScope())
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
}
}
catch (Exception)
{
// do nothing
}
}
catch (Exception)
{
// do nothing
}
}
}
catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException)
{
_logger.LogInformation("Emby service shutting down");
}
}
private async Task SynchronizeSources(
+31 -24
View File
@@ -27,40 +27,47 @@ public class FFmpegWorkerService : BackgroundService
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("FFmpeg worker service started");
await foreach (IFFmpegWorkerRequest request in _channel.ReadAllAsync(cancellationToken))
try
{
using IServiceScope scope = _serviceScopeFactory.CreateScope();
_logger.LogInformation("FFmpeg worker service started");
try
await foreach (IFFmpegWorkerRequest request in _channel.ReadAllAsync(cancellationToken))
{
using IServiceScope scope = _serviceScopeFactory.CreateScope();
switch (request)
{
case TouchFFmpegSession touchFFmpegSession:
foreach (DirectoryInfo parent in Optional(Directory.GetParent(touchFFmpegSession.Path)))
{
_ffmpegSegmenterService.TouchChannel(parent.Name);
}
break;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to handle ffmpeg worker request");
try
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
switch (request)
{
case TouchFFmpegSession touchFFmpegSession:
foreach (DirectoryInfo parent in Optional(Directory.GetParent(touchFFmpegSession.Path)))
{
_ffmpegSegmenterService.TouchChannel(parent.Name);
}
break;
}
}
catch (Exception)
catch (Exception ex)
{
// do nothing
_logger.LogWarning(ex, "Failed to handle ffmpeg worker request");
try
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
}
catch (Exception)
{
// do nothing
}
}
}
}
catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException)
{
_logger.LogInformation("FFmpeg worker service shutting down");
}
}
}
+51 -44
View File
@@ -26,61 +26,68 @@ public class JellyfinService : BackgroundService
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
if (!File.Exists(FileSystemLayout.JellyfinSecretsPath))
try
{
await File.WriteAllTextAsync(FileSystemLayout.JellyfinSecretsPath, "{}", cancellationToken);
}
_logger.LogInformation(
"Jellyfin service started; secrets are at {JellyfinSecretsPath}",
FileSystemLayout.JellyfinSecretsPath);
// synchronize sources on startup
await SynchronizeSources(new SynchronizeJellyfinMediaSources(), cancellationToken);
await foreach (IJellyfinBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken))
{
try
if (!File.Exists(FileSystemLayout.JellyfinSecretsPath))
{
Task requestTask;
switch (request)
{
case SynchronizeJellyfinMediaSources synchronizeJellyfinMediaSources:
requestTask = SynchronizeSources(synchronizeJellyfinMediaSources, cancellationToken);
break;
case SynchronizeJellyfinAdminUserId synchronizeJellyfinAdminUserId:
requestTask = SynchronizeAdminUserId(synchronizeJellyfinAdminUserId, cancellationToken);
break;
case SynchronizeJellyfinLibraries synchronizeJellyfinLibraries:
requestTask = SynchronizeLibraries(synchronizeJellyfinLibraries, cancellationToken);
break;
case ISynchronizeJellyfinLibraryById synchronizeJellyfinLibraryById:
requestTask = SynchronizeJellyfinLibrary(synchronizeJellyfinLibraryById, cancellationToken);
break;
default:
throw new NotSupportedException($"Unsupported request type: {request.GetType().Name}");
}
await requestTask;
await File.WriteAllTextAsync(FileSystemLayout.JellyfinSecretsPath, "{}", cancellationToken);
}
catch (Exception ex)
_logger.LogInformation(
"Jellyfin service started; secrets are at {JellyfinSecretsPath}",
FileSystemLayout.JellyfinSecretsPath);
// synchronize sources on startup
await SynchronizeSources(new SynchronizeJellyfinMediaSources(), cancellationToken);
await foreach (IJellyfinBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken))
{
_logger.LogWarning(ex, "Failed to process Jellyfin background service request");
try
{
using (IServiceScope scope = _serviceScopeFactory.CreateScope())
Task requestTask;
switch (request)
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
case SynchronizeJellyfinMediaSources synchronizeJellyfinMediaSources:
requestTask = SynchronizeSources(synchronizeJellyfinMediaSources, cancellationToken);
break;
case SynchronizeJellyfinAdminUserId synchronizeJellyfinAdminUserId:
requestTask = SynchronizeAdminUserId(synchronizeJellyfinAdminUserId, cancellationToken);
break;
case SynchronizeJellyfinLibraries synchronizeJellyfinLibraries:
requestTask = SynchronizeLibraries(synchronizeJellyfinLibraries, cancellationToken);
break;
case ISynchronizeJellyfinLibraryById synchronizeJellyfinLibraryById:
requestTask = SynchronizeJellyfinLibrary(synchronizeJellyfinLibraryById, cancellationToken);
break;
default:
throw new NotSupportedException($"Unsupported request type: {request.GetType().Name}");
}
await requestTask;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to process Jellyfin background service request");
try
{
using (IServiceScope scope = _serviceScopeFactory.CreateScope())
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
}
}
catch (Exception)
{
// do nothing
}
}
catch (Exception)
{
// do nothing
}
}
}
catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException)
{
_logger.LogInformation("Jellyfin service shutting down");
}
}
private async Task SynchronizeSources(
+51 -44
View File
@@ -26,61 +26,68 @@ public class PlexService : BackgroundService
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
if (!File.Exists(FileSystemLayout.PlexSecretsPath))
try
{
await File.WriteAllTextAsync(FileSystemLayout.PlexSecretsPath, "{}", cancellationToken);
}
_logger.LogInformation(
"Plex service started; secrets are at {PlexSecretsPath}",
FileSystemLayout.PlexSecretsPath);
// synchronize sources on startup
await SynchronizeSources(new SynchronizePlexMediaSources(), cancellationToken);
await foreach (IPlexBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken))
{
try
if (!File.Exists(FileSystemLayout.PlexSecretsPath))
{
Task requestTask;
switch (request)
{
case TryCompletePlexPinFlow pinRequest:
requestTask = CompletePinFlow(pinRequest, cancellationToken);
break;
case SynchronizePlexMediaSources sourcesRequest:
requestTask = SynchronizeSources(sourcesRequest, cancellationToken);
break;
case SynchronizePlexLibraries synchronizePlexLibrariesRequest:
requestTask = SynchronizeLibraries(synchronizePlexLibrariesRequest, cancellationToken);
break;
case ISynchronizePlexLibraryById synchronizePlexLibraryById:
requestTask = SynchronizePlexLibrary(synchronizePlexLibraryById, cancellationToken);
break;
default:
throw new NotSupportedException($"Unsupported request type: {request.GetType().Name}");
}
await requestTask;
await File.WriteAllTextAsync(FileSystemLayout.PlexSecretsPath, "{}", cancellationToken);
}
catch (Exception ex)
_logger.LogInformation(
"Plex service started; secrets are at {PlexSecretsPath}",
FileSystemLayout.PlexSecretsPath);
// synchronize sources on startup
await SynchronizeSources(new SynchronizePlexMediaSources(), cancellationToken);
await foreach (IPlexBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken))
{
_logger.LogWarning(ex, "Failed to process plex background service request");
try
{
using (IServiceScope scope = _serviceScopeFactory.CreateScope())
Task requestTask;
switch (request)
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
case TryCompletePlexPinFlow pinRequest:
requestTask = CompletePinFlow(pinRequest, cancellationToken);
break;
case SynchronizePlexMediaSources sourcesRequest:
requestTask = SynchronizeSources(sourcesRequest, cancellationToken);
break;
case SynchronizePlexLibraries synchronizePlexLibrariesRequest:
requestTask = SynchronizeLibraries(synchronizePlexLibrariesRequest, cancellationToken);
break;
case ISynchronizePlexLibraryById synchronizePlexLibraryById:
requestTask = SynchronizePlexLibrary(synchronizePlexLibraryById, cancellationToken);
break;
default:
throw new NotSupportedException($"Unsupported request type: {request.GetType().Name}");
}
await requestTask;
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to process plex background service request");
try
{
using (IServiceScope scope = _serviceScopeFactory.CreateScope())
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
}
}
catch (Exception)
{
// do nothing
}
}
catch (Exception)
{
// do nothing
}
}
}
catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException)
{
_logger.LogInformation("Plex service shutting down");
}
}
private async Task<List<PlexMediaSource>> SynchronizeSources(
+10 -2
View File
@@ -51,8 +51,16 @@ public class SchedulerService : BackgroundService
int currentMinutes = DateTime.Now.TimeOfDay.Minutes;
int toWait = currentMinutes < 30 ? 30 - currentMinutes : 60 - currentMinutes;
_logger.LogDebug("Scheduler sleeping for {Minutes} minutes", toWait);
await Task.Delay(TimeSpan.FromMinutes(toWait), cancellationToken);
try
{
await Task.Delay(TimeSpan.FromMinutes(toWait), cancellationToken);
}
catch (TaskCanceledException)
{
// do nothing
}
if (!cancellationToken.IsCancellationRequested)
{
var roundedMinute = (int)(Math.Round(DateTime.Now.Minute / 5.0) * 5);
+72 -56
View File
@@ -29,74 +29,90 @@ public class WorkerService : BackgroundService
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("Worker service started");
await foreach (IBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken))
try
{
using IServiceScope scope = _serviceScopeFactory.CreateScope();
_logger.LogInformation("Worker service started");
try
await foreach (IBackgroundServiceRequest request in _channel.ReadAllAsync(cancellationToken))
{
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
switch (request)
if (cancellationToken.IsCancellationRequested)
{
case BuildPlayout buildPlayout:
Either<BaseError, Unit> buildPlayoutResult = await mediator.Send(
buildPlayout,
cancellationToken);
buildPlayoutResult.BiIter(
_ => _logger.LogDebug("Built playout {PlayoutId}", buildPlayout.PlayoutId),
error => _logger.LogWarning(
"Unable to build playout {PlayoutId}: {Error}",
buildPlayout.PlayoutId,
error.Value));
break;
case IScanLocalLibrary scanLocalLibrary:
Either<BaseError, string> scanResult = await mediator.Send(
scanLocalLibrary,
cancellationToken);
scanResult.BiIter(
name => _logger.LogDebug(
"Done scanning local library {Library}",
name),
error => _logger.LogWarning(
"Unable to scan local library {LibraryId}: {Error}",
scanLocalLibrary.LibraryId,
error.Value));
break;
case RebuildSearchIndex rebuildSearchIndex:
await mediator.Send(rebuildSearchIndex, cancellationToken);
break;
case DeleteOrphanedArtwork deleteOrphanedArtwork:
_logger.LogInformation("Deleting orphaned artwork from the database");
await mediator.Send(deleteOrphanedArtwork, cancellationToken);
break;
case AddTraktList addTraktList:
await mediator.Send(addTraktList, cancellationToken);
break;
case DeleteTraktList deleteTraktList:
await mediator.Send(deleteTraktList, cancellationToken);
break;
case MatchTraktListItems matchTraktListItems:
await mediator.Send(matchTraktListItems, cancellationToken);
break;
break;
}
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to process background service request");
using IServiceScope scope = _serviceScopeFactory.CreateScope();
try
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
IMediator mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
switch (request)
{
case BuildPlayout buildPlayout:
Either<BaseError, Unit> buildPlayoutResult = await mediator.Send(
buildPlayout,
cancellationToken);
buildPlayoutResult.BiIter(
_ => _logger.LogDebug("Built playout {PlayoutId}", buildPlayout.PlayoutId),
error => _logger.LogWarning(
"Unable to build playout {PlayoutId}: {Error}",
buildPlayout.PlayoutId,
error.Value));
break;
case IScanLocalLibrary scanLocalLibrary:
Either<BaseError, string> scanResult = await mediator.Send(
scanLocalLibrary,
cancellationToken);
scanResult.BiIter(
name => _logger.LogDebug(
"Done scanning local library {Library}",
name),
error => _logger.LogWarning(
"Unable to scan local library {LibraryId}: {Error}",
scanLocalLibrary.LibraryId,
error.Value));
break;
case RebuildSearchIndex rebuildSearchIndex:
await mediator.Send(rebuildSearchIndex, cancellationToken);
break;
case DeleteOrphanedArtwork deleteOrphanedArtwork:
_logger.LogInformation("Deleting orphaned artwork from the database");
await mediator.Send(deleteOrphanedArtwork, cancellationToken);
break;
case AddTraktList addTraktList:
await mediator.Send(addTraktList, cancellationToken);
break;
case DeleteTraktList deleteTraktList:
await mediator.Send(deleteTraktList, cancellationToken);
break;
case MatchTraktListItems matchTraktListItems:
await mediator.Send(matchTraktListItems, cancellationToken);
break;
}
}
catch (Exception)
catch (ObjectDisposedException) when (cancellationToken.IsCancellationRequested)
{
// do nothing
// this can happen when we're shutting down
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to process background service request");
try
{
IClient client = scope.ServiceProvider.GetRequiredService<IClient>();
client.Notify(ex);
}
catch (Exception)
{
// do nothing
}
}
}
}
catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException)
{
_logger.LogInformation("Worker service shutting down");
}
}
}