/// <summary> /// Initializes this instance. /// </summary> public static void Initialize() { if (System.Web.Hosting.HostingEnvironment.InClientBuildManager == true) { // AssemblyInitializer is pre-loaded before RockWeb starts, // but it is also loaded when just loading the Rock solution or building RockWeb! // see https://stackoverflow.com/questions/13642691/avoid-aspnet-compiler-running-preapplicationstart-method/13689600#13689600 // We don't want RockApplicationStartupHelper.RunApplicationStartup to run in the situation, but // we can detect that with System.Web.Hosting.HostingEnvironment.InClientBuildManager // so just exit RockApplicationStartupHelper.LogStartupMessage("AssemblyInitializer started by Visual Studio"); return; } RockApplicationStartupHelper.LogStartupMessage("AssemblyInitializer started by RockWeb"); try { RockApplicationStartupHelper.RunApplicationStartup(); } catch (RockStartupException rockStartupException) { AssemblyInitializerException = rockStartupException; } catch (Exception ex) { AssemblyInitializerException = new RockStartupException("Error occurred in RunApplicationStartup", ex); } }
/// <summary> /// Handles the End event of the Application control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void Application_End(object sender, EventArgs e) { try { // Log the reason that the application end was fired var shutdownReason = System.Web.Hosting.HostingEnvironment.ShutdownReason; // Stop the bus and farm Rock.Bus.RockMessageBus.IsRockStarted = false; Rock.WebFarm.RockWebFarm.Shutdown(shutdownReason); // Tell our CompileThemesThread and BlockTypeCompilationThread to cancel if they aren't done when Rock shuts down if (_threadCancellationTokenSource != null) { _threadCancellationTokenSource.Cancel(); } // Send debug info to debug window System.Diagnostics.Debug.WriteLine(string.Format("shutdownReason:{0}", shutdownReason)); var shutdownMessage = string.Format("Application Ended: {0} (Process ID: {1})", shutdownReason, Rock.WebFarm.RockWebFarm.ProcessId); RockApplicationStartupHelper.LogShutdownMessage(shutdownMessage); // Close out jobs infrastructure if running under IIS bool runJobsInContext = Convert.ToBoolean(ConfigurationManager.AppSettings["RunJobsInIISContext"]); if (runJobsInContext) { if (RockApplicationStartupHelper.QuartzScheduler != null) { RockApplicationStartupHelper.QuartzScheduler.Shutdown(); } } // Process the transaction queue DrainTransactionQueue(); // Mark any user login stored as 'IsOnline' in the database as offline MarkOnlineUsersOffline(); // Auto-restart appdomain restarts (triggered by web.config changes, new dlls in the bin folder, etc.) // These types of restarts don't cause the worker process to restart, but they do cause ASP.NET to unload // the current AppDomain and start up a new one. This will launch a web request which will auto-start Rock // in these cases. // https://weblog.west-wind.com/posts/2013/oct/02/use-iis-application-initialization-for-keeping-aspnet-apps-alive var client = new WebClient(); client.DownloadString(GetKeepAliveUrl()); RockLogger.Log.Close(); } catch { // Intentionally ignore exception } }
/// <summary> /// Handles the Start event of the Application control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void Application_Start(object sender, EventArgs e) { RockApplicationStartupHelper.ShowDebugTimingMessage("Application Start"); Rock.Bus.RockMessageBus.IsRockStarted = false; QueueInUse = false; /* 2020-05-20 MDP * Prior to Application_Start, Rock.WebStartup has an AssemblyInitializer class that runs as a PreApplicationStartMethod. * * This will call RockApplicationStartupHelper which will take care of the following * -- EF Migrations * -- Rock Plugin Migrations (except for ones that are in App_Code) * -- Sending Version update notifications to Spark * -- Pre-loading EntityTypeCache, FieldTypeCache, and AttributeCache * -- Loading any attributes defined in web.config * -- Registering HttpModules * -- Initializing Lava * -- Starting the Job Scheduler (if configured to run) */ /* 2020-05-20 MDP * The remaining items need to be run here in Application_Start since they depend on things that don't happen until now * like Routes, plugin stuff in App_Code */ try { // AssemblyInitializer will catch any exception that it gets and sets AssemblyInitializerException. // Doing this lets us do any error handling (now that RockWeb has started) if (AssemblyInitializer.AssemblyInitializerException != null) { throw AssemblyInitializer.AssemblyInitializerException; } // register the App_Code assembly in the Rock.Reflection helper so that Reflection methods can search for types in it var appCodeAssembly = typeof(Global).Assembly; Rock.Reflection.SetAppCodeAssembly(appCodeAssembly); // Probably won't be any, but run any migrations that might be in App_Code. (Any that are dll's get run in RockApplicationStartupHelper.RunApplicationStartup()) RockApplicationStartupHelper.RunPluginMigrations(appCodeAssembly); // Register Routes RouteTable.Routes.Clear(); Rock.Web.RockRouteHandler.RegisterRoutes(); // Configure Rock Rest API GlobalConfiguration.Configure(Rock.Rest.WebApiConfig.Register); // set the encryption protocols that are permissible for external SSL connections System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; RockApplicationStartupHelper.ShowDebugTimingMessage("Register Routes"); // add call back to keep IIS process awake at night and to provide a timer for the queued transactions AddCallBack(); // register any EntityTypes or FieldTypes that are discovered in Rock or any plugins (including ones in ~/App_Code) EntityTypeService.RegisterEntityTypes(); FieldTypeService.RegisterFieldTypes(); BundleConfig.RegisterBundles(BundleTable.Bundles); // mark any user login stored as 'IsOnline' in the database as offline MarkOnlineUsersOffline(); SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~")); RockApplicationStartupHelper.ShowDebugTimingMessage("Register Types"); RockApplicationStartupHelper.LogStartupMessage("Application Started Successfully"); if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment) { System.Diagnostics.Debug.WriteLine(string.Format("[{0,5:#} ms] Total Startup Time", (RockDateTime.Now - RockApplicationStartupHelper.StartDateTime).TotalMilliseconds)); } ExceptionLogService.AlwaysLogToFile = false; // Perform any Rock startups RunStartups(); } catch (Exception ex) { if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment) { System.Diagnostics.Debug.WriteLine(string.Format("##Startup Exception##: {0}\n{1}", ex.Message, ex.StackTrace)); } SetError66(); var startupException = new RockStartupException("Error occurred during application startup", ex); LogError(startupException, null); throw startupException; } StartBlockTypeCompilationThread(); StartWorkflowActionUpdateAttributesThread(); StartCompileThemesThread(); Rock.Bus.RockMessageBus.IsRockStarted = true; }