예제 #1
0
 private void responseExceptionHandler(HttpRequest req, Exception exception, HttpResponse resp)
 {
     lock (_log)
     {
         if (req != null && resp != null)
         {
             _log.Error("Error in response for request {0}, status code {1}:".Fmt(req.Url.ToFull(), (int)resp.Status));
         }
         PropellerUtil.LogException(_log, exception);
     }
 }
예제 #2
0
        public override int Execute()
        {
            PropellerUtil.RunStandalone(ConfigFile ?? @"D:\Daten\Config\Zinga.config.json", new ZingaPropellerModule(),
#if DEBUG
                                        true
#else
                                        false
#endif
                                        );
            return(0);
        }
예제 #3
0
 private HttpResponse errorHandler(HttpRequest req, Exception exception)
 {
     if (exception is HttpException httpExc)
     {
         _log.Info("Request {0} failure code {1}.".Fmt(req.Url.ToFull(), (int)httpExc.StatusCode));
     }
     else
     {
         lock (_log)
         {
             _log.Error("Error in handler for request {0}:".Fmt(req.Url.ToFull()));
             PropellerUtil.LogException(_log, exception);
         }
     }
     throw exception;
 }
예제 #4
0
        public void Start(string settingsPath, bool backgroundThread = false)
        {
            _settingsPath = settingsPath ?? SettingsUtil.GetAttribute <PropellerSettings>().GetFileName();

            // Do one reinitialization outside of the periodic schedule so that if the first initialization fails, the service doesn’t start
            try
            {
                reinitialize();
            }
            catch (Exception e)
            {
                PropellerUtil.LogException(_log ?? new ConsoleLogger(), e);
                throw;
            }

            // Now start the periodic checking that might trigger reinitialization
            base.Start(backgroundThread);
        }
예제 #5
0
        public static int Main(string[] args)
        {
            try { Console.OutputEncoding = Encoding.UTF8; }
            catch { }

            if (args.Length == 2 && args[0] == "--post-build-check")
            {
                return(PostBuildChecker.RunPostBuildChecks(args[1], Assembly.GetExecutingAssembly()));
            }

            Console.BackgroundColor = IsDebug ? ConsoleColor.DarkBlue : ConsoleColor.DarkRed;
            Console.ForegroundColor = ConsoleColor.White;
            var msg    = IsDebug ? "DEBUG MODE" : "RELEASE MODE";
            var spaces = new string(' ', (Console.BufferWidth - msg.Length - 7) / 2);

            Console.WriteLine("{0}┌──{1}──╖{0}".Fmt(spaces, new string('─', msg.Length)));
            Console.WriteLine("{0}│  {1}  ║{0}".Fmt(spaces, msg));
            Console.WriteLine("{0}╘══{1}══╝{0}".Fmt(spaces, new string('═', msg.Length)));
            Console.ResetColor();

            PropellerUtil.RunStandalone(PathUtil.AppPathCombine("DocGen.Settings.json"), new DocGenPropellerModule());
            return(0);
        }
예제 #6
0
        private bool reinitialize()
        {
            // If we are already initialized and the settings file hasn’t changed, we don’t need to do anything.
            var firstRunEver = _server == null;

            if (_server != null && File.GetLastWriteTimeUtc(_settingsPath) <= _settingsLastChangedTime)
            {
                return(false);
            }

            // This may load *and re-write* the settings file...
            var newSettings = PropellerUtil.LoadSettings(_settingsPath, firstRunEver ? new ConsoleLogger() : _log, firstRunEver);

            // ... so remember the file date/time stamp *after* the writing
            _settingsLastChangedTime = File.GetLastWriteTimeUtc(_settingsPath);

            _log = PropellerUtil.GetLogger(true, newSettings.LogFile, newSettings.LogVerbosity);
            _log.Info(firstRunEver ? "Initializing Propeller" : "Reinitializing Propeller");

            // If either port number or the bind-to address have changed, stop and restart the server’s listener.
            var startListening = false;

            if (_server == null || CurrentSettings == null ||
                !CurrentSettings.ServerOptions.Endpoints.Values.SequenceEqual(newSettings.ServerOptions.Endpoints.Values))
            {
                var removed = CurrentSettings == null ? new HttpEndpoint[0] : CurrentSettings.ServerOptions.Endpoints.Values.Except(newSettings.ServerOptions.Endpoints.Values).ToArray();
                var added   = CurrentSettings == null?newSettings.ServerOptions.Endpoints.Values.ToArray() : newSettings.ServerOptions.Endpoints.Values.Except(CurrentSettings.ServerOptions.Endpoints.Values).ToArray();

                if (_server == null || removed.Length > 0 || added.Length > 0)
                {
                    if (removed.Length > 0)
                    {
                        _log.Info("Disabling {0}".Fmt(removed.Select(ep => "HTTP{0} on port {1}".Fmt(ep.Secure ? "S" : null, ep.Port)).JoinString(", ", lastSeparator: " and ")));
                    }
                    if (added.Length > 0)
                    {
                        _log.Info("Enabling {0}".Fmt(added.Select(ep => "HTTP{0} on port {1}".Fmt(ep.Secure ? "S" : null, ep.Port)).JoinString(", ", lastSeparator: " and ")));
                    }

                    if (_server == null)
                    {
                        _server = new HttpServer
                        {
                            Options                  = newSettings.ServerOptions,
                            ErrorHandler             = errorHandler,
                            ResponseExceptionHandler = responseExceptionHandler
                        }
                    }
                    ;
                    else
                    {
                        _server.StopListening();
                    }
                    startListening = true;
                }
            }

            CurrentSettings = newSettings;

            // Create a new instance of all the modules
            var newAppDomains = new HashSet <AppDomainInfo>();

            foreach (var module in newSettings.Modules)
            {
                _log.Info("Initializing module: " + module.ModuleName);
                try
                {
                    var inf = new AppDomainInfo(_log, newSettings, module, new SettingsSaver(s =>
                    {
                        module.Settings        = s;
                        _settingsSavedByModule = true;
                    }));
                    newAppDomains.Add(inf);
                }
                catch (Exception e)
                {
                    _log.Error("Failed to initialize module {0}:".Fmt(module.ModuleName));
                    _log.Exception(e);
                }
            }

            // Switcheroo!
            lock (_lockObject)
            {
                _log.Info("AppDomain Switcheroo");
                _inactiveAppDomains.AddRange(_activeAppDomains);
                _activeAppDomains = newAppDomains;
                _server.Options   = newSettings.ServerOptions;
                _server.Handler   = createResolver().Handle;
                _server.Log       = PropellerUtil.GetLogger(newSettings.HttpAccessLogToConsole, newSettings.HttpAccessLogFile, newSettings.HttpAccessLogVerbosity);
                if (startListening)
                {
                    _server.StartListening();
                }
            }

            // Delete any remaining temp folders no longer in use
            HashSet <string> tempFoldersInUse;

            lock (_lockObject)
                tempFoldersInUse = _activeAppDomains.Concat(_inactiveAppDomains).Select(ad => ad.TempPathUsed).ToHashSet();
            foreach (var tempFolder in Directory.EnumerateDirectories(CurrentSettings.TempFolder ?? Path.GetTempPath(), "propeller-tmp-*"))
            {
                if (tempFoldersInUse.Contains(tempFolder))
                {
                    continue;
                }
                try { Directory.Delete(tempFolder, recursive: true); }
                catch { }
            }

            return(true);
        }
