Files
Umbraco-CMS/src/Umbraco.Infrastructure/HostedServices/KeepAlive.cs

114 lines
4.6 KiB
C#

// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Runtime;
using Umbraco.Cms.Core.Sync;
using Umbraco.Extensions;
namespace Umbraco.Cms.Infrastructure.HostedServices
{
/// <summary>
/// Hosted service implementation for keep alive feature.
/// </summary>
public class KeepAlive : RecurringHostedServiceBase
{
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IMainDom _mainDom;
private readonly KeepAliveSettings _keepAliveSettings;
private readonly ILogger<KeepAlive> _logger;
private readonly IProfilingLogger _profilingLogger;
private readonly IServerRoleAccessor _serverRegistrar;
private readonly IHttpClientFactory _httpClientFactory;
/// <summary>
/// Initializes a new instance of the <see cref="KeepAlive"/> class.
/// </summary>
/// <param name="requestAccessor">Accessor for the current request.</param>
/// <param name="mainDom">Representation of the main application domain.</param>
/// <param name="keepAliveSettings">The configuration for keep alive settings.</param>
/// <param name="logger">The typed logger.</param>
/// <param name="profilingLogger">The profiling logger.</param>
/// <param name="serverRegistrar">Provider of server registrations to the distributed cache.</param>
/// <param name="httpClientFactory">Factory for <see cref="HttpClient" /> instances.</param>
public KeepAlive(
IHostingEnvironment hostingEnvironment,
IMainDom mainDom,
IOptions<KeepAliveSettings> keepAliveSettings,
ILogger<KeepAlive> logger,
IProfilingLogger profilingLogger,
IServerRoleAccessor serverRegistrar,
IHttpClientFactory httpClientFactory)
: base(TimeSpan.FromMinutes(5), DefaultDelay)
{
_hostingEnvironment = hostingEnvironment;
_mainDom = mainDom;
_keepAliveSettings = keepAliveSettings.Value;
_logger = logger;
_profilingLogger = profilingLogger;
_serverRegistrar = serverRegistrar;
_httpClientFactory = httpClientFactory;
}
internal override async Task PerformExecuteAsync(object state)
{
if (_keepAliveSettings.DisableKeepAliveTask)
{
return;
}
// Don't run on replicas nor unknown role servers
switch (_serverRegistrar.CurrentServerRole)
{
case ServerRole.Replica:
_logger.LogDebug("Does not run on replica servers.");
return;
case ServerRole.Unknown:
_logger.LogDebug("Does not run on servers with unknown role.");
return;
}
// Ensure we do not run if not main domain, but do NOT lock it
if (_mainDom.IsMainDom == false)
{
_logger.LogDebug("Does not run if not MainDom.");
return;
}
using (_profilingLogger.DebugDuration<KeepAlive>("Keep alive executing", "Keep alive complete"))
{
var keepAlivePingUrl = _keepAliveSettings.KeepAlivePingUrl;
try
{
if (keepAlivePingUrl.Contains("{umbracoApplicationUrl}"))
{
var umbracoAppUrl = _hostingEnvironment.ApplicationMainUrl.ToString();
if (umbracoAppUrl.IsNullOrWhiteSpace())
{
_logger.LogWarning("No umbracoApplicationUrl for service (yet), skip.");
return;
}
keepAlivePingUrl = keepAlivePingUrl.Replace("{umbracoApplicationUrl}", umbracoAppUrl.TrimEnd('/'));
}
var request = new HttpRequestMessage(HttpMethod.Get, keepAlivePingUrl);
HttpClient httpClient = _httpClientFactory.CreateClient();
_ = await httpClient.SendAsync(request);
}
catch (Exception ex)
{
_logger.LogError(ex, "Keep alive failed (at '{keepAlivePingUrl}').", keepAlivePingUrl);
}
}
}
}
}