mirror of https://github.com/ogoun/Zero.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
8.1 KiB
216 lines
8.1 KiB
using System;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using ZeroLevel.Logging;
|
|
using ZeroLevel.Network;
|
|
|
|
namespace ZeroLevel
|
|
{
|
|
public static class Bootstrap
|
|
{
|
|
public interface IServiceExecution
|
|
{
|
|
IServiceExecution Run();
|
|
IServiceExecution WaitForStatus(ZeroServiceStatus status);
|
|
IServiceExecution WaitForStatus(ZeroServiceStatus status, TimeSpan period);
|
|
IServiceExecution WaitWhileStatus(ZeroServiceStatus status);
|
|
IServiceExecution WaitWhileStatus(ZeroServiceStatus status, TimeSpan period);
|
|
IServiceExecution Stop();
|
|
IZeroService Service { get; }
|
|
ZeroServiceStatus Status { get; }
|
|
}
|
|
|
|
public class BootstrapFluent
|
|
: IServiceExecution
|
|
{
|
|
private readonly IZeroService _service;
|
|
public IZeroService Service { get { return _service; } }
|
|
|
|
public BootstrapFluent(IZeroService service)
|
|
{
|
|
if (service == null!)
|
|
{
|
|
throw new ArgumentNullException(nameof(service));
|
|
}
|
|
_service = service;
|
|
}
|
|
|
|
public BootstrapFluent UseDiscovery() { _service?.UseDiscovery(); return this; }
|
|
public BootstrapFluent UseDiscovery(string url) { _service?.UseDiscovery(url); return this; }
|
|
public BootstrapFluent UseDiscovery(IPEndPoint endpoint) { _service?.UseDiscovery(endpoint); return this; }
|
|
|
|
public BootstrapFluent ReadServiceInfo() { _service?.ReadServiceInfo(); return this; }
|
|
public BootstrapFluent ReadServiceInfo(IConfigurationSet config) { _service?.ReadServiceInfo(config); return this; }
|
|
|
|
public BootstrapFluent EnableConsoleLog(LogLevel level = LogLevel.FullStandart) { Log.AddConsoleLogger(level); return this; }
|
|
|
|
public ZeroServiceStatus Status { get { return _service.Status; } }
|
|
|
|
public IServiceExecution Run()
|
|
{
|
|
try
|
|
{
|
|
_service?.Start();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex, $"[Bootstrap] Service {_service?.Name} run error");
|
|
return null!;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public IServiceExecution Stop()
|
|
{
|
|
try
|
|
{
|
|
_service?.Stop();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex, $"[Bootstrap] Service {_service?.Name} dispose error");
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public IServiceExecution WaitForStatus(ZeroServiceStatus status)
|
|
{
|
|
_service.WaitForStatus(status);
|
|
return this;
|
|
}
|
|
public IServiceExecution WaitForStatus(ZeroServiceStatus status, TimeSpan period)
|
|
{
|
|
_service.WaitForStatus(status, period);
|
|
return this;
|
|
}
|
|
public IServiceExecution WaitWhileStatus(ZeroServiceStatus status)
|
|
{
|
|
_service.WaitWhileStatus(status);
|
|
return this;
|
|
}
|
|
public IServiceExecution WaitWhileStatus(ZeroServiceStatus status, TimeSpan period)
|
|
{
|
|
_service.WaitWhileStatus(status, period);
|
|
return this;
|
|
}
|
|
}
|
|
|
|
static Bootstrap()
|
|
{
|
|
// Tricks for minimize config changes for dependency resolve
|
|
//AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
|
}
|
|
|
|
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
|
{
|
|
try
|
|
{
|
|
Log.Info($"[Bootstrap] Resolve assembly '{args.Name}' {args.Name}");
|
|
string name = args.Name.Split(',')[0];
|
|
if (name.EndsWith(".resources")) return null!;
|
|
foreach (string file in Directory.
|
|
GetFiles(Path.Combine(Configuration.BaseDirectory), "*.dll", SearchOption.TopDirectoryOnly))
|
|
{
|
|
if (file.IndexOf(name, StringComparison.OrdinalIgnoreCase) >= 0)
|
|
{
|
|
Log.Info($"[Bootstrap] Resolve assembly '{args.Name}' found '{file}'");
|
|
return Assembly.LoadFile(file);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex, $"[Bootstrap] Fault load assembly '{args.Name}'");
|
|
}
|
|
return null!;
|
|
}
|
|
|
|
public static BootstrapFluent Startup<T>(string[] args,
|
|
Func<bool> preStartConfiguration = null!,
|
|
Func<bool> postStartConfiguration = null!)
|
|
where T : IZeroService
|
|
{
|
|
var service = Initialize<T>(args, null!,
|
|
preStartConfiguration, postStartConfiguration);
|
|
return new BootstrapFluent(service);
|
|
}
|
|
|
|
public static BootstrapFluent Startup<T>(string[] args,
|
|
Func<IConfigurationSet> configuration,
|
|
Func<bool> preStartConfiguration = null!,
|
|
Func<bool> postStartConfiguration = null!)
|
|
where T : IZeroService
|
|
{
|
|
var service = Initialize<T>(args, configuration?.Invoke()!, preStartConfiguration, postStartConfiguration);
|
|
return new BootstrapFluent(service);
|
|
}
|
|
|
|
private static IZeroService Initialize<T>(string[] args,
|
|
IConfigurationSet configurationSet,
|
|
Func<bool> preStartConfiguration = null!,
|
|
Func<bool> postStartConfiguration = null!)
|
|
where T : IZeroService
|
|
{
|
|
IZeroService service = null!;
|
|
IConfigurationSet config = Configuration.DefaultSet;
|
|
config.CreateSection("commandline", Configuration.ReadFromCommandLine(args));
|
|
if (configurationSet != null!)
|
|
{
|
|
config.Merge(configurationSet);
|
|
}
|
|
Log.CreateLoggingFromConfiguration(Configuration.DefaultSet);
|
|
|
|
if (preStartConfiguration != null!)
|
|
{
|
|
try
|
|
{
|
|
if (preStartConfiguration() == false)
|
|
{
|
|
Log.SystemInfo("[Bootstrap] Service start canceled, because custom preconfig return false");
|
|
return null!;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.SystemError(ex, "[Bootstrap] Service start canceled, preconfig faulted");
|
|
return null!;
|
|
}
|
|
}
|
|
try
|
|
{
|
|
service = Activator.CreateInstance<T>();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.SystemError(ex, "[Bootstrap] Service start canceled, service constructor call fault");
|
|
}
|
|
if (postStartConfiguration != null!)
|
|
{
|
|
try
|
|
{
|
|
if (postStartConfiguration() == false)
|
|
{
|
|
Log.SystemInfo("[Bootstrap] Service start canceled, because custom postconfig return false");
|
|
return null!;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.SystemError(ex, "[Bootstrap] Service start canceled, postconfig faulted");
|
|
return null!;
|
|
}
|
|
}
|
|
return service;
|
|
}
|
|
|
|
public static IExchange CreateExchange() => new Exchange(null!);
|
|
|
|
public static void Shutdown()
|
|
{
|
|
try { Sheduller.Dispose(); } catch (Exception ex) { Log.Error(ex, "[Bootstrap] Dispose default sheduller error"); }
|
|
try { Log.Dispose(); } catch (Exception ex) { Log.Error(ex, "[Bootstrap] Dispose log error"); }
|
|
try { Injector.Default.Dispose(); Injector.Dispose(); } catch (Exception ex) { Log.Error(ex, "[Bootstrap] Dispose DI containers error"); }
|
|
}
|
|
}
|
|
} |