diff --git a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs index 6f1fc03281..6d5614eb77 100644 --- a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs +++ b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs @@ -205,7 +205,7 @@ namespace Umbraco.Core.Sync /// /// Synchronize the server (throttled). /// - protected void Sync() + protected internal void Sync() { lock (_locko) { diff --git a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs index 23edb2dde2..c3f9d62411 100644 --- a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs +++ b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Sync; using Umbraco.Web.Routing; using Umbraco.Core.Logging; +using Umbraco.Web.Scheduling; namespace Umbraco.Web { @@ -22,7 +23,31 @@ namespace Umbraco.Web { public BatchedDatabaseServerMessenger(ApplicationContext appContext, bool enableDistCalls, DatabaseServerMessengerOptions options) : base(appContext, enableDistCalls, options) - { } + { + Scheduler.Initializing += Scheduler_Initializing; + } + + /// + /// Occurs when the scheduler initializes all scheduling activity when the app is ready + /// + /// + /// + private void Scheduler_Initializing(object sender, List e) + { + //if the current resolver is 'this' then we will start the scheduling + var isMessenger = ServerMessengerResolver.HasCurrent && ReferenceEquals(ServerMessengerResolver.Current.Messenger, this); + + if (isMessenger) + { + //start the background task runner for processing instructions + const int delayMilliseconds = 60000; + var instructionProcessingRunner = new BackgroundTaskRunner("InstructionProcessing", ApplicationContext.ProfilingLogger.Logger); + var instructionProcessingTask = new InstructionProcessing(instructionProcessingRunner, this, delayMilliseconds, Options.ThrottleSeconds * 1000); + instructionProcessingRunner.TryAdd(instructionProcessingTask); + e.Add(instructionProcessingTask); + } + } + // invoked by BatchedDatabaseServerMessengerStartup which is an ApplicationEventHandler // with default "ShouldExecute", so that method will run if app IsConfigured and database @@ -30,7 +55,6 @@ namespace Umbraco.Web internal void Startup() { UmbracoModule.EndRequest += UmbracoModule_EndRequest; - UmbracoModule.RouteAttempt += UmbracoModule_RouteAttempt; if (ApplicationContext.DatabaseContext.CanConnect == false) { @@ -43,20 +67,31 @@ namespace Umbraco.Web } } - private void UmbracoModule_RouteAttempt(object sender, RoutableAttemptEventArgs e) + /// + /// This will process cache instructions on a background thread and will run every 5 seconds (or whatever is defined in the ) + /// + private class InstructionProcessing : RecurringTaskBase { - // as long as umbraco is ready & configured, sync - switch (e.Outcome) + private readonly DatabaseServerMessenger _messenger; + + public InstructionProcessing(IBackgroundTaskRunner runner, + DatabaseServerMessenger messenger, + int delayMilliseconds, int periodMilliseconds) + : base(runner, delayMilliseconds, periodMilliseconds) { - case EnsureRoutableOutcome.IsRoutable: - case EnsureRoutableOutcome.NotDocumentRequest: - case EnsureRoutableOutcome.NoContent: - Sync(); - break; - //case EnsureRoutableOutcome.NotReady: - //case EnsureRoutableOutcome.NotConfigured: - //default: - // break; + _messenger = messenger; + } + + public override bool PerformRun() + { + _messenger.Sync(); + //return true to repeat + return true; + } + + public override bool IsAsync + { + get { return false; } } } diff --git a/src/Umbraco.Web/Scheduling/Scheduler.cs b/src/Umbraco.Web/Scheduling/Scheduler.cs index 9eeefbf54a..5a8d409a8c 100644 --- a/src/Umbraco.Web/Scheduling/Scheduler.cs +++ b/src/Umbraco.Web/Scheduling/Scheduler.cs @@ -35,7 +35,7 @@ namespace Umbraco.Web.Scheduling return; // backgrounds runners are web aware, if the app domain dies, these tasks will wind down correctly - _keepAliveRunner = new BackgroundTaskRunner("KeepAlive", applicationContext.ProfilingLogger.Logger); + _keepAliveRunner = new BackgroundTaskRunner("KeepAlive", applicationContext.ProfilingLogger.Logger); _publishingRunner = new BackgroundTaskRunner("ScheduledPublishing", applicationContext.ProfilingLogger.Logger); _tasksRunner = new BackgroundTaskRunner("ScheduledTasks", applicationContext.ProfilingLogger.Logger); _scrubberRunner = new BackgroundTaskRunner("LogScrubber", applicationContext.ProfilingLogger.Logger); @@ -74,7 +74,7 @@ namespace Umbraco.Web.Scheduling new KeepAlive(_keepAliveRunner, delayMilliseconds, 300000, e.UmbracoContext.Application), new ScheduledPublishing(_publishingRunner, delayMilliseconds, 60000, e.UmbracoContext.Application, settings), new ScheduledTasks(_tasksRunner, delayMilliseconds, 60000, e.UmbracoContext.Application, settings), - new LogScrubber(_scrubberRunner, delayMilliseconds, LogScrubber.GetLogScrubbingInterval(settings), e.UmbracoContext.Application, settings), + new LogScrubber(_scrubberRunner, delayMilliseconds, LogScrubber.GetLogScrubbingInterval(settings), e.UmbracoContext.Application, settings) }; if (healthCheckConfig.NotificationSettings.Enabled) @@ -116,10 +116,20 @@ namespace Umbraco.Web.Scheduling if (healthCheckConfig.NotificationSettings.Enabled) { _healthCheckRunner.TryAdd(tasks[4]); - } + } + + OnInitializing(tasks); return tasks.ToArray(); }); } + + public static event EventHandler> Initializing; + + private static void OnInitializing(List e) + { + var handler = Initializing; + if (handler != null) handler(null, e); + } } }