88 lines
2.8 KiB
C#
88 lines
2.8 KiB
C#
using System.Runtime.CompilerServices;
|
|
using Explorer.Hosting;
|
|
using Explorer.Hosting.Ipc;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Serilog;
|
|
using Serilog.Extensions.Logging;
|
|
|
|
namespace Explorer.Host;
|
|
|
|
internal static class HostEntry
|
|
{
|
|
public static async Task<int> RunAsync(string[] args, Action<string> boot)
|
|
{
|
|
using var loggerFactory = new SerilogLoggerFactory(Log.Logger, dispose: false);
|
|
var deferred = new DeferredServiceProvider();
|
|
var pipe = new WorkbenchPipeServer(
|
|
deferred,
|
|
new WorkbenchIpcOptions(),
|
|
loggerFactory.CreateLogger<WorkbenchPipeServer>());
|
|
await pipe.StartAsync(CancellationToken.None).ConfigureAwait(false);
|
|
await pipe.Listening.WaitAsync(TimeSpan.FromSeconds(5)).ConfigureAwait(false);
|
|
boot("Pipe listening");
|
|
Log.Information("Named pipe {Pipe} is listening; loading the rest of the host", new WorkbenchIpcOptions().PipeName);
|
|
|
|
using var stopping = new CancellationTokenSource();
|
|
pipe.ShutdownRequested = () => stopping.Cancel();
|
|
using var tray = new HostTray(pipe.RequestShutdown);
|
|
tray.Start();
|
|
|
|
try
|
|
{
|
|
return await RunCoreAsync(args, deferred, boot, stopping.Token).ConfigureAwait(false);
|
|
}
|
|
finally
|
|
{
|
|
try
|
|
{
|
|
await pipe.StopAsync(CancellationToken.None).ConfigureAwait(false);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Debug(ex, "Pipe server stop");
|
|
}
|
|
}
|
|
}
|
|
|
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
private static async Task<int> RunCoreAsync(
|
|
string[] args,
|
|
DeferredServiceProvider deferred,
|
|
Action<string> boot,
|
|
CancellationToken shutdown)
|
|
{
|
|
if (shutdown.IsCancellationRequested)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
var builder = Microsoft.Extensions.Hosting.Host.CreateApplicationBuilder(args);
|
|
builder.Services.Configure<HostOptions>(options => options.ServicesStartConcurrently = true);
|
|
builder.Services.AddExplorerHostProcess();
|
|
using var host = builder.Build();
|
|
using var stop = shutdown.Register(() =>
|
|
host.Services.GetRequiredService<IHostApplicationLifetime>().StopApplication());
|
|
if (shutdown.IsCancellationRequested)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
await host.StartAsync().ConfigureAwait(false);
|
|
deferred.Complete(host.Services);
|
|
boot("Core ready");
|
|
Log.Information("Host core is ready");
|
|
try
|
|
{
|
|
await host.WaitForShutdownAsync().ConfigureAwait(false);
|
|
}
|
|
finally
|
|
{
|
|
await host.StopAsync().ConfigureAwait(false);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|