Simplifies IMainDom interface, removes system-wide mutex in favor of maindom

This commit is contained in:
Shannon
2021-01-20 19:14:26 +11:00
parent 17078b59c5
commit 0e7f13f92d
9 changed files with 62 additions and 76 deletions

View File

@@ -1,7 +1,7 @@
using System;
using System;
using Umbraco.Core.Hosting;
// TODO: Can't change namespace due to breaking changes, change in netcore
namespace Umbraco.Core
{
/// <summary>
@@ -24,18 +24,8 @@ namespace Umbraco.Core
/// <summary>
/// Tries to acquire the MainDom, returns true if successful else false
/// </summary>
/// <param name="hostingEnvironment"></param>
/// <returns></returns>
bool Acquire(IApplicationShutdownRegistry hostingEnvironment);
/// <summary>
/// Registers a resource that requires the current AppDomain to be the main domain to function.
/// </summary>
/// <param name="release">An action to execute before the AppDomain releases the main domain status.</param>
/// <param name="weight">An optional weight (lower goes first).</param>
/// <returns>A value indicating whether it was possible to register.</returns>
bool Register(Action release, int weight = 100);
/// <summary>
/// Registers a resource that requires the current AppDomain to be the main domain to function.
/// </summary>
@@ -45,6 +35,6 @@ namespace Umbraco.Core
/// <returns>A value indicating whether it was possible to register.</returns>
/// <remarks>If registering is successful, then the <paramref name="install"/> action
/// is guaranteed to execute before the AppDomain releases the main domain status.</remarks>
bool Register(Action install, Action release, int weight = 100);
bool Register(Action install = null, Action release = null, int weight = 100);
}
}

View File

