69 lines
2.3 KiB
C#
69 lines
2.3 KiB
C#
using System.Diagnostics;
|
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
|
using Microsoft.Extensions.Options;
|
|
using TuneRipper.Api.Configuration;
|
|
|
|
namespace TuneRipper.Api.Health;
|
|
|
|
public sealed class ExternalToolsHealthCheck(IOptions<YtDlpOptions> options) : IHealthCheck
|
|
{
|
|
public async Task<HealthCheckResult> CheckHealthAsync(
|
|
HealthCheckContext context,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var ytDlp = await ProbeAsync(options.Value.ExecutablePath, "--version", cancellationToken);
|
|
if (!ytDlp.Success)
|
|
{
|
|
return HealthCheckResult.Unhealthy($"yt-dlp is unavailable: {ytDlp.Message}");
|
|
}
|
|
|
|
var ffmpeg = await ProbeAsync(options.Value.FfmpegExecutablePath, "-version", cancellationToken);
|
|
if (!ffmpeg.Success)
|
|
{
|
|
return HealthCheckResult.Unhealthy($"ffmpeg is unavailable: {ffmpeg.Message}");
|
|
}
|
|
|
|
return HealthCheckResult.Healthy($"yt-dlp {ytDlp.Message}; ffmpeg available");
|
|
}
|
|
|
|
private static async Task<(bool Success, string Message)> ProbeAsync(
|
|
string executable,
|
|
string argument,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
var startInfo = new ProcessStartInfo
|
|
{
|
|
FileName = executable,
|
|
UseShellExecute = false,
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
CreateNoWindow = true
|
|
};
|
|
startInfo.ArgumentList.Add(argument);
|
|
|
|
using var process = Process.Start(startInfo);
|
|
if (process is null)
|
|
{
|
|
return (false, "process could not be started");
|
|
}
|
|
|
|
using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
|
timeout.CancelAfter(TimeSpan.FromSeconds(10));
|
|
|
|
var outputTask = process.StandardOutput.ReadLineAsync(timeout.Token).AsTask();
|
|
await process.WaitForExitAsync(timeout.Token);
|
|
var output = (await outputTask)?.Trim();
|
|
|
|
return process.ExitCode == 0
|
|
? (true, string.IsNullOrWhiteSpace(output) ? "available" : output)
|
|
: (false, $"exit code {process.ExitCode}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return (false, ex.Message);
|
|
}
|
|
}
|
|
}
|