V10: Use FireAndForget when logging install (#12658)
* Use FireAndForget when logging install * Obsolete constructor Co-authored-by: Zeegaan <nge@umbraco.dk>
This commit is contained in:
41
src/Umbraco.Core/FireAndForgetRunner.cs
Normal file
41
src/Umbraco.Core/FireAndForgetRunner.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Umbraco.Cms.Core;
|
||||
|
||||
|
||||
public class FireAndForgetRunner : IFireAndForgetRunner
|
||||
{
|
||||
private readonly ILogger<FireAndForgetRunner> _logger;
|
||||
|
||||
public FireAndForgetRunner(ILogger<FireAndForgetRunner> logger) => _logger = logger;
|
||||
|
||||
public void RunFireAndForget(Func<Task> task) => ExecuteBackgroundTask(task);
|
||||
|
||||
private Task ExecuteBackgroundTask(Func<Task> fn)
|
||||
{
|
||||
// it is also possible to use UnsafeQueueUserWorkItem which does not flow the execution context,
|
||||
// however that seems more difficult to use for async operations.
|
||||
|
||||
// Do not flow AsyncLocal to the child thread
|
||||
using (ExecutionContext.SuppressFlow())
|
||||
{
|
||||
// NOTE: ConfigureAwait(false) is irrelevant here, it is not needed because this is not being
|
||||
// awaited. ConfigureAwait(false) is only relevant when awaiting to prevent the SynchronizationContext
|
||||
// (very different from the ExecutionContext!) from running the continuation on the calling thread.
|
||||
return Task.Run(LoggingWrapper(fn));
|
||||
}
|
||||
}
|
||||
|
||||
private Func<Task> LoggingWrapper(Func<Task> fn) =>
|
||||
async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await fn();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "Exception thrown in a background thread");
|
||||
}
|
||||
};
|
||||
}
|
||||
6
src/Umbraco.Core/IFireAndForgetRunner.cs
Normal file
6
src/Umbraco.Core/IFireAndForgetRunner.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Core;
|
||||
|
||||
public interface IFireAndForgetRunner
|
||||
{
|
||||
void RunFireAndForget(Func<Task> task);
|
||||
}
|
||||
@@ -219,6 +219,8 @@ public static partial class UmbracoBuilderExtensions
|
||||
|
||||
// Services required to run background jobs (with out the handler)
|
||||
builder.Services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
|
||||
|
||||
builder.Services.AddTransient<IFireAndForgetRunner, FireAndForgetRunner>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core;
|
||||
@@ -9,6 +10,7 @@ using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Infrastructure.Migrations.Install;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Web.Common.DependencyInjection;
|
||||
using Umbraco.Extensions;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
|
||||
@@ -24,8 +26,35 @@ namespace Umbraco.Cms.Infrastructure.Install
|
||||
private readonly ICookieManager _cookieManager;
|
||||
private readonly IUserAgentProvider _userAgentProvider;
|
||||
private readonly IUmbracoDatabaseFactory _umbracoDatabaseFactory;
|
||||
private readonly IFireAndForgetRunner _fireAndForgetRunner;
|
||||
private InstallationType? _installationType;
|
||||
|
||||
public InstallHelper(
|
||||
DatabaseBuilder databaseBuilder,
|
||||
ILogger<InstallHelper> logger,
|
||||
IUmbracoVersion umbracoVersion,
|
||||
IOptionsMonitor<ConnectionStrings> connectionStrings,
|
||||
IInstallationService installationService,
|
||||
ICookieManager cookieManager,
|
||||
IUserAgentProvider userAgentProvider,
|
||||
IUmbracoDatabaseFactory umbracoDatabaseFactory,
|
||||
IFireAndForgetRunner fireAndForgetRunner)
|
||||
{
|
||||
_logger = logger;
|
||||
_umbracoVersion = umbracoVersion;
|
||||
_databaseBuilder = databaseBuilder;
|
||||
_connectionStrings = connectionStrings;
|
||||
_installationService = installationService;
|
||||
_cookieManager = cookieManager;
|
||||
_userAgentProvider = userAgentProvider;
|
||||
_umbracoDatabaseFactory = umbracoDatabaseFactory;
|
||||
_fireAndForgetRunner = fireAndForgetRunner;
|
||||
|
||||
// We need to initialize the type already, as we can't detect later, if the connection string is added on the fly.
|
||||
GetInstallationType();
|
||||
}
|
||||
|
||||
[Obsolete("Please use constructor that takes an IFireAndForgetRunner instead, scheduled for removal in Umbraco 12")]
|
||||
public InstallHelper(
|
||||
DatabaseBuilder databaseBuilder,
|
||||
ILogger<InstallHelper> logger,
|
||||
@@ -35,6 +64,16 @@ namespace Umbraco.Cms.Infrastructure.Install
|
||||
ICookieManager cookieManager,
|
||||
IUserAgentProvider userAgentProvider,
|
||||
IUmbracoDatabaseFactory umbracoDatabaseFactory)
|
||||
: this(
|
||||
databaseBuilder,
|
||||
logger,
|
||||
umbracoVersion,
|
||||
connectionStrings,
|
||||
installationService,
|
||||
cookieManager,
|
||||
userAgentProvider,
|
||||
umbracoDatabaseFactory,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IFireAndForgetRunner>())
|
||||
{
|
||||
_logger = logger;
|
||||
_umbracoVersion = umbracoVersion;
|
||||
@@ -87,7 +126,7 @@ namespace Umbraco.Cms.Infrastructure.Install
|
||||
userAgent: userAgent,
|
||||
dbProvider: dbProvider);
|
||||
|
||||
await _installationService.LogInstall(installLog);
|
||||
_fireAndForgetRunner.RunFireAndForget(() => _installationService.LogInstall(installLog));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user