diff --git a/src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs b/src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs
index 70dcb3a04e..b6f2b469f6 100644
--- a/src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs
+++ b/src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs
@@ -21,7 +21,7 @@ namespace Umbraco.Cms.Infrastructure.HostedServices
///
protected static readonly TimeSpan DefaultDelay = TimeSpan.FromMinutes(3);
- private readonly TimeSpan _period;
+ private TimeSpan _period;
private readonly TimeSpan _delay;
private Timer _timer;
@@ -73,6 +73,7 @@ namespace Umbraco.Cms.Infrastructure.HostedServices
///
public Task StopAsync(CancellationToken cancellationToken)
{
+ _period = Timeout.InfiniteTimeSpan;
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
diff --git a/src/Umbraco.Infrastructure/HostedServices/ServerRegistration/TouchServerTask.cs b/src/Umbraco.Infrastructure/HostedServices/ServerRegistration/TouchServerTask.cs
index 282847963f..d54d67338e 100644
--- a/src/Umbraco.Infrastructure/HostedServices/ServerRegistration/TouchServerTask.cs
+++ b/src/Umbraco.Infrastructure/HostedServices/ServerRegistration/TouchServerTask.cs
@@ -2,13 +2,17 @@
// See LICENSE for more details.
using System;
+using System.Threading;
using System.Threading.Tasks;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Core.Sync;
+using Umbraco.Cms.Web.Common.DependencyInjection;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.HostedServices.ServerRegistration
@@ -22,6 +26,7 @@ namespace Umbraco.Cms.Infrastructure.HostedServices.ServerRegistration
private readonly IServerRegistrationService _serverRegistrationService;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly ILogger _logger;
+ private readonly IServerRoleAccessor _serverRoleAccessor;
private readonly GlobalSettings _globalSettings;
///
@@ -37,7 +42,8 @@ namespace Umbraco.Cms.Infrastructure.HostedServices.ServerRegistration
IServerRegistrationService serverRegistrationService,
IHostingEnvironment hostingEnvironment,
ILogger logger,
- IOptions globalSettings)
+ IOptions globalSettings,
+ IServerRoleAccessor serverRoleAccessor)
: base(globalSettings.Value.DatabaseServerRegistrar.WaitTimeBetweenCalls, TimeSpan.FromSeconds(15))
{
_runtimeState = runtimeState;
@@ -45,6 +51,24 @@ namespace Umbraco.Cms.Infrastructure.HostedServices.ServerRegistration
_hostingEnvironment = hostingEnvironment;
_logger = logger;
_globalSettings = globalSettings.Value;
+ _serverRoleAccessor = serverRoleAccessor;
+ }
+
+ [Obsolete("Use constructor that takes an IServerRoleAccessor")]
+ public TouchServerTask(
+ IRuntimeState runtimeState,
+ IServerRegistrationService serverRegistrationService,
+ IHostingEnvironment hostingEnvironment,
+ ILogger logger,
+ IOptions globalSettings)
+ : this(
+ runtimeState,
+ serverRegistrationService,
+ hostingEnvironment,
+ logger,
+ globalSettings,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
}
public override Task PerformExecuteAsync(object state)
@@ -54,6 +78,14 @@ namespace Umbraco.Cms.Infrastructure.HostedServices.ServerRegistration
return Task.CompletedTask;
}
+ // If the IServerRoleAccessor has been changed away from ElectedServerRoleAccessor this task no longer makes sense,
+ // since all it's used for is to allow the ElectedServerRoleAccessor
+ // to figure out what role a given server has, so we just stop this task.
+ if (_serverRoleAccessor is not ElectedServerRoleAccessor)
+ {
+ return StopAsync(CancellationToken.None);
+ }
+
var serverAddress = _hostingEnvironment.ApplicationMainUrl?.ToString();
if (serverAddress.IsNullOrWhiteSpace())
{
diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HostedServices/ServerRegistration/TouchServerTaskTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HostedServices/ServerRegistration/TouchServerTaskTests.cs
index 29b011a5a6..c690f35b7a 100644
--- a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HostedServices/ServerRegistration/TouchServerTaskTests.cs
+++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HostedServices/ServerRegistration/TouchServerTaskTests.cs
@@ -11,6 +11,7 @@ using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Services;
+using Umbraco.Cms.Core.Sync;
using Umbraco.Cms.Infrastructure.HostedServices.ServerRegistration;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices.ServerRegistration
@@ -51,7 +52,15 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices.Serv
VerifyServerTouched();
}
- private TouchServerTask CreateTouchServerTask(RuntimeLevel runtimeLevel = RuntimeLevel.Run, string applicationUrl = ApplicationUrl)
+ [Test]
+ public async Task Does_Not_Execute_When_Role_Accessor_Is_Not_Elected()
+ {
+ TouchServerTask sut = CreateTouchServerTask(useElection: false);
+ await sut.PerformExecuteAsync(null);
+ VerifyServerNotTouched();
+ }
+
+ private TouchServerTask CreateTouchServerTask(RuntimeLevel runtimeLevel = RuntimeLevel.Run, string applicationUrl = ApplicationUrl, bool useElection = true)
{
var mockRequestAccessor = new Mock();
mockRequestAccessor.SetupGet(x => x.ApplicationMainUrl).Returns(!string.IsNullOrEmpty(applicationUrl) ? new Uri(ApplicationUrl) : null);
@@ -71,12 +80,17 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices.Serv
}
};
+ IServerRoleAccessor roleAccessor = useElection
+ ? new ElectedServerRoleAccessor(_mockServerRegistrationService.Object)
+ : new SingleServerRoleAccessor();
+
return new TouchServerTask(
mockRunTimeState.Object,
_mockServerRegistrationService.Object,
mockRequestAccessor.Object,
mockLogger.Object,
- Options.Create(settings));
+ Options.Create(settings),
+ roleAccessor);
}
private void VerifyServerNotTouched() => VerifyServerTouchedTimes(Times.Never());