U4-7949 The task runner has completed YSOD when using the Umbraco Package installer
This commit is contained in:
@@ -217,7 +217,11 @@ namespace Umbraco.Web.Scheduling
|
||||
{
|
||||
lock (_locker)
|
||||
{
|
||||
if (_isCompleted) return false;
|
||||
if (_isCompleted)
|
||||
{
|
||||
_logger.Debug<BackgroundTaskRunner>(_logPrefix + "Task cannot be added {0}, the task runner is already shutdown", task.GetType);
|
||||
return false;
|
||||
}
|
||||
|
||||
// add task
|
||||
_logger.Debug<BackgroundTaskRunner>(_logPrefix + "Task added {0}", task.GetType);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using System.Web;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Scheduling
|
||||
{
|
||||
@@ -14,60 +17,74 @@ namespace Umbraco.Web.Scheduling
|
||||
/// </remarks>
|
||||
internal sealed class Scheduler : ApplicationEventHandler
|
||||
{
|
||||
private static BackgroundTaskRunner<IBackgroundTask> _keepAliveRunner;
|
||||
private static BackgroundTaskRunner<IBackgroundTask> _publishingRunner;
|
||||
private static BackgroundTaskRunner<IBackgroundTask> _tasksRunner;
|
||||
private static BackgroundTaskRunner<IBackgroundTask> _scrubberRunner;
|
||||
private static volatile bool _started;
|
||||
private static readonly object Locker = new object();
|
||||
private BackgroundTaskRunner<IBackgroundTask> _keepAliveRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _publishingRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _tasksRunner;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _scrubberRunner;
|
||||
private bool _started = false;
|
||||
private object _locker = new object();
|
||||
private IBackgroundTask[] _tasks;
|
||||
|
||||
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (umbracoApplication.Context == null)
|
||||
return;
|
||||
|
||||
//subscribe to app init so we can subsribe to the application events
|
||||
UmbracoApplicationBase.ApplicationInit += (sender, args) =>
|
||||
// backgrounds runners are web aware, if the app domain dies, these tasks will wind down correctly
|
||||
_keepAliveRunner = new BackgroundTaskRunner<IBackgroundTask>("KeepAlive", applicationContext.ProfilingLogger.Logger);
|
||||
_publishingRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledPublishing", applicationContext.ProfilingLogger.Logger);
|
||||
_tasksRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledTasks", applicationContext.ProfilingLogger.Logger);
|
||||
_scrubberRunner = new BackgroundTaskRunner<IBackgroundTask>("LogScrubber", applicationContext.ProfilingLogger.Logger);
|
||||
|
||||
//We will start the whole process when a successful request is made
|
||||
UmbracoModule.RouteAttempt += UmbracoModuleRouteAttempt;
|
||||
}
|
||||
|
||||
private void UmbracoModuleRouteAttempt(object sender, RoutableAttemptEventArgs e)
|
||||
{
|
||||
switch (e.Outcome)
|
||||
{
|
||||
var app = (HttpApplication)sender;
|
||||
case EnsureRoutableOutcome.IsRoutable:
|
||||
case EnsureRoutableOutcome.NotDocumentRequest:
|
||||
RegisterBackgroundTasks(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//subscribe to the end of a successful request (a handler actually executed)
|
||||
app.PostRequestHandlerExecute += (o, eventArgs) =>
|
||||
private void RegisterBackgroundTasks(UmbracoRequestEventArgs e)
|
||||
{
|
||||
//remove handler, we're done
|
||||
UmbracoModule.RouteAttempt -= UmbracoModuleRouteAttempt;
|
||||
|
||||
LazyInitializer.EnsureInitialized(ref _tasks, ref _started, ref _locker, () =>
|
||||
{
|
||||
LogHelper.Debug<Scheduler>(() => "Initializing the scheduler");
|
||||
var settings = UmbracoConfig.For.UmbracoSettings();
|
||||
|
||||
var tasks = new List<IBackgroundTask>
|
||||
{
|
||||
if (_started == false)
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
if (_started == false)
|
||||
{
|
||||
_started = true;
|
||||
LogHelper.Debug<Scheduler>(() => "Initializing the scheduler");
|
||||
|
||||
// backgrounds runners are web aware, if the app domain dies, these tasks will wind down correctly
|
||||
_keepAliveRunner = new BackgroundTaskRunner<IBackgroundTask>("KeepAlive", applicationContext.ProfilingLogger.Logger);
|
||||
_publishingRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledPublishing", applicationContext.ProfilingLogger.Logger);
|
||||
_tasksRunner = new BackgroundTaskRunner<IBackgroundTask>("ScheduledTasks", applicationContext.ProfilingLogger.Logger);
|
||||
_scrubberRunner = new BackgroundTaskRunner<IBackgroundTask>("LogScrubber", applicationContext.ProfilingLogger.Logger);
|
||||
|
||||
var settings = UmbracoConfig.For.UmbracoSettings();
|
||||
|
||||
// ping/keepalive
|
||||
// on all servers
|
||||
_keepAliveRunner.Add(new KeepAlive(_keepAliveRunner, 60000, 300000, applicationContext));
|
||||
|
||||
// scheduled publishing/unpublishing
|
||||
// install on all, will only run on non-slaves servers
|
||||
_publishingRunner.Add(new ScheduledPublishing(_publishingRunner, 60000, 60000, applicationContext, settings));
|
||||
_tasksRunner.Add(new ScheduledTasks(_tasksRunner, 60000, 60000, applicationContext, settings));
|
||||
|
||||
// log scrubbing
|
||||
// install on all, will only run on non-slaves servers
|
||||
_scrubberRunner.Add(new LogScrubber(_scrubberRunner, 60000, LogScrubber.GetLogScrubbingInterval(settings), applicationContext, settings));
|
||||
}
|
||||
}
|
||||
}
|
||||
new KeepAlive(_keepAliveRunner, 60000, 300000, e.UmbracoContext.Application),
|
||||
new ScheduledPublishing(_publishingRunner, 60000, 60000, e.UmbracoContext.Application, settings),
|
||||
new ScheduledTasks(_tasksRunner, 60000, 60000, e.UmbracoContext.Application, settings),
|
||||
new LogScrubber(_scrubberRunner, 60000, LogScrubber.GetLogScrubbingInterval(settings), e.UmbracoContext.Application, settings)
|
||||
};
|
||||
};
|
||||
|
||||
// ping/keepalive
|
||||
// on all servers
|
||||
_keepAliveRunner.TryAdd(tasks[0]);
|
||||
|
||||
// scheduled publishing/unpublishing
|
||||
// install on all, will only run on non-slaves servers
|
||||
_publishingRunner.TryAdd(tasks[1]);
|
||||
|
||||
_tasksRunner.TryAdd(tasks[2]);
|
||||
|
||||
// log scrubbing
|
||||
// install on all, will only run on non-slaves servers
|
||||
_scrubberRunner.TryAdd(tasks[3]);
|
||||
|
||||
return tasks.ToArray();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,19 +28,21 @@ namespace Umbraco.Web.Strategies
|
||||
private DatabaseServerRegistrar _registrar;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _backgroundTaskRunner;
|
||||
private bool _started = false;
|
||||
private TouchServerTask _task;
|
||||
private object _lock = new object();
|
||||
|
||||
// bind to events
|
||||
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
_registrar = ServerRegistrarResolver.Current.Registrar as DatabaseServerRegistrar;
|
||||
|
||||
// only for the DatabaseServerRegistrar
|
||||
if (_registrar == null) return;
|
||||
|
||||
_backgroundTaskRunner = new BackgroundTaskRunner<IBackgroundTask>(
|
||||
new BackgroundTaskRunnerOptions { AutoStart = true },
|
||||
applicationContext.ProfilingLogger.Logger);
|
||||
|
||||
// only for the DatabaseServerRegistrar
|
||||
if (_registrar == null) return;
|
||||
|
||||
//We will start the whole process when a successful request is made
|
||||
UmbracoModule.RouteAttempt += UmbracoModuleRouteAttempt;
|
||||
}
|
||||
@@ -61,40 +63,34 @@ namespace Umbraco.Web.Strategies
|
||||
switch (e.Outcome)
|
||||
{
|
||||
case EnsureRoutableOutcome.IsRoutable:
|
||||
// front-end request
|
||||
RegisterServer(e);
|
||||
//remove handler, we're done
|
||||
UmbracoModule.RouteAttempt -= UmbracoModuleRouteAttempt;
|
||||
break;
|
||||
case EnsureRoutableOutcome.NotDocumentRequest:
|
||||
// anything else (back-end request, service...)
|
||||
//so it's not a document request, we'll check if it's a back office request
|
||||
if (e.HttpContext.Request.Url.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath))
|
||||
{
|
||||
RegisterServer(e);
|
||||
//remove handler, we're done
|
||||
UmbracoModule.RouteAttempt -= UmbracoModuleRouteAttempt;
|
||||
}
|
||||
break;
|
||||
RegisterBackgroundTasks(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterServer(UmbracoRequestEventArgs e)
|
||||
private void RegisterBackgroundTasks(UmbracoRequestEventArgs e)
|
||||
{
|
||||
//only process once
|
||||
if (_started) return;
|
||||
//remove handler, we're done
|
||||
UmbracoModule.RouteAttempt -= UmbracoModuleRouteAttempt;
|
||||
|
||||
_started = true;
|
||||
//only perform this one time ever
|
||||
LazyInitializer.EnsureInitialized(ref _task, ref _started, ref _lock, () =>
|
||||
{
|
||||
var serverAddress = e.UmbracoContext.Application.UmbracoApplicationUrl;
|
||||
var svc = e.UmbracoContext.Application.Services.ServerRegistrationService;
|
||||
|
||||
var serverAddress = e.UmbracoContext.Application.UmbracoApplicationUrl;
|
||||
var svc = e.UmbracoContext.Application.Services.ServerRegistrationService;
|
||||
var task = new TouchServerTask(_backgroundTaskRunner,
|
||||
15000, //delay before first execution
|
||||
_registrar.Options.RecurringSeconds*1000, //amount of ms between executions
|
||||
svc, _registrar, serverAddress);
|
||||
|
||||
//Perform the rest async, we don't want to block the startup sequence
|
||||
// this will just reoccur on a background thread
|
||||
_backgroundTaskRunner.TryAdd(task);
|
||||
|
||||
//Perform the rest async, we don't want to block the startup sequence
|
||||
// this will just reoccur on a background thread
|
||||
_backgroundTaskRunner.Add(new TouchServerTask(_backgroundTaskRunner,
|
||||
15000, //delay before first execution
|
||||
_registrar.Options.RecurringSeconds * 1000, //amount of ms between executions
|
||||
svc, _registrar, serverAddress));
|
||||
return task;
|
||||
});
|
||||
}
|
||||
|
||||
private class TouchServerTask : RecurringTaskBase
|
||||
|
||||
Reference in New Issue
Block a user