private static async Task StartApp(StartupOptions options) { ServerApplicationPaths appPaths = CreateApplicationPaths(options); // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); await CreateLogger(appPaths); _logger = _loggerFactory.CreateLogger("Main"); AppDomain.CurrentDomain.UnhandledException += (sender, e) => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception"); // Intercept Ctrl+C and Ctrl+Break Console.CancelKeyPress += (sender, e) => { if (_tokenSource.IsCancellationRequested) { return; // Already shutting down } e.Cancel = true; _logger.LogInformation("Ctrl+C, shutting down"); Environment.ExitCode = 128 + 2; Shutdown(); }; // Register a SIGTERM handler AppDomain.CurrentDomain.ProcessExit += (sender, e) => { if (_tokenSource.IsCancellationRequested) { return; // Already shutting down } _logger.LogInformation("Received a SIGTERM signal, shutting down"); Environment.ExitCode = 128 + 15; Shutdown(); }; _logger.LogInformation("Jellyfin version: {Version}", Assembly.GetEntryAssembly().GetName().Version); EnvironmentInfo environmentInfo = new EnvironmentInfo(GetOperatingSystem()); ApplicationHost.LogEnvironmentInfo(_logger, appPaths, environmentInfo); SQLitePCL.Batteries_V2.Init(); // Allow all https requests ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return(true); }); var fileSystem = new ManagedFileSystem(_loggerFactory, environmentInfo, null, appPaths.TempDirectory, true); using (var appHost = new CoreAppHost( appPaths, _loggerFactory, options, fileSystem, environmentInfo, new NullImageEncoder(), new NetworkManager(_loggerFactory, environmentInfo))) { await appHost.Init(); appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager); await appHost.RunStartupTasks(); // TODO: read input for a stop command try { // Block main thread until shutdown await Task.Delay(-1, _tokenSource.Token); } catch (TaskCanceledException) { // Don't throw on cancellation } } if (_restartOnShutdown) { StartNewInstance(options); } }
private static async Task StartApp(StartupOptions options) { ServerApplicationPaths appPaths = CreateApplicationPaths(options); // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); IConfiguration appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false); CreateLogger(appConfig, appPaths); _logger = _loggerFactory.CreateLogger("Main"); AppDomain.CurrentDomain.UnhandledException += (sender, e) => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception"); // Intercept Ctrl+C and Ctrl+Break Console.CancelKeyPress += (sender, e) => { if (_tokenSource.IsCancellationRequested) { return; // Already shutting down } e.Cancel = true; _logger.LogInformation("Ctrl+C, shutting down"); Environment.ExitCode = 128 + 2; Shutdown(); }; // Register a SIGTERM handler AppDomain.CurrentDomain.ProcessExit += (sender, e) => { if (_tokenSource.IsCancellationRequested) { return; // Already shutting down } _logger.LogInformation("Received a SIGTERM signal, shutting down"); Environment.ExitCode = 128 + 15; Shutdown(); }; _logger.LogInformation("Jellyfin version: {Version}", Assembly.GetEntryAssembly().GetName().Version); ApplicationHost.LogEnvironmentInfo(_logger, appPaths); // Increase the max http request limit // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others. ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); // Disable the "Expect: 100-Continue" header by default // http://stackoverflow.com/questions/566437/http-post-returns-the-error-417-expectation-failed-c ServicePointManager.Expect100Continue = false; // CA5359: Do Not Disable Certificate Validation #pragma warning disable CA5359 // Allow all https requests ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return(true); }); #pragma warning restore CA5359 Batteries_V2.Init(); if (raw.sqlite3_enable_shared_cache(1) != raw.SQLITE_OK) { _logger.LogWarning("Failed to enable shared cache for SQLite"); } var appHost = new CoreAppHost( appPaths, _loggerFactory, options, new ManagedFileSystem(_loggerFactory.CreateLogger <ManagedFileSystem>(), appPaths), new NullImageEncoder(), new NetworkManager(_loggerFactory.CreateLogger <NetworkManager>()), appConfig); try { await appHost.InitAsync(new ServiceCollection()).ConfigureAwait(false); appHost.ImageProcessor.ImageEncoder = GetImageEncoder(appPaths, appHost.LocalizationManager); await appHost.RunStartupTasksAsync().ConfigureAwait(false); // Block main thread until shutdown await Task.Delay(-1, _tokenSource.Token).ConfigureAwait(false); } catch (TaskCanceledException) { // Don't throw on cancellation } catch (Exception ex) { _logger.LogCritical(ex, "Error while starting server."); } finally { appHost?.Dispose(); } if (_restartOnShutdown) { StartNewInstance(options); } }
private static async Task StartApp(StartupOptions options) { ServerApplicationPaths appPaths = CreateApplicationPaths(options); // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); appConfig = await CreateConfiguration(appPaths).ConfigureAwait(false); CreateLogger(appConfig, appPaths); _logger = _loggerFactory.CreateLogger("Main"); AppDomain.CurrentDomain.UnhandledException += (sender, e) => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception"); // Intercept Ctrl+C and Ctrl+Break Console.CancelKeyPress += (sender, e) => { if (_tokenSource.IsCancellationRequested) { return; // Already shutting down } e.Cancel = true; _logger.LogInformation("Ctrl+C, shutting down"); Environment.ExitCode = 128 + 2; Shutdown(); }; // Register a SIGTERM handler AppDomain.CurrentDomain.ProcessExit += (sender, e) => { if (_tokenSource.IsCancellationRequested) { return; // Already shutting down } _logger.LogInformation("Received a SIGTERM signal, shutting down"); Environment.ExitCode = 128 + 15; Shutdown(); }; _logger.LogInformation("Jellyfin version: {Version}", Assembly.GetEntryAssembly().GetName().Version); ApplicationHost.LogEnvironmentInfo(_logger, appPaths); SQLitePCL.Batteries_V2.Init(); // Increase the max http request limit // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others. ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); // CA5359: Do Not Disable Certificate Validation #pragma warning disable CA5359 // Allow all https requests ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return(true); }); #pragma warning restore CA5359 var fileSystem = new ManagedFileSystem(_loggerFactory, appPaths); using (var appHost = new CoreAppHost( appPaths, _loggerFactory, options, fileSystem, new NullImageEncoder(), new NetworkManager(_loggerFactory), appConfig)) { await appHost.InitAsync(new ServiceCollection()).ConfigureAwait(false); appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager); await appHost.RunStartupTasksAsync().ConfigureAwait(false); try { // Block main thread until shutdown await Task.Delay(-1, _tokenSource.Token).ConfigureAwait(false); } catch (TaskCanceledException) { // Don't throw on cancellation } } if (_restartOnShutdown) { StartNewInstance(options); } }
static void Main() { ApplicationPath = Assembly.GetEntryAssembly().Location; var environmentInfo = GetEnvironmentInfo(); var appPaths = new ApplicationPaths(GetProgramDataPath(ApplicationPath), ApplicationPath); _appPaths = appPaths; using (var logManager = new SimpleLogManager(appPaths.LogDirectoryPath, "theater")) { _logManager = logManager; logManager.ReloadLogger(LogSeverity.Debug); logManager.AddConsoleOutput(); var logger = _logger = logManager.GetLogger("Main"); logger.Info("Application path: {0}", ApplicationPath); ApplicationHost.LogEnvironmentInfo(logger, appPaths, true); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; // Mutex credit: https://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/229567 // unique id for global mutex - Global prefix means it is global to the machine string mutexId = string.Format("Global\\{{{0}}}", "EmbyTheater"); // Need a place to store a return value in Mutex() constructor call bool createdNew; // edited by MasonGZhwiti to prevent race condition on security settings via VanNguyen using (var mutex = new Mutex(false, mutexId, out createdNew)) { // edited by acidzombie24 var hasHandle = false; try { // note, you may want to time out here instead of waiting forever // edited by acidzombie24 hasHandle = mutex.WaitOne(5000, false); if (hasHandle == false) { logger.Info("Exiting because another instance is already running."); return; } } catch (AbandonedMutexException) { // Log the fact that the mutex was abandoned in another process, // it will still get acquired hasHandle = true; logger.Info("Mutex was abandoned in another process."); } using (new MutexHandle(mutex, hasHandle, _logger)) { if (PerformUpdateIfNeeded(appPaths, environmentInfo, logger)) { logger.Info("Exiting to perform application update."); return; } RunApplication(appPaths, logManager, environmentInfo, new StartupOptions(Environment.GetCommandLineArgs())); } } logger.Info("Shutdown complete"); if (_restartOnShutdown) { // This is artificial, but add some delay to ensure sockets are released. var delay = environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows ? 5000 : 60000; var task = Task.Delay(delay); Task.WaitAll(task); logger.Info("Starting new server process"); var restartCommandLine = GetRestartCommandLine(); Process.Start(restartCommandLine.Item1, restartCommandLine.Item2); } } }
public static async Task <int> Main(string[] args) { StartupOptions options = new StartupOptions(args); Version version = Assembly.GetEntryAssembly().GetName().Version; if (options.ContainsOption("-v") || options.ContainsOption("--version")) { Console.WriteLine(version.ToString()); return(0); } ServerApplicationPaths appPaths = createApplicationPaths(options); // $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath); await createLogger(appPaths); _loggerFactory = new SerilogLoggerFactory(); _logger = _loggerFactory.CreateLogger("Main"); AppDomain.CurrentDomain.UnhandledException += (sender, e) => _logger.LogCritical((Exception)e.ExceptionObject, "Unhandled Exception"); _logger.LogInformation("Jellyfin version: {Version}", version); EnvironmentInfo environmentInfo = new EnvironmentInfo(getOperatingSystem()); ApplicationHost.LogEnvironmentInfo(_logger, appPaths, environmentInfo); SQLitePCL.Batteries_V2.Init(); // Allow all https requests ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return(true); }); var fileSystem = new ManagedFileSystem(_loggerFactory.CreateLogger("FileSystem"), environmentInfo, null, appPaths.TempDirectory, true); using (var appHost = new CoreAppHost( appPaths, _loggerFactory, options, fileSystem, environmentInfo, new NullImageEncoder(), new SystemEvents(_loggerFactory.CreateLogger("SystemEvents")), new NetworkManager(_loggerFactory.CreateLogger("NetworkManager"), environmentInfo))) { appHost.Init(); appHost.ImageProcessor.ImageEncoder = getImageEncoder(_logger, fileSystem, options, () => appHost.HttpClient, appPaths, environmentInfo, appHost.LocalizationManager); _logger.LogInformation("Running startup tasks"); await appHost.RunStartupTasks(); // TODO: read input for a stop command // Block main thread until shutdown await ApplicationTaskCompletionSource.Task; _logger.LogInformation("Disposing app host"); } if (_restartOnShutdown) { StartNewInstance(options); } return(0); }
/// <summary> /// Begins the log. /// </summary> /// <param name="logger">The logger.</param> private static void BeginLog(ILogger logger, IApplicationPaths appPaths) { logger.Info("Media Browser Server started"); ApplicationHost.LogEnvironmentInfo(logger, appPaths); }