From 3f22e727f6e83ca59a72092c58c62523577f00b4 Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 23 Sep 2016 16:42:42 +0200 Subject: [PATCH] Some things need to be public/adjusted for Deploy --- src/SolutionInfo.cs | 2 +- .../Configuration/UmbracoVersion.cs | 2 +- .../Logging/DebugDiagnosticsLogger.cs | 6 +- src/Umbraco.Core/MainDom.cs | 47 ++++++++++++--- .../Scheduling/BackgroundTaskRunner.cs | 57 +++++++++++++------ .../Scheduling/BackgroundTaskRunnerOptions.cs | 2 +- src/Umbraco.Web/Scheduling/TaskEventArgs.cs | 28 +++++++-- .../Scheduling/ThreadingTaskImmutable.cs | 4 +- 8 files changed, 112 insertions(+), 36 deletions(-) diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index b322fb5290..6e4b94ca44 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -12,4 +12,4 @@ using System.Resources; [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyFileVersion("7.6.0")] -[assembly: AssemblyInformationalVersion("7.6.0-alpha016")] \ No newline at end of file +[assembly: AssemblyInformationalVersion("7.6.0-alpha019")] \ No newline at end of file diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index 09f6cd8b84..adde8ca8cd 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration /// Gets the version comment (like beta or RC). /// /// The version comment. - public static string CurrentComment { get { return "alpha016"; } } + public static string CurrentComment { get { return "alpha019"; } } // Get the version of the umbraco.dll by looking at a class in that dll // Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx diff --git a/src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs b/src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs index c1b3306129..f5ae689da9 100644 --- a/src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs +++ b/src/Umbraco.Core/Logging/DebugDiagnosticsLogger.cs @@ -3,7 +3,11 @@ using System.Linq; namespace Umbraco.Core.Logging { - internal class DebugDiagnosticsLogger : ILogger + /// + /// Implements on top of System.Diagnostics.Debug. + /// + /// Useful for tests. + public class DebugDiagnosticsLogger : ILogger { public void Error(Type callingType, string message, Exception exception) { diff --git a/src/Umbraco.Core/MainDom.cs b/src/Umbraco.Core/MainDom.cs index 9ded022195..52dbb21f21 100644 --- a/src/Umbraco.Core/MainDom.cs +++ b/src/Umbraco.Core/MainDom.cs @@ -11,8 +11,16 @@ using Umbraco.Core.ObjectResolution; namespace Umbraco.Core { - // represents the main domain - class MainDom : IRegisteredObject + /// + /// Represents the main AppDomain running for a given application. + /// + /// + /// There can be only one "main" AppDomain running for a given application at a time. + /// When an AppDomain starts, it tries to acquire the main domain status. + /// When an AppDomain stops (eg the application is restarting) it should release the main domain status. + /// It is possible to register against the MainDom and be notified when it is released. + /// + internal class MainDom : IRegisteredObject { #region Vars @@ -34,16 +42,26 @@ namespace Umbraco.Core private volatile bool _signaled; // we have been signaled // actions to run before releasing the main domain - private readonly SortedList _callbacks = new SortedList(); + private readonly SortedList _callbacks = new SortedList(new WeightComparer()); private const int LockTimeoutMilliseconds = 90000; // (1.5 * 60 * 1000) == 1 min 30 seconds + private class WeightComparer : IComparer + { + public int Compare(int x, int y) + { + var result = x.CompareTo(y); + // return "equal" as "greater than" + return result == 0 ? 1 : result; + } + } + #endregion #region Ctor // initializes a new instance of MainDom - public MainDom(ILogger logger) + internal MainDom(ILogger logger) { _logger = logger; @@ -73,13 +91,26 @@ namespace Umbraco.Core #endregion - // register a main domain consumer + /// + /// Registers a resource that requires the current AppDomain to be the main domain to function. + /// + /// An action to execute before the AppDomain releases the main domain status. + /// An optional weight (lower goes first). + /// A value indicating whether it was possible to register. public bool Register(Action release, int weight = 100) { return Register(null, release, weight); } - // register a main domain consumer + /// + /// Registers a resource that requires the current AppDomain to be the main domain to function. + /// + /// An action to execute when registering. + /// An action to execute before the AppDomain releases the main domain status. + /// An optional weight (lower goes first). + /// A value indicating whether it was possible to register. + /// If registering is successful, then the action + /// is guaranteed to execute before the AppDomain releases the main domain status. public bool Register(Action install, Action release, int weight = 100) { lock (_locko) @@ -135,7 +166,7 @@ namespace Umbraco.Core } // acquires the main domain - public bool Acquire() + internal bool Acquire() { lock (_locko) // we don't want the hosting environment to interfere by signaling { @@ -186,7 +217,7 @@ namespace Umbraco.Core } // IRegisteredObject - public void Stop(bool immediate) + void IRegisteredObject.Stop(bool immediate) { try { diff --git a/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs b/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs index d63fbb4606..b67c2c08ac 100644 --- a/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs +++ b/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs @@ -3,13 +3,17 @@ using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; using System.Web.Hosting; +using Umbraco.Core; using Umbraco.Core.Events; using Umbraco.Core.Logging; namespace Umbraco.Web.Scheduling { - // exists for logging purposes - internal class BackgroundTaskRunner + /// + /// Manages a queue of tasks and runs them in the background. + /// + /// This class exists for logging purposes - the one you want to use is BackgroundTaskRunner{T}. + public abstract class BackgroundTaskRunner { } /// @@ -18,7 +22,7 @@ namespace Umbraco.Web.Scheduling /// The type of the managed tasks. /// The task runner is web-aware and will ensure that it shuts down correctly when the AppDomain /// shuts down (ie is unloaded). - internal class BackgroundTaskRunner : BackgroundTaskRunner, IBackgroundTaskRunner + public class BackgroundTaskRunner : BackgroundTaskRunner, IBackgroundTaskRunner where T : class, IBackgroundTask { private readonly string _logPrefix; @@ -43,10 +47,10 @@ namespace Umbraco.Web.Scheduling private bool _terminated; // remember we've terminated private TaskCompletionSource _terminatedSource; // awaitable source - internal event TypedEventHandler, TaskEventArgs> TaskError; - internal event TypedEventHandler, TaskEventArgs> TaskStarting; - internal event TypedEventHandler, TaskEventArgs> TaskCompleted; - internal event TypedEventHandler, TaskEventArgs> TaskCancelled; + public event TypedEventHandler, TaskEventArgs> TaskError; + public event TypedEventHandler, TaskEventArgs> TaskStarting; + public event TypedEventHandler, TaskEventArgs> TaskCompleted; + public event TypedEventHandler, TaskEventArgs> TaskCancelled; // triggers when the runner stops (but could start again if a task is added to it) internal event TypedEventHandler, EventArgs> Stopped; @@ -60,26 +64,33 @@ namespace Umbraco.Web.Scheduling /// /// Initializes a new instance of the class. /// - public BackgroundTaskRunner(ILogger logger) - : this(typeof (T).FullName, new BackgroundTaskRunnerOptions(), logger) + /// A logger. + /// An optional action to execute when the main domain status is aquired. + /// An optional action to execute when the main domain status is released. + public BackgroundTaskRunner(ILogger logger, Action mainDomInstall = null, Action mainDomRelease = null) + : this(typeof (T).FullName, new BackgroundTaskRunnerOptions(), logger, mainDomInstall, mainDomRelease) { } /// /// Initializes a new instance of the class. /// /// The name of the runner. - /// - public BackgroundTaskRunner(string name, ILogger logger) - : this(name, new BackgroundTaskRunnerOptions(), logger) + /// A logger. + /// An optional action to execute when the main domain status is aquired. + /// An optional action to execute when the main domain status is released. + public BackgroundTaskRunner(string name, ILogger logger, Action mainDomInstall = null, Action mainDomRelease = null) + : this(name, new BackgroundTaskRunnerOptions(), logger, mainDomInstall, mainDomRelease) { } /// /// Initializes a new instance of the class with a set of options. /// /// The set of options. - /// - public BackgroundTaskRunner(BackgroundTaskRunnerOptions options, ILogger logger) - : this(typeof (T).FullName, options, logger) + /// A logger. + /// An optional action to execute when the main domain status is aquired. + /// An optional action to execute when the main domain status is released. + public BackgroundTaskRunner(BackgroundTaskRunnerOptions options, ILogger logger, Action mainDomInstall = null, Action mainDomRelease = null) + : this(typeof (T).FullName, options, logger, mainDomInstall, mainDomRelease) { } /// @@ -87,8 +98,10 @@ namespace Umbraco.Web.Scheduling /// /// The name of the runner. /// The set of options. - /// - public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger) + /// A logger. + /// An optional action to execute when the main domain status is aquired. + /// An optional action to execute when the main domain status is released. + public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger, Action mainDomInstall = null, Action mainDomRelease = null) { if (options == null) throw new ArgumentNullException("options"); if (logger == null) throw new ArgumentNullException("logger"); @@ -99,7 +112,15 @@ namespace Umbraco.Web.Scheduling if (options.Hosted) HostingEnvironment.RegisterObject(this); - if (options.AutoStart) + if (mainDomRelease != null) + { + var mainDom = ApplicationContext.Current.MainDom; + var reg = mainDom == null || ApplicationContext.Current.MainDom.Register(mainDomInstall, mainDomRelease); + if (reg == false) + _isCompleted = _terminated = true; + } + + if (options.AutoStart && _terminated == false) StartUp(); } diff --git a/src/Umbraco.Web/Scheduling/BackgroundTaskRunnerOptions.cs b/src/Umbraco.Web/Scheduling/BackgroundTaskRunnerOptions.cs index 55df42d3b7..28c814db24 100644 --- a/src/Umbraco.Web/Scheduling/BackgroundTaskRunnerOptions.cs +++ b/src/Umbraco.Web/Scheduling/BackgroundTaskRunnerOptions.cs @@ -3,7 +3,7 @@ namespace Umbraco.Web.Scheduling /// /// Provides options to the class. /// - internal class BackgroundTaskRunnerOptions + public class BackgroundTaskRunnerOptions { //TODO: Could add options for using a stack vs queue if required diff --git a/src/Umbraco.Web/Scheduling/TaskEventArgs.cs b/src/Umbraco.Web/Scheduling/TaskEventArgs.cs index 27e5174616..5e83b14231 100644 --- a/src/Umbraco.Web/Scheduling/TaskEventArgs.cs +++ b/src/Umbraco.Web/Scheduling/TaskEventArgs.cs @@ -2,21 +2,41 @@ namespace Umbraco.Web.Scheduling { - internal class TaskEventArgs : EventArgs + /// + /// Provides arguments for task runner events. + /// + /// The type of the task. + public class TaskEventArgs : EventArgs where T : IBackgroundTask { - public T Task { get; private set; } - public Exception Exception { get; private set; } - + /// + /// Initializes a new instance of the class with a task. + /// + /// The task. public TaskEventArgs(T task) { Task = task; } + /// + /// Initializes a new instance of the class with a task and an exception. + /// + /// The task. + /// An exception. public TaskEventArgs(T task, Exception exception) { Task = task; Exception = exception; } + + /// + /// Gets or sets the task. + /// + public T Task { get; private set; } + + /// + /// Gets or sets the exception. + /// + public Exception Exception { get; private set; } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Scheduling/ThreadingTaskImmutable.cs b/src/Umbraco.Web/Scheduling/ThreadingTaskImmutable.cs index e8ccbeac0e..1bb5fcbf41 100644 --- a/src/Umbraco.Web/Scheduling/ThreadingTaskImmutable.cs +++ b/src/Umbraco.Web/Scheduling/ThreadingTaskImmutable.cs @@ -5,10 +5,10 @@ using System.Threading.Tasks; namespace Umbraco.Web.Scheduling { /// - /// Wraps a Task within an object that gives access to its GetAwaiter method and Status + /// Wraps a within an object that gives access to its GetAwaiter method and Status /// property while ensuring that it cannot be modified in any way. /// - internal class ThreadingTaskImmutable + public class ThreadingTaskImmutable { private readonly Task _task;