Files
Explorer-Workbench/src/Explorer.Host/HostEntry.cs

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;
}
}