@@ -66,15 +66,6 @@ namespace Umbraco.Core.Runtime
});
}
/// <summary>
/// Registers a resource that requires the current AppDomain to be the main domain to function.
/// </summary>
/// <param name="release">An action to execute before the AppDomain releases the main domain status.</param>
/// <param name="weight">An optional weight (lower goes first).</param>
/// <returns>A value indicating whether it was possible to register.</returns>
public bool Register(Action release, int weight = 100)
=> Register(null, release, weight);
/// <summary>
/// Registers a resource that requires the current AppDomain to be the main domain to function.
/// </summary>
@@ -84,7 +75,7 @@ namespace Umbraco.Core.Runtime
/// <returns>A value indicating whether it was possible to register.</returns>
/// <remarks>If registering is successful, then the <paramref name="install"/> action
/// is guaranteed to execute before the AppDomain releases the main domain status.</remarks>
public bool Register(Action install, Action release, int weight = 100)
public bool Register(Action install = null, Action release = null, int weight = 100)
{
lock (_locko)
{

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Hosting;
@@ -21,10 +21,6 @@ namespace Umbraco.Core
// always acquire
public bool Acquire(IApplicationShutdownRegistry hostingEnvironment) => true;
/// <inheritdoc />
public bool Register(Action release, int weight = 100)
=> Register(null, release, weight);
/// <inheritdoc />
public bool Register(Action install, Action release, int weight = 100)
{

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
@@ -51,7 +51,9 @@ namespace Umbraco.Web.Scheduling
internal bool Register()
{
if (MainDom != null)
{
return MainDom.Register(Install, Release);
}
// tests
Install?.Invoke();

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
@@ -72,7 +72,7 @@ namespace Umbraco.Web.Search
public void Initialize()
{
//let's deal with shutting down Examine with MainDom
var examineShutdownRegistered = _mainDom.Register(() =>
var examineShutdownRegistered = _mainDom.Register(release: () =>
{
using (_profilingLogger.TraceDuration<ExamineComponent>("Examine shutting down"))
{

View File

@@ -151,7 +151,7 @@ namespace Umbraco.Core.Sync
const int weight = 10;
var registered = _mainDom.Register(
() =>
release: () =>
{
lock (_locko)
{
@@ -169,7 +169,7 @@ namespace Umbraco.Core.Sync
Logger.LogWarning("The wait lock timed out, application is shutting down. The current instruction batch will be re-processed.");
}
},
weight);
weight: weight);
if (registered == false)
{

View File

@@ -1,4 +1,4 @@
using System.IO;
using System.IO;
using System.Text;
using Microsoft.Extensions.Options;
using Umbraco.Core.Configuration;
@@ -27,16 +27,20 @@ namespace Umbraco.ModelsBuilder.Embedded.Building
{
var modelsDirectory = _config.ModelsDirectoryAbsolute(_hostingEnvironment);
if (!Directory.Exists(modelsDirectory))
{
Directory.CreateDirectory(modelsDirectory);
}
foreach (var file in Directory.GetFiles(modelsDirectory, "*.generated.cs"))
{
File.Delete(file);
}
var typeModels = _umbracoService.GetAllTypes();
System.Collections.Generic.IList<TypeModel> typeModels = _umbracoService.GetAllTypes();
var builder = new TextBuilder(_config, typeModels);
foreach (var typeModel in builder.GetModelsToGenerate())
foreach (TypeModel typeModel in builder.GetModelsToGenerate())
{
var sb = new StringBuilder();
builder.Generate(sb, typeModel);

View File

@@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Configuration;
using Umbraco.Core;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Events;
using Umbraco.Core.Hosting;
@@ -18,14 +19,13 @@ namespace Umbraco.ModelsBuilder.Embedded
// supports LiveAppData - but not PureLive
public sealed class LiveModelsProvider : INotificationHandler<UmbracoApplicationStarting>
{
private static Mutex s_mutex;
private static int s_req;
private readonly ILogger<LiveModelsProvider> _logger;
private readonly ModelsBuilderSettings _config;
private readonly ModelsGenerator _modelGenerator;
private readonly ModelsGenerationError _mbErrors;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IUmbracoRequestLifetime _umbracoRequestLifetime;
private readonly IMainDom _mainDom;
/// <summary>
/// Initializes a new instance of the <see cref="LiveModelsProvider"/> class.
@@ -35,15 +35,15 @@ namespace Umbraco.ModelsBuilder.Embedded
IOptions<ModelsBuilderSettings> config,
ModelsGenerator modelGenerator,
ModelsGenerationError mbErrors,
IHostingEnvironment hostingEnvironment,
IUmbracoRequestLifetime umbracoRequestLifetime)
IUmbracoRequestLifetime umbracoRequestLifetime,
IMainDom mainDom)
{
_logger = logger;
_config = config.Value ?? throw new ArgumentNullException(nameof(config));
_modelGenerator = modelGenerator;
_mbErrors = mbErrors;
_hostingEnvironment = hostingEnvironment;
_umbracoRequestLifetime = umbracoRequestLifetime;
_mainDom = mainDom;
}
// we do not manage pure live here
@@ -66,18 +66,17 @@ namespace Umbraco.ModelsBuilder.Embedded
return;
}
_umbracoRequestLifetime.RequestEnd += (sender, context) => AppEndRequest(context);
// Must register with maindom in order to function.
// If registration is not successful then events are not bound
// and we also don't generate models.
_mainDom.Register(() =>
{
_umbracoRequestLifetime.RequestEnd += (sender, context) => AppEndRequest(context);
// initialize mutex
// ApplicationId will look like "/LM/W3SVC/1/Root/AppName"
// name is system-wide and must be less than 260 chars
var name = _hostingEnvironment.ApplicationId + "/UmbracoLiveModelsProvider";
s_mutex = new Mutex(false, name); //TODO: Replace this with MainDom? Seems we now have 2x implementations of almost the same thing
// anything changes, and we want to re-generate models.
ContentTypeCacheRefresher.CacheUpdated += RequestModelsGeneration;
DataTypeCacheRefresher.CacheUpdated += RequestModelsGeneration;
// anything changes, and we want to re-generate models.
ContentTypeCacheRefresher.CacheUpdated += RequestModelsGeneration;
DataTypeCacheRefresher.CacheUpdated += RequestModelsGeneration;
});
}
// NOTE
@@ -100,28 +99,32 @@ namespace Umbraco.ModelsBuilder.Embedded
return;
}
try
// cannot proceed unless we are MainDom
if (_mainDom.IsMainDom)
{
_logger.LogDebug("Generate models...");
const int timeout = 2 * 60 * 1000; // 2 mins
s_mutex.WaitOne(timeout); // wait until it is safe, and acquire
_logger.LogInformation("Generate models now.");
_modelGenerator.GenerateModels();
_mbErrors.Clear();
_logger.LogInformation("Generated.");
try
{
_logger.LogDebug("Generate models...");
_logger.LogInformation("Generate models now.");
_modelGenerator.GenerateModels();
_mbErrors.Clear();
_logger.LogInformation("Generated.");
}
catch (TimeoutException)
{
_logger.LogWarning("Timeout, models were NOT generated.");
}
catch (Exception e)
{
_mbErrors.Report("Failed to build Live models.", e);
_logger.LogError("Failed to generate models.", e);
}
}
catch (TimeoutException)
else
{
_logger.LogWarning("Timeout, models were NOT generated.");
}
catch (Exception e)
{
_mbErrors.Report("Failed to build Live models.", e);
_logger.LogError("Failed to generate models.", e);
}
finally
{
s_mutex.ReleaseMutex(); // release
// this will only occur if this appdomain was MainDom and it has
// been released while trying to regenerate models.
_logger.LogWarning("Cannot generate models while app is shutting down");
}
}

View File

@@ -1,12 +1,12 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Umbraco.Core.Configuration;
using Umbraco.Core.Hosting;
using Umbraco.Core.Configuration.Models;
using Umbraco.Web.Cache;
using Umbraco.Core.Events;
using System.Threading.Tasks;
using System.Threading;
using Umbraco.Core.Hosting;
using Umbraco.Web.Cache;
namespace Umbraco.ModelsBuilder.Embedded
{
@@ -94,6 +94,6 @@ namespace Umbraco.ModelsBuilder.Embedded
}
File.Delete(path);
}
}
}
}