From e3973de880a7ea99c12a5db14ec60b4bdc6f23b8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 4 Jun 2015 12:13:27 +0200 Subject: [PATCH] Updates scheduled tasks to be async with cancellation token --- .../Scheduling/ScheduledPublishing.cs | 10 ++- src/Umbraco.Web/Scheduling/ScheduledTasks.cs | 72 ++++++++++++------- src/Umbraco.Web/Scheduling/Scheduler.cs | 2 +- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs b/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs index cbc000b7e6..c60226965f 100644 --- a/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs +++ b/src/Umbraco.Web/Scheduling/ScheduledPublishing.cs @@ -98,8 +98,14 @@ namespace Umbraco.Web.Scheduling //There is no valid token, so we'll continue with the empty one } - var result = await wc.SendAsync(request, token); - + try + { + var result = await wc.SendAsync(request, token); + } + catch (Exception ex) + { + LogHelper.Error("An error occurred calling scheduled publish url", ex); + } } } } diff --git a/src/Umbraco.Web/Scheduling/ScheduledTasks.cs b/src/Umbraco.Web/Scheduling/ScheduledTasks.cs index cba3cb4fc8..600cc499de 100644 --- a/src/Umbraco.Web/Scheduling/ScheduledTasks.cs +++ b/src/Umbraco.Web/Scheduling/ScheduledTasks.cs @@ -2,6 +2,8 @@ using System; using System.Collections; using System.Linq; using System.Net; +using System.Net.Http; +using System.Threading; using System.Threading.Tasks; using System.Xml; using Umbraco.Core.Configuration; @@ -21,15 +23,17 @@ namespace Umbraco.Web.Scheduling { private readonly ApplicationContext _appContext; private readonly IUmbracoSettingsSection _settings; + private readonly Func _cancellationToken; private static readonly Hashtable ScheduledTaskTimes = new Hashtable(); private static bool _isPublishingRunning = false; public ScheduledTasks(IBackgroundTaskRunner runner, int delayMilliseconds, int periodMilliseconds, - ApplicationContext appContext, IUmbracoSettingsSection settings) + ApplicationContext appContext, IUmbracoSettingsSection settings, Func cancellationToken) : base(runner, delayMilliseconds, periodMilliseconds) { _appContext = appContext; _settings = settings; + _cancellationToken = cancellationToken; } public ScheduledTasks(ScheduledTasks source) @@ -44,18 +48,19 @@ namespace Umbraco.Web.Scheduling return new ScheduledTasks(this); } - private void ProcessTasks() + private async Task ProcessTasksAsync() { var scheduledTasks = _settings.ScheduledTasks.Tasks; foreach (var t in scheduledTasks) { var runTask = false; - if (!ScheduledTaskTimes.ContainsKey(t.Alias)) + if (ScheduledTaskTimes.ContainsKey(t.Alias) == false) { runTask = true; ScheduledTaskTimes.Add(t.Alias, DateTime.Now); } - /// Add 1 second to timespan to compensate for differencies in timer + + // Add 1 second to timespan to compensate for differencies in timer else if ( new TimeSpan( DateTime.Now.Ticks - ((DateTime)ScheduledTaskTimes[t.Alias]).Ticks).TotalSeconds + 1 >= t.Interval) @@ -66,33 +71,55 @@ namespace Umbraco.Web.Scheduling if (runTask) { - bool taskResult = GetTaskByHttp(t.Url); + bool taskResult = await GetTaskByHttpAync(t.Url); if (t.Log) LogHelper.Info(string.Format("{0} has been called with response: {1}", t.Alias, taskResult)); } } } - private bool GetTaskByHttp(string url) + private async Task GetTaskByHttpAync(string url) { - var myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url); - - try + using (var wc = new HttpClient()) { - using (var response = (HttpWebResponse)myHttpWebRequest.GetResponse()) + var request = new HttpRequestMessage() { - return response.StatusCode == HttpStatusCode.OK; - } - } - catch (Exception ex) - { - LogHelper.Error("An error occurred calling web task for url: " + url, ex); - } + RequestUri = new Uri(url), + Method = HttpMethod.Get, + Content = new StringContent(string.Empty) + }; + //TODO: pass custom the authorization header, currently these aren't really secured! + //request.Headers.Authorization = AdminTokenAuthorizeAttribute.GetAuthenticationHeaderValue(_appContext); - return false; + var token = new CancellationToken(); + try + { + token = _cancellationToken(); + } + catch (InvalidOperationException) + { + //There is no valid token, so we'll continue with the empty one + } + + try + { + var result = await wc.SendAsync(request, token); + return result.StatusCode == HttpStatusCode.OK; + } + catch (Exception ex) + { + LogHelper.Error("An error occurred calling web task for url: " + url, ex); + } + return false; + } } public override void PerformRun() + { + throw new NotImplementedException(); + } + + public override async Task PerformRunAsync() { if (ServerEnvironmentHelper.GetStatus(_settings) == CurrentServerEnvironmentStatus.Slave) { @@ -108,7 +135,7 @@ namespace Umbraco.Web.Scheduling try { - ProcessTasks(); + await ProcessTasksAsync(); } catch (Exception ee) { @@ -121,14 +148,9 @@ namespace Umbraco.Web.Scheduling } } - public override Task PerformRunAsync() - { - throw new NotImplementedException(); - } - public override bool IsAsync { - get { return false; } + get { return true; } } public override bool RunsOnShutdown diff --git a/src/Umbraco.Web/Scheduling/Scheduler.cs b/src/Umbraco.Web/Scheduling/Scheduler.cs index 71f2ab59c5..904254ee79 100644 --- a/src/Umbraco.Web/Scheduling/Scheduler.cs +++ b/src/Umbraco.Web/Scheduling/Scheduler.cs @@ -67,7 +67,7 @@ namespace Umbraco.Web.Scheduling // install on all, will only run on non-slaves servers // both are delayed recurring tasks _publishingRunner.Add(new ScheduledPublishing(_publishingRunner, 60000, 60000, applicationContext, settings, () => _publishingRunner.CurrentCancellationToken)); - _tasksRunner.Add(new ScheduledTasks(_tasksRunner, 60000, 60000, applicationContext, settings)); + _tasksRunner.Add(new ScheduledTasks(_tasksRunner, 60000, 60000, applicationContext, settings, () => _tasksRunner.CurrentCancellationToken)); // log scrubbing // install & run on all servers