Fixes our sql azure transient fault detection to be inline with current standards, adds a scope for the health check schedule tasks

This commit is contained in:
Shannon
2020-07-08 17:26:31 +10:00
parent 384531ea68
commit e1757178b9
5 changed files with 57 additions and 43 deletions

View File

@@ -5,6 +5,7 @@ using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Scoping;
using Umbraco.Core.Sync;
using Umbraco.Web.HealthCheck;
@@ -15,16 +16,17 @@ namespace Umbraco.Web.Scheduling
private readonly IRuntimeState _runtimeState;
private readonly HealthCheckCollection _healthChecks;
private readonly HealthCheckNotificationMethodCollection _notifications;
private readonly IScopeProvider _scopeProvider;
private readonly IProfilingLogger _logger;
public HealthCheckNotifier(IBackgroundTaskRunner<RecurringTaskBase> runner, int delayMilliseconds, int periodMilliseconds,
HealthCheckCollection healthChecks, HealthCheckNotificationMethodCollection notifications,
IRuntimeState runtimeState,
IProfilingLogger logger)
IScopeProvider scopeProvider, IRuntimeState runtimeState, IProfilingLogger logger)
: base(runner, delayMilliseconds, periodMilliseconds)
{
_healthChecks = healthChecks;
_notifications = notifications;
_scopeProvider = scopeProvider;
_runtimeState = runtimeState;
_logger = logger;
}
@@ -51,6 +53,10 @@ namespace Umbraco.Web.Scheduling
return false; // do NOT repeat, going down
}
// Ensure we use an explicit scope since we are running on a background thread and plugin health
// checks can be making service/database calls so we want to ensure the CallContext/Ambient scope
// isn't used since that can be problematic.
using (var scope = _scopeProvider.CreateScope())
using (_logger.DebugDuration<HealthCheckNotifier>("Health checks executing", "Health checks complete"))
{
var healthCheckConfig = Current.Configs.HealthChecks();

View File

@@ -70,8 +70,7 @@ namespace Umbraco.Web.Scheduling
return false; // do NOT repeat, going down
}
// running on a background task, and Log.CleanLogs uses the old SqlHelper,
// better wrap in a scope and ensure it's all cleaned up and nothing leaks
// Ensure we use an explicit scope since we are running on a background thread.
using (var scope = _scopeProvider.CreateScope())
using (_logger.DebugDuration<LogScrubber>("Log scrubbing executing", "Log scrubbing complete"))
{

View File

@@ -2,6 +2,7 @@
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Core.Sync;
@@ -55,30 +56,24 @@ namespace Umbraco.Web.Scheduling
try
{
// ensure we run with an UmbracoContext, because this may run in a background task,
// yet developers may be using the 'current' UmbracoContext in the event handlers
//
// TODO: or maybe not, CacheRefresherComponent already ensures a context when handling events
// - UmbracoContext 'current' needs to be refactored and cleaned up
// - batched messenger should not depend on a current HttpContext
// but then what should be its "scope"? could we attach it to scopes?
// - and we should definitively *not* have to flush it here (should be auto)
//
using (var contextReference = _umbracoContextFactory.EnsureUmbracoContext())
// We don't need an explicit scope here because PerformScheduledPublish creates it's own scope
// so it's safe as it will create it's own ambient scope.
// Ensure we run with an UmbracoContext, because this will run in a background task,
// and developers may be using the UmbracoContext in the event handlers.
using var contextReference = _umbracoContextFactory.EnsureUmbracoContext();
try
{
try
{
// run
var result = _contentService.PerformScheduledPublish(DateTime.Now);
foreach (var grouped in result.GroupBy(x => x.Result))
_logger.Info<ScheduledPublishing>("Scheduled publishing result: '{StatusCount}' items with status {Status}", grouped.Count(), grouped.Key);
}
finally
{
// if running on a temp context, we have to flush the messenger
if (contextReference.IsRoot && Composing.Current.ServerMessenger is BatchedDatabaseServerMessenger m)
m.FlushBatch();
}
// run
var result = _contentService.PerformScheduledPublish(DateTime.Now);
foreach (var grouped in result.GroupBy(x => x.Result))
_logger.Info<ScheduledPublishing>("Scheduled publishing result: '{StatusCount}' items with status {Status}", grouped.Count(), grouped.Key);
}
finally
{
// if running on a temp context, we have to flush the messenger
if (contextReference.IsRoot && Composing.Current.ServerMessenger is BatchedDatabaseServerMessenger m)
m.FlushBatch();
}
}
catch (Exception ex)

View File

@@ -155,7 +155,7 @@ namespace Umbraco.Web.Scheduling
}
var periodInMilliseconds = healthCheckConfig.NotificationSettings.PeriodInHours * 60 * 60 * 1000;
var task = new HealthCheckNotifier(_healthCheckRunner, delayInMilliseconds, periodInMilliseconds, healthChecks, notifications, _runtime, logger);
var task = new HealthCheckNotifier(_healthCheckRunner, delayInMilliseconds, periodInMilliseconds, healthChecks, notifications, _scopeProvider, _runtime, logger);
_healthCheckRunner.TryAdd(task);
return task;
}