some re-architectoring and code cleanups
This commit is contained in:
parent
50b682c875
commit
af700c798e
9 changed files with 81 additions and 55 deletions
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
6
netsd/Utils/Globals.cs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
namespace netsd.Utils;
|
||||||
|
|
||||||
|
public static class Globals
|
||||||
|
{
|
||||||
|
public static List<StartService> Services = new();
|
||||||
|
}
|
|
@ -16,5 +16,5 @@ public class ServiceParser
|
||||||
sv.ExecStart = serviceData["Service"]["ExecStart"];
|
sv.ExecStart = serviceData["Service"]["ExecStart"];
|
||||||
|
|
||||||
return sv;
|
return sv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
51
netsd/Utils/StartService.cs
Normal file
51
netsd/Utils/StartService.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Reference in a new issue