예제 #7
0
        private void checkSettingsChanges()
        {
            try
            {
                // ① If the server settings have changed, reinitialize everything.
                if (reinitialize())
                {
                    return;
                }

                // ② If a module rewrote its settings, save the settings file.
                if (_settingsSavedByModule)
                {
                    _log.Debug("A module saved the settings.");
                    try
                    {
                        lock (_lockObject)
                            CurrentSettings.Save(_settingsPath);
                    }
                    catch (Exception e)
                    {
                        _log.Error("Error saving Propeller settings:");
                        PropellerUtil.LogException(_log, e);
                    }
                    _settingsSavedByModule   = false;
                    _settingsLastChangedTime = File.GetLastWriteTimeUtc(_settingsPath);
                }

                // ③ If any module wants to reinitialize, do it
                AppDomainInfo[] actives;
                lock (_lockObject)
                    actives = _activeAppDomains.ToArray();
                foreach (var active in actives)
                {
                    if (!active.MustReinitialize)   // this adds a log message if it returns true
                    {
                        continue;
                    }
                    _log.Info("Module says it must reinitialize: {0} ({1})".Fmt(active.ModuleSettings.ModuleName, active.GetHashCode()));
                    var newAppDomain = new AppDomainInfo(_log, CurrentSettings, active.ModuleSettings, active.Saver);
                    lock (_lockObject)
                    {
                        _inactiveAppDomains.Add(active);
                        _activeAppDomains.Remove(active);
                        _activeAppDomains.Add(newAppDomain);
                        _server.Handler = createResolver().Handle;
                        _log.Info(" --- {0} replaced with {1}, {0} shutting down".Fmt(active.GetHashCode(), newAppDomain.GetHashCode()));
                        active.RunnerProxy.Shutdown();
                    }
                }

                // ④ Try to clean up as many inactive AppDomains as possible
                AppDomainInfo[] inactives;
                lock (_lockObject)
                    inactives = _inactiveAppDomains.ToArray();
                foreach (var inactive in inactives)
                {
                    // Ask the runner if it has active connections; if this throws, it’s in a broken state anyway, so unload it by force.
                    bool disposeAllowed;
                    try { disposeAllowed = inactive.HasActiveConnections; }
                    catch { disposeAllowed = true; }

                    if (disposeAllowed)
                    {
                        _log.Info("Disposing inactive module: {0} ({1})".Fmt(inactive.ModuleSettings.ModuleName, inactive.GetHashCode()));
                        lock (_lockObject)
                            _inactiveAppDomains.Remove(inactive);
                        try { inactive.Dispose(); }
                        catch { }
                    }
                    else
                    {
                        _log.Info("Inactive module still has active connections: {0} ({1})".Fmt(inactive.ModuleSettings.ModuleName, inactive.GetHashCode()));
                    }
                }
            }
            catch (Exception e)
            {
                PropellerUtil.LogException(_log, e);
            }
        }
예제 #8
0
 static void Main(string[] args)
 {
     PropellerUtil.RunStandalone(PathUtil.AppPathCombine("KTANE-Propeller-standalone.json"), new KtanePropellerModule());
 }
예제 #9
0
 static void Main(string[] args)
 {
     PropellerUtil.RunStandalone(PathUtil.AppPathCombine("Bot-Propeller-standalone.json"), new BotServer());
 }