Changed some commands in file getting, redone compression check commands and turned off btrfs compactor for 1.12.4
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Diagnostics;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace LightlessSync.Services.Compression
|
||||
namespace LightlessSync.Services.Compactor
|
||||
{
|
||||
/// <summary>
|
||||
/// This batch service is made for the File Frag command, because of each file needing to use this command.
|
||||
@@ -19,13 +18,26 @@ namespace LightlessSync.Services.Compression
|
||||
private readonly TimeSpan _flushDelay;
|
||||
private readonly CancellationTokenSource _cts = new();
|
||||
|
||||
public BatchFilefragService(bool useShell, ILogger log, int batchSize = 128, int flushMs = 25)
|
||||
public delegate (bool ok, string stdout, string stderr, int exitCode) RunDirect(string fileName, IEnumerable<string> args, string? workingDir, int timeoutMs);
|
||||
private readonly RunDirect _runDirect;
|
||||
|
||||
public delegate (bool ok, string stdout, string stderr, int exitCode) RunShell(string command, string? workingDir, int timeoutMs);
|
||||
private readonly RunShell _runShell;
|
||||
|
||||
public BatchFilefragService(bool useShell, ILogger log, int batchSize = 128, int flushMs = 25, RunDirect? runDirect = null, RunShell? runShell = null)
|
||||
{
|
||||
_useShell = useShell;
|
||||
_log = log;
|
||||
_batchSize = Math.Max(8, batchSize);
|
||||
_flushDelay = TimeSpan.FromMilliseconds(Math.Max(5, flushMs));
|
||||
_ch = Channel.CreateUnbounded<(string, TaskCompletionSource<bool>)>(new UnboundedChannelOptions { SingleReader = true, SingleWriter = false });
|
||||
|
||||
// require runners to be setup, wouldnt start otherwise
|
||||
if (runDirect is null || runShell is null)
|
||||
throw new ArgumentNullException(nameof(runDirect), "Provide process runners from FileCompactor");
|
||||
_runDirect = runDirect;
|
||||
_runShell = runShell;
|
||||
|
||||
_worker = Task.Run(ProcessAsync, _cts.Token);
|
||||
}
|
||||
|
||||
@@ -92,7 +104,7 @@ namespace LightlessSync.Services.Compression
|
||||
|
||||
try
|
||||
{
|
||||
var map = await RunBatchAsync(pending.Select(p => p.path)).ConfigureAwait(false);
|
||||
var map = RunBatch(pending.Select(p => p.path));
|
||||
foreach (var (path, tcs) in pending)
|
||||
{
|
||||
tcs.TrySetResult(map.TryGetValue(path, out var c) && c);
|
||||
@@ -124,75 +136,33 @@ namespace LightlessSync.Services.Compression
|
||||
/// <param name="paths">Paths that are needed for the command building for the batch return</param>
|
||||
/// <returns>Path of the file and if it went correctly</returns>
|
||||
/// <exception cref="InvalidOperationException">Failing to start filefrag on the system if this exception is found</exception>
|
||||
private async Task<Dictionary<string, bool>> RunBatchAsync(IEnumerable<string> paths)
|
||||
private Dictionary<string, bool> RunBatch(IEnumerable<string> paths)
|
||||
{
|
||||
var list = paths.Distinct(StringComparer.Ordinal).ToList();
|
||||
var result = list.ToDictionary(p => p, _ => false, StringComparer.Ordinal);
|
||||
|
||||
ProcessStartInfo psi;
|
||||
(bool ok, string stdout, string stderr, int code) res;
|
||||
|
||||
if (_useShell)
|
||||
{
|
||||
var inner = "filefrag -v -- " + string.Join(' ', list.Select(QuoteSingle));
|
||||
psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "/bin/bash",
|
||||
Arguments = "-lc " + QuoteDouble(inner),
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
WorkingDirectory = "/"
|
||||
};
|
||||
|
||||
if (!psi.Environment.TryGetValue("PATH", out var p) || string.IsNullOrWhiteSpace(p))
|
||||
psi.Environment["PATH"] = "/usr/sbin:/usr/bin:/bin";
|
||||
else
|
||||
psi.Environment["PATH"] = "/usr/sbin:/usr/bin:/bin:" + p;
|
||||
var inner = "filefrag -v " + string.Join(' ', list.Select(QuoteSingle));
|
||||
res = _runShell(inner, timeoutMs: 15000, workingDir: "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "filefrag",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
if (!psi.Environment.TryGetValue("PATH", out var p) || string.IsNullOrWhiteSpace(p))
|
||||
psi.Environment["PATH"] = "/usr/sbin:/usr/bin:/bin";
|
||||
else
|
||||
psi.Environment["PATH"] = "/usr/sbin:/usr/bin:/bin:" + p;
|
||||
|
||||
psi.ArgumentList.Add("-v");
|
||||
psi.ArgumentList.Add("--");
|
||||
var args = new List<string> { "-v" };
|
||||
foreach (var path in list)
|
||||
psi.ArgumentList.Add(path);
|
||||
{
|
||||
args.Add(' ' + path);
|
||||
}
|
||||
|
||||
res = _runDirect("filefrag", args, workingDir: "/", timeoutMs: 15000);
|
||||
}
|
||||
|
||||
using var proc = Process.Start(psi) ?? throw new InvalidOperationException("Failed to start filefrag");
|
||||
if (!string.IsNullOrWhiteSpace(res.stderr))
|
||||
_log.LogTrace("filefrag stderr (batch): {err}", res.stderr.Trim());
|
||||
|
||||
var outTask = proc.StandardOutput.ReadToEndAsync(_cts.Token);
|
||||
var errTask = proc.StandardError.ReadToEndAsync(_cts.Token);
|
||||
|
||||
var timeout = TimeSpan.FromSeconds(15);
|
||||
var combined = Task.WhenAll(outTask, errTask);
|
||||
var finished = await Task.WhenAny(combined, Task.Delay(timeout, _cts.Token)).ConfigureAwait(false);
|
||||
|
||||
if (finished != combined)
|
||||
{
|
||||
try { proc.Kill(entireProcessTree: true); } catch { /* ignore */ }
|
||||
try { await combined.ConfigureAwait(false); } catch { /* ignore */ }
|
||||
}
|
||||
|
||||
var stdout = outTask.IsCompletedSuccessfully ? await outTask.ConfigureAwait(false) : "";
|
||||
var stderr = errTask.IsCompletedSuccessfully ? await errTask.ConfigureAwait(false) : "";
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(stderr))
|
||||
_log.LogTrace("filefrag stderr (batch): {err}", stderr.Trim());
|
||||
|
||||
ParseFilefrag(stdout, result);
|
||||
ParseFilefrag(res.stdout, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -225,7 +195,6 @@ namespace LightlessSync.Services.Compression
|
||||
}
|
||||
|
||||
private static string QuoteSingle(string s) => "'" + s.Replace("'", "'\\''", StringComparison.Ordinal) + "'";
|
||||
private static string QuoteDouble(string s) => "\"" + s.Replace("\\", "\\\\", StringComparison.Ordinal).Replace("\"", "\\\"", StringComparison.Ordinal).Replace("$", "\\$", StringComparison.Ordinal).Replace("`", "\\`", StringComparison.Ordinal) + "\"";
|
||||
|
||||
/// <summary>
|
||||
/// Regex of the File Size return on the Linux/Wine systems, giving back the amount
|
||||
Reference in New Issue
Block a user