Program.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using Edge.Core.Processor;
  6. using Edge.Core.Database;
  7. using System.Diagnostics;
  8. using System.Threading;
  9. using System.Xml;
  10. using System.Security.Cryptography;
  11. using System.Text;
  12. using System.Runtime.InteropServices;
  13. using Microsoft.Extensions.DependencyInjection;
  14. using Microsoft.Extensions.Logging;
  15. using LiteFccCoreMain.Service;
  16. using System.IO.Ports;
  17. using System.Runtime.Loader;
  18. using System.Threading.Tasks;
  19. using System.IO;
  20. using MQTTnet.Server;
  21. using MQTTnet.Protocol;
  22. using MQTTnet.Diagnostics;
  23. using Microsoft.EntityFrameworkCore;
  24. using Edge.Core.Configuration;
  25. using System.Text.RegularExpressions;
  26. using Edge.Core.Processor.Dispatcher;
  27. using Edge.Core.UniversalApi;
  28. namespace LiteFccCoreMain
  29. {
  30. class Program
  31. {
  32. static ILogger mainLogger;//= NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("Main");
  33. static DefaultDispatcher processorsDispatcher = null;
  34. public static async Task Main(string[] args)
  35. {
  36. Console.WriteLine("LiteFccCore is starting...");
  37. var services = ServiceBuilder.Build();
  38. var loggerFactory = services.GetRequiredService<ILoggerFactory>();
  39. mainLogger = loggerFactory.CreateLogger("Main");
  40. string coreVersionStr = $"{Assembly.GetAssembly(typeof(IProcessor)).GetName().Version.ToString()}(core), " +
  41. $"{Assembly.GetAssembly(typeof(Program)).GetName().Version.ToString()}(entry)";
  42. IEnumerable<IProcessor> processorInstances = null;
  43. #region pre-Setup
  44. AppDomain.CurrentDomain.UnhandledException += (sender, arg) =>
  45. {
  46. mainLogger.LogError(string.Format("Unhandled exception from AppDomain.UnhandledException event:\r\n {0}", arg.ExceptionObject));
  47. NLog.LogManager.Shutdown();
  48. };
  49. AppDomain.CurrentDomain.ProcessExit += (s, a) =>
  50. {
  51. mainLogger.LogCritical("!!!!!! Process is exiting... !!!!!!");
  52. Console.WriteLine("Stopping processors...");
  53. mainLogger.LogInformation("Stopping processors...");
  54. var stopResults = processorsDispatcher?.StopProcessorsAsync(processorInstances, "Process is Exiting...")?.Result;
  55. Console.WriteLine("Stopped processors.");
  56. mainLogger.LogInformation("Stopped processors." + Environment.NewLine + Environment.NewLine + Environment.NewLine);
  57. NLog.LogManager.Shutdown();
  58. };
  59. Console.CancelKeyPress += (sender, arg) =>
  60. {
  61. Console.WriteLine("Cancel key: " + arg.SpecialKey + " pressed, will exit whole application...");
  62. mainLogger.LogInformation("Cancel key: " + arg.SpecialKey + " pressed, will exit whole application...");
  63. //shutdown the while LiteFccCore process
  64. Environment.Exit(-1);
  65. };
  66. Console.WriteLine($"Version: {coreVersionStr}");
  67. mainLogger.LogInformation($"Version: {coreVersionStr}");
  68. PerformanceMonitor.Logger = loggerFactory.CreateLogger("Performance");
  69. PerformanceMonitor.Start();
  70. #endregion
  71. var configurator = services.GetService<Configurator>();
  72. #region Migrating database
  73. mainLogger.LogInformation("Migrating database...");
  74. Console.WriteLine("Migrating database...");
  75. var migrateDbContext = services.GetRequiredService<SqliteDbContext>();
  76. try
  77. {
  78. migrateDbContext.Database.Migrate();
  79. }
  80. catch (Exception exx)
  81. {
  82. string migrationsStr = "";
  83. string pendingMigrationsStr = "";
  84. string appliedMigrationsStr = "";
  85. try
  86. {
  87. migrationsStr = migrateDbContext.Database?.GetMigrations()?.Aggregate((acc, n) => acc + ", " + n) ?? "";
  88. pendingMigrationsStr = migrateDbContext.Database?.GetPendingMigrations()?.Aggregate((acc, n) => acc + ", " + n) ?? "";
  89. appliedMigrationsStr = migrateDbContext.Database?.GetAppliedMigrations()?.Aggregate((acc, n) => acc + ", " + n) ?? "";
  90. }
  91. catch
  92. {
  93. mainLogger.LogError("Starting LiteFccCore Exceptioned when Migrating the database, detail: " + exx + System.Environment.NewLine +
  94. "migrations are: " + migrationsStr + System.Environment.NewLine +
  95. ", pendingMigrations are: " + pendingMigrationsStr + System.Environment.NewLine +
  96. ", appliedMigrations are: " + appliedMigrationsStr);
  97. }
  98. throw new InvalidOperationException("Starting LiteFccCore Exceptioned when Migrating the database");
  99. }
  100. mainLogger.LogInformation(" Migrate finished.");
  101. Console.WriteLine($" Migrate finished.{Environment.NewLine}");
  102. #endregion
  103. try
  104. {
  105. processorsDispatcher = new DefaultDispatcher(services);
  106. IEnumerable<ProcessorInstanceOperatingResult> instantiateResults = null;
  107. if (args?.Any(g => g.Equals("--enable-safeboot", StringComparison.OrdinalIgnoreCase)) ?? false)
  108. {
  109. mainLogger.LogInformation("Enabling Safe Boot, Only Loading Core Moduels...");
  110. Console.BackgroundColor = ConsoleColor.Yellow;
  111. Console.ForegroundColor = ConsoleColor.Black;
  112. Console.WriteLine("Enabling Safe Boot, Only Loading Core Moduels...");
  113. Console.ResetColor();
  114. instantiateResults = await processorsDispatcher.CreateProcessorsAsync("Main starting with enabling SafeBoot", true);
  115. }
  116. else
  117. instantiateResults = await processorsDispatcher.CreateProcessorsAsync("Main starting", false);
  118. var startResults = await processorsDispatcher.StartProcessorsAsync(
  119. instantiateResults.Where(r => r.Succeed).Select(r => r.ProcessorInstance),
  120. "Main starting");
  121. processorInstances = startResults.Select(r => r.ProcessorInstance);
  122. processorsDispatcher.OnProcessorInstantiated += (__, arg) =>
  123. {
  124. processorInstances = arg.OperationResults.Select(r => r.ProcessorInstance);
  125. instantiateResults = null;
  126. startResults = null;
  127. };
  128. mainLogger.LogInformation("LiteFccCore is running...");
  129. Console.BackgroundColor = ConsoleColor.Green;
  130. Console.ForegroundColor = ConsoleColor.Black;
  131. Console.WriteLine($"LiteFccCore with version: {coreVersionStr} is running...");
  132. Console.ResetColor();
  133. }
  134. catch (Exception exx)
  135. {
  136. mainLogger.LogError("******Start LiteFccCore internal error!\r\n" + exx.ToString());
  137. Console.BackgroundColor = ConsoleColor.Red;
  138. Console.ForegroundColor = ConsoleColor.Black;
  139. Console.WriteLine("******Start LiteFccCore internal error: " + exx.ToString().Substring(0, 70) + "...");
  140. Console.ResetColor();
  141. }
  142. while (true)
  143. {
  144. // in ARM Linux deamon mode, it always can read an empty line, here have to sleep to avoid quit.
  145. Thread.Sleep(1000);
  146. var read = Console.ReadLine();
  147. }
  148. }
  149. }
  150. }