routing - handle when umbraco is not ready or has no content

This commit is contained in:
Stephan
2012-09-28 11:11:47 -02:00
parent d82cbfccc5
commit abe4944843
6 changed files with 58 additions and 51 deletions

View File

@@ -36,6 +36,7 @@ namespace Umbraco.Core
// note - the original umbraco module checks on content.Instance in umbraco.dll
// now, the boot task that setup the content store ensures that it is ready
bool _isReady = false;
System.Threading.ManualResetEventSlim _isReadyEvent = new System.Threading.ManualResetEventSlim(false);
public bool IsReady
{
get
@@ -46,9 +47,15 @@ namespace Umbraco.Core
{
AssertIsNotReady();
_isReady = value;
_isReadyEvent.Set();
}
}
public bool WaitForReady(int timeout)
{
return _isReadyEvent.WaitHandle.WaitOne(timeout);
}
// notes
// GlobalSettings.ConfigurationStatus returns the value that's in the web.config, so it's the "configured version"

View File

@@ -145,14 +145,9 @@ namespace Umbraco.Core.Configuration
/// </summary>
internal static string BootSplashPage
{
get { return "~/default.aspx"; }
get { return "~/config/splashes/booting.aspx"; }
}
internal static string NoContentSplashPage
{
get { return "~/config/splashes/noNodes.aspx"; }
}
/// <summary>
/// Gets a value indicating whether logging is enabled in umbracoSettings.config (/settings/logging/enableLogging).
/// </summary>

View File

@@ -33,10 +33,7 @@ namespace Umbraco.Core
_timer = DisposableTimer.Start(x => LogHelper.Info<CoreBootManager>("Umbraco application startup complete" + " (took " + x + "ms)"));
//create the ApplicationContext
ApplicationContext = ApplicationContext.Current = new ApplicationContext()
{
IsReady = true // fixme
};
ApplicationContext = ApplicationContext.Current = new ApplicationContext();
InitializeResolvers();

View File

@@ -1,19 +1,18 @@
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="booting.aspx.cs" Inherits="umbraco.presentation.config.splashes.booting" %>
<%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Website booting</title>
<META HTTP-EQUIV=REFRESH CONTENT="10; URL=<%=Request["orgUrl"] %>">
<title>The website is restarting</title>
<META HTTP-EQUIV=REFRESH CONTENT="10; URL=<%=Request["url"] %>">
</head>
<body>
<h1>Website is restarting</h1>
<p>The webpage cannot be displayed right now.</p>
<p>This page will refresh in ten seconds.</p>
<h1>The website is restarting</h1>
<p>Please wait for 10s while we prepare to serve the page you have requested...</p>
<div style="border-top: 1px solid #999; padding-top: 5px">
<p>You can modify the design of this page by editing /config/splashes/booting.aspx</p>
</div>
<p style="border-top: 1px solid #ccc; padding-top: 10px;">
<small>You can modify the design of this page by editing /config/splashes/booting.aspx</small>
</p>
</body>
</html>

View File

@@ -283,52 +283,58 @@ namespace Umbraco.Web
// if yes, return true
bool EnsureIsReady(HttpContextBase httpContext, Uri uri)
{
var ready = ApplicationContext.Current.IsReady;
// ensure we are ready
if (!ApplicationContext.Current.IsReady)
if (!ready)
{
LogHelper.Warn<UmbracoModule>("Umbraco is not ready");
httpContext.Response.StatusCode = 503;
// fixme - default.aspx has to be ready for RequestContext.DocumentRequest==null
// fixme - in fact we should transfer to an empty html page...
var bootUrl = UriUtility.ToAbsolute(UmbracoSettings.BootSplashPage);
if (UmbracoSettings.EnableSplashWhileLoading) // legacy - should go
if (!UmbracoSettings.EnableSplashWhileLoading)
{
var configPath = UriUtility.ToAbsolute(SystemDirectories.Config);
bootUrl = string.Format("{0}/splashes/booting.aspx?url={1}", configPath, HttpUtility.UrlEncode(uri.ToString()));
// fixme ?orgurl=... ?retry=...
// let requests pile up and wait for 10s then show the splash anyway
ready = ApplicationContext.Current.WaitForReady(10 * 1000);
}
httpContext.RewritePath(bootUrl);
if (!ready)
{
httpContext.Response.StatusCode = 503;
return false;
var bootUrl = UmbracoSettings.BootSplashPage;
if (string.IsNullOrWhiteSpace(bootUrl))
bootUrl = "~/config/splashes/booting.aspx";
httpContext.RewritePath(UriUtility.ToAbsolute(bootUrl) + "?url=" + HttpUtility.UrlEncode(uri.ToString()));
return false;
}
}
return true;
}
// ensures Umbraco has at least one published node
// if not, rewrites to splash and return false
// if yes, return true
bool EnsureHasContent(HttpContextBase httpContext)
{
var context = UmbracoContext.Current;
var store = context.RoutingContext.PublishedContentStore;
if (!store.HasContent(context))
{
LogHelper.Warn<UmbracoModule>("Umbraco has not content");
// ensures Umbraco has at least one published node
// if not, rewrites to splash and return false
// if yes, return true
bool EnsureHasContent(HttpContextBase httpContext)
{
var context = UmbracoContext.Current;
var store = context.RoutingContext.PublishedContentStore;
if (!store.HasContent(context))
{
LogHelper.Warn<UmbracoModule>("Umbraco has no content");
var noContentUrl = UriUtility.ToAbsolute(UmbracoSettings.NoContentSplashPage);
httpContext.RewritePath(noContentUrl);
return false;
}
else
{
return true;
}
}
httpContext.Response.StatusCode = 503;
var noContentUrl = "~/config/splashes/noNodes.aspx";
httpContext.RewritePath(UriUtility.ToAbsolute(noContentUrl));
return false;
}
else
{
return true;
}
}
// ensures Umbraco is configured
// if not, redirect to install and return false

View File

@@ -108,6 +108,9 @@ namespace Umbraco.Web
ApplicationEventsResolver.Current.ApplicationEventHandlers
.ForEach(x => x.OnApplicationStarted(_umbracoApplication, ApplicationContext));
// we're ready to serve content!
ApplicationContext.IsReady = true;
return this;
}