Archived
0
0
Fork 0

some re-architectoring and code cleanups

This commit is contained in:
Daryl Ronningen 2022-11-19 03:50:09 -08:00
parent 50b682c875
commit af700c798e
Signed by: Daryl Ronningen
GPG key ID: FD23F0C934A5EC6B
9 changed files with 81 additions and 55 deletions

View file

@ -1,4 +1,3 @@
using System.Diagnostics;
using Grpc.Core; using Grpc.Core;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
@ -40,42 +39,26 @@ public class Init
var app = _socketBuilder.Build(); var app = _socketBuilder.Build();
app.MapGrpcService<StartGrpc>(); app.MapGrpcService<StartRPC>();
app.Run(); app.Run();
} }
} }
public class StartGrpc : StartRpc.StartRpcBase public class StartRPC : StartRpc.StartRpcBase
{ {
public override async Task StartService(StartRequest request, IServerStreamWriter<StartReply> responseStream, public override async Task<StartReply> StartService(StartRequest request, ServerCallContext context)
ServerCallContext context)
{ {
Init.Logger.Information($"Received request to start service {Path.GetFileName(request.Path)}."); Init.Logger.Information($"Received request to start service {Path.GetFileName(request.Path)}.");
var parseServiceFile = await ServiceParser.Parse(request.Path); var startService = await Utils.StartService.InitAsync(request.Path);
var thread = new Thread(startService.StartServiceAsync);
thread.Start();
using var startService = new Process(); Init.Logger.Information($"Started service {Path.GetFileName(Path.GetFileName(request.Path))}.");
startService.StartInfo.FileName = parseServiceFile.ExecStart?.Split(' ').First();
startService.StartInfo.Arguments = string.Join(" ", parseServiceFile.ExecStart?.Split(' ').Skip(1)!);
startService.StartInfo.UseShellExecute = false;
startService.StartInfo.RedirectStandardOutput = true;
startService.StartInfo.RedirectStandardError = true;
startService.EnableRaisingEvents = true;
startService.OutputDataReceived += (sender, args) => Init.Logger.Information(args.Data!); Globals.Services.Add(startService);
startService.ErrorDataReceived += (sender, args) => Init.Logger.Error(args.Data!);
if (!startService.Start()) return new StartReply { Success = true };
throw new Exception("Process failed to start");
startService.BeginOutputReadLine();
startService.BeginErrorReadLine();
Init.Logger.Information($"Started service {Path.GetFileName(request.Path)}.");
await responseStream.WriteAsync(new StartReply { Success = true });
await startService.WaitForExitAsync();
} }
} }

View file

@ -1,4 +1,3 @@
using Grpc.Core;
using netsd.Utils; using netsd.Utils;
using StartGrpc; using StartGrpc;
@ -23,17 +22,8 @@ public class Start
using var channel = UDSConnector.CreateChannel(); using var channel = UDSConnector.CreateChannel();
var client = new StartRpc.StartRpcClient(channel); var client = new StartRpc.StartRpcClient(channel);
var reply = client.StartService(new StartRequest{ Path = ServiceFilePath }); var reply = await client.StartServiceAsync(new StartRequest { Path = ServiceFilePath });
while (await reply.ResponseStream.MoveNext()) Console.WriteLine($"{reply.Success}");
{
var current = reply.ResponseStream.Current;
Console.WriteLine($"{current.Success}");
if (!current.Success) continue;
Environment.Exit(0);
break;
}
} }
} }

View file

@ -22,13 +22,9 @@ initCommand.SetHandler(() => new Init());
startCommand.SetHandler(async (file, name) => startCommand.SetHandler(async (file, name) =>
{ {
if (name.Length != 0) if (name.Length != 0)
{
await new Start().StartAsync(ServiceName: name); await new Start().StartAsync(ServiceName: name);
}
else else
{ await new Start().StartAsync(file.FullName);
await new Start().StartAsync(ServiceFilePath: file.FullName);
}
}, startServicePath, startServiceName); }, startServicePath, startServiceName);
return await rootCommand.InvokeAsync(args); return await rootCommand.InvokeAsync(args);

View file

@ -5,7 +5,7 @@ option csharp_namespace = "StartGrpc";
package netsd; package netsd;
service StartRpc { service StartRpc {
rpc StartService (StartRequest) returns (stream StartReply); rpc StartService (StartRequest) returns (StartReply);
} }
message StartRequest { message StartRequest {

6
netsd/Utils/Globals.cs Normal file
View file

@ -0,0 +1,6 @@
namespace netsd.Utils;
public static class Globals
{
public static List<StartService> Services = new();
}

View file

@ -16,5 +16,5 @@ public class ServiceParser
sv.ExecStart = serviceData["Service"]["ExecStart"]; sv.ExecStart = serviceData["Service"]["ExecStart"];
return sv; return sv;
} }
} }

View file

@ -0,0 +1,51 @@
using System.Diagnostics;
using netsd.Handlers;
namespace netsd.Utils;
public class StartService
{
private readonly ServiceParser _parseServiceFile;
private readonly Process _process;
private readonly string _servicePath;
private StartService(string servicePath, ServiceParser parseServiceFile)
{
_parseServiceFile = parseServiceFile;
_servicePath = servicePath;
_process = new Process();
_process.StartInfo.FileName = _parseServiceFile.ExecStart?.Split(' ').First();
_process.StartInfo.Arguments = string.Join(" ", _parseServiceFile.ExecStart?.Split(' ').Skip(1)!);
_process.StartInfo.UseShellExecute = false;
_process.StartInfo.RedirectStandardOutput = true;
_process.StartInfo.RedirectStandardError = true;
_process.EnableRaisingEvents = true;
_process.OutputDataReceived += (sender, args) =>
Init.Logger.Information($"({Path.GetFileName(_servicePath)}) {args.Data}");
_process.ErrorDataReceived += (sender, args) =>
Init.Logger.Error($"({Path.GetFileName(_servicePath)}) {args.Data}");
_process.Exited += (sender, args) =>
{
if (_process.ExitCode != 0)
Init.Logger.Error(
$"Service {Path.GetFileName(_servicePath)} exited with a non-zero code! ({_process.ExitCode})");
};
}
public static async Task<StartService> InitAsync(string servicePath)
{
var parseServiceFile = await ServiceParser.Parse(servicePath);
return new StartService(servicePath, parseServiceFile);
}
public async void StartServiceAsync()
{
_process.Start();
_process.BeginOutputReadLine();
_process.BeginErrorReadLine();
await _process.WaitForExitAsync();
}
}

View file

@ -6,15 +6,16 @@ namespace netsd.Utils;
public class UDSConnector public class UDSConnector
{ {
private readonly EndPoint _endPoint;
private static readonly string _socketPath = Path.Combine(Path.GetTempPath(), "netsd.sock"); private static readonly string _socketPath = Path.Combine(Path.GetTempPath(), "netsd.sock");
private readonly EndPoint _endPoint;
private UDSConnector(EndPoint endPoint) private UDSConnector(EndPoint endPoint)
{ {
_endPoint = endPoint; _endPoint = endPoint;
} }
private async ValueTask<Stream> _connectAsync(SocketsHttpConnectionContext _, CancellationToken cancellationToken = default) private async ValueTask<Stream> _connectAsync(SocketsHttpConnectionContext _,
CancellationToken cancellationToken = default)
{ {
var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
@ -29,19 +30,19 @@ public class UDSConnector
throw; throw;
} }
} }
public static GrpcChannel CreateChannel() public static GrpcChannel CreateChannel()
{ {
var udsEndPoint = new UnixDomainSocketEndPoint(_socketPath); var udsEndPoint = new UnixDomainSocketEndPoint(_socketPath);
var connectionFactory = new UDSConnector(udsEndPoint); var connectionFactory = new UDSConnector(udsEndPoint);
var socketsHttpHandler = new SocketsHttpHandler var socketsHttpHandler = new SocketsHttpHandler
{ {
ConnectCallback = connectionFactory._connectAsync ConnectCallback = connectionFactory._connectAsync,
}; };
return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
{ {
HttpHandler = socketsHttpHandler HttpHandler = socketsHttpHandler,
}); });
} }
} }

View file

@ -10,10 +10,7 @@
<FileVersion>0.0.0.1</FileVersion> <FileVersion>0.0.0.1</FileVersion>
<Configurations>Release;Debug</Configurations> <Configurations>Release;Debug</Configurations>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<!-- Agressive Optimizations (Saves a lot of mbs for the end user :3) --> <!-- Agressive Trimming (Saves a lot of mbs for the end user :3) -->
<PublishAot>true</PublishAot>
<IlcOptimizationPreference>Size</IlcOptimizationPreference>
<IlcGenerateStackTraceData>false</IlcGenerateStackTraceData>
<StripSymbols>true</StripSymbols> <StripSymbols>true</StripSymbols>
<DebuggerSupport>false</DebuggerSupport> <DebuggerSupport>false</DebuggerSupport>
<EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding> <EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
@ -25,8 +22,10 @@
<MetadataUpdaterSupport>false</MetadataUpdaterSupport> <MetadataUpdaterSupport>false</MetadataUpdaterSupport>
<UseNativeHttpHandler>true</UseNativeHttpHandler> <UseNativeHttpHandler>true</UseNativeHttpHandler>
<UseSystemResourceKeys>true</UseSystemResourceKeys> <UseSystemResourceKeys>true</UseSystemResourceKeys>
<PublishTrimmed>true</PublishTrimmed>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" /> <FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup> </ItemGroup>