From 35391ad1a16f695c0d1c13196220c65ed6a99486 Mon Sep 17 00:00:00 2001 From: Gary Sharp Date: Wed, 25 Dec 2013 18:35:19 +1100 Subject: [PATCH] Feature: Thread-blocking task status completion Thread can be blocked until a task completes (or a timeout period elapses). Used to wait up to 3 seconds before redirecting to the TaskStatus when downloading the Plugin Catalogue. --- Disco.Services/Tasks/ScheduledTask.cs | 2 ++ Disco.Services/Tasks/ScheduledTaskStatus.cs | 13 ++++++++ .../Areas/API/Controllers/PluginController.cs | 15 +++++++--- .../Config/Controllers/PluginsController.cs | 2 +- .../Areas/Config/Views/Plugins/Install.cshtml | 2 +- .../Config/Views/Plugins/Install.generated.cs | 30 +++++++++---------- Disco.Web/T4MVC.cs | 15 ++++++++-- 7 files changed, 55 insertions(+), 24 deletions(-) diff --git a/Disco.Services/Tasks/ScheduledTask.cs b/Disco.Services/Tasks/ScheduledTask.cs index f5856a09..cd5f0623 100644 --- a/Disco.Services/Tasks/ScheduledTask.cs +++ b/Disco.Services/Tasks/ScheduledTask.cs @@ -90,6 +90,8 @@ namespace Disco.Services.Tasks if (!this.Status.FinishedTimestamp.HasValue) // Scheduled Task Didn't Trigger 'Finished' this.Status.Finished(); + this.Status.Finally(); + var nextTriggerTime = context.NextFireTimeUtc; if (nextTriggerTime.HasValue) { // Continuous Task diff --git a/Disco.Services/Tasks/ScheduledTaskStatus.cs b/Disco.Services/Tasks/ScheduledTaskStatus.cs index 3c77477e..2e1a138b 100644 --- a/Disco.Services/Tasks/ScheduledTaskStatus.cs +++ b/Disco.Services/Tasks/ScheduledTaskStatus.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Quartz; using System.Web.Script.Serialization; +using System.Threading; namespace Disco.Services.Tasks { @@ -15,6 +16,7 @@ namespace Disco.Services.Tasks private string _triggerKey; private string _taskName; private Type _taskType; + private EventWaitHandle _waitHandle; private bool _isSilent; private byte _progress; @@ -85,6 +87,7 @@ namespace Disco.Services.Tasks { this._taskName = Task.TaskName; this._taskType = Task.GetType(); + this._waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); this._sessionId = SessionId; this._triggerKey = TriggerKey; @@ -285,8 +288,14 @@ namespace Disco.Services.Tasks } UpdateTriggered(changedProperties.ToArray()); } + internal void Finally() + { + this._waitHandle.Set(); + } public void Reset(DateTime? NextScheduledTimestamp) { + this._waitHandle.Reset(); + List changedProperties = new List(); if (this._nextScheduledTimestamp != NextScheduledTimestamp) @@ -337,6 +346,10 @@ namespace Disco.Services.Tasks } UpdateTriggered(changedProperties.ToArray()); } + public bool WaitUntilFinished(TimeSpan Timeout) + { + return this._waitHandle.WaitOne(Timeout); + } #endregion private void UpdateTriggered(string[] ChangedProperties) diff --git a/Disco.Web/Areas/API/Controllers/PluginController.cs b/Disco.Web/Areas/API/Controllers/PluginController.cs index 2142976f..06260a2c 100644 --- a/Disco.Web/Areas/API/Controllers/PluginController.cs +++ b/Disco.Web/Areas/API/Controllers/PluginController.cs @@ -15,13 +15,20 @@ namespace Disco.Web.Areas.API.Controllers public partial class PluginController : AuthorizedDatabaseController { [DiscoAuthorize(Claims.Config.Plugin.Install)] - public virtual ActionResult UpdateLibraryCatalogue() + public virtual ActionResult UpdateLibraryCatalogue(bool TryWaitingForCompletion = false) { var status = PluginLibraryUpdateTask.ScheduleNow(); - status.SetFinishedUrl(Url.Action(MVC.Config.Plugins.Install())); - - return RedirectToAction(MVC.Config.Logging.TaskStatus(status.SessionId)); + // If upload takes <= 2 seconds, return back to Plugin Install (rather than Task Status) + if (TryWaitingForCompletion && status.WaitUntilFinished(TimeSpan.FromSeconds(3)) && status.TaskException == null) + { + return RedirectToAction(MVC.Config.Plugins.Install()); + } + else + { + status.SetFinishedUrl(Url.Action(MVC.Config.Plugins.Install())); + return RedirectToAction(MVC.Config.Logging.TaskStatus(status.SessionId)); + } } [DiscoAuthorize(Claims.Config.Plugin.Install)] diff --git a/Disco.Web/Areas/Config/Controllers/PluginsController.cs b/Disco.Web/Areas/Config/Controllers/PluginsController.cs index ace52205..da36119f 100644 --- a/Disco.Web/Areas/Config/Controllers/PluginsController.cs +++ b/Disco.Web/Areas/Config/Controllers/PluginsController.cs @@ -75,7 +75,7 @@ namespace Disco.Web.Areas.Config.Controllers if (catalogue == null || catalogue.ResponseTimestamp < DateTime.Now.AddHours(-1)) { // Need to Update Catalogue (over 1 hour old) - return RedirectToAction(MVC.API.Plugin.UpdateLibraryCatalogue()); + return RedirectToAction(MVC.API.Plugin.UpdateLibraryCatalogue(true)); } else { diff --git a/Disco.Web/Areas/Config/Views/Plugins/Install.cshtml b/Disco.Web/Areas/Config/Views/Plugins/Install.cshtml index fbbea279..60c6faca 100644 --- a/Disco.Web/Areas/Config/Views/Plugins/Install.cshtml +++ b/Disco.Web/Areas/Config/Views/Plugins/Install.cshtml @@ -8,7 +8,7 @@ ViewBag.Title = Html.ToBreadcrumb("Configuration", MVC.Config.Config.Index(), "Plugins", MVC.Config.Plugins.Index(), "Install Plugin"); }
-

The plugin catalogue [https://discoict.com.au] was last updated @CommonHelpers.FriendlyDate(Model.Catalogue.ResponseTimestamp) +

The plugin catalogue [https://discoict.com.au] was last updated @CommonHelpers.FriendlyDate((Model.Catalogue.ResponseTimestamp > DateTime.Now ? DateTime.Now : Model.Catalogue.ResponseTimestamp))

@if (Model.Catalogue.Plugins.Count == 0) { diff --git a/Disco.Web/Areas/Config/Views/Plugins/Install.generated.cs b/Disco.Web/Areas/Config/Views/Plugins/Install.generated.cs index dd800ee5..a5e67cb4 100644 --- a/Disco.Web/Areas/Config/Views/Plugins/Install.generated.cs +++ b/Disco.Web/Areas/Config/Views/Plugins/Install.generated.cs @@ -77,7 +77,7 @@ WriteLiteral(">https://discoict.com.au] was last updated "); #line 11 "..\..\Areas\Config\Views\Plugins\Install.cshtml" - Write(CommonHelpers.FriendlyDate(Model.Catalogue.ResponseTimestamp)); + Write(CommonHelpers.FriendlyDate((Model.Catalogue.ResponseTimestamp > DateTime.Now ? DateTime.Now : Model.Catalogue.ResponseTimestamp))); #line default @@ -161,16 +161,16 @@ WriteLiteral(" \r\n"); #line hidden WriteLiteral(" (installedPlugin != null ? " pluginInstalled" : string.Empty +, Tuple.Create(Tuple.Create("", 1693), Tuple.Create(installedPlugin != null ? " pluginInstalled" : string.Empty #line default #line hidden -, 1625), false) +, 1693), false) ); WriteLiteral(">\r\n (Url.Action(MVC.API.Plugin.Install(plugin.Id)) + , Tuple.Create(Tuple.Create("", 2042), Tuple.Create(Url.Action(MVC.API.Plugin.Install(plugin.Id)) #line default #line hidden -, 1974), false) +, 2042), false) ); WriteLiteral(">Install\r\n"); @@ -237,14 +237,14 @@ WriteLiteral(" (Url.Action(MVC.API.Plugin.Update(plugin.Id)) + , Tuple.Create(Tuple.Create("", 2457), Tuple.Create(Url.Action(MVC.API.Plugin.Update(plugin.Id)) #line default #line hidden -, 2389), false) +, 2457), false) ); WriteLiteral(">Update \r\n"); @@ -328,14 +328,14 @@ WriteLiteral(" | "); #line hidden WriteLiteral(" | (plugin.Url + , Tuple.Create(Tuple.Create("", 3218), Tuple.Create(plugin.Url #line default #line hidden -, 3150), false) +, 3218), false) ); WriteLiteral(" title=\"More Information\""); diff --git a/Disco.Web/T4MVC.cs b/Disco.Web/T4MVC.cs index 8cc8e657..5f1204d0 100644 --- a/Disco.Web/T4MVC.cs +++ b/Disco.Web/T4MVC.cs @@ -7930,6 +7930,14 @@ namespace Disco.Web.Areas.API.Controllers } + static readonly ActionParamsClass_UpdateLibraryCatalogue s_params_UpdateLibraryCatalogue = new ActionParamsClass_UpdateLibraryCatalogue(); + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public ActionParamsClass_UpdateLibraryCatalogue UpdateLibraryCatalogueParams { get { return s_params_UpdateLibraryCatalogue; } } + [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] + public class ActionParamsClass_UpdateLibraryCatalogue + { + public readonly string TryWaitingForCompletion = "TryWaitingForCompletion"; + } static readonly ActionParamsClass_Update s_params_Update = new ActionParamsClass_Update(); [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] public ActionParamsClass_Update UpdateParams { get { return s_params_Update; } } @@ -7991,12 +7999,13 @@ namespace Disco.Web.Areas.API.Controllers { public T4MVC_PluginController() : base(Dummy.Instance) { } - partial void UpdateLibraryCatalogueOverride(T4MVC_System_Web_Mvc_ActionResult callInfo); + partial void UpdateLibraryCatalogueOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, bool TryWaitingForCompletion); - public override System.Web.Mvc.ActionResult UpdateLibraryCatalogue() + public override System.Web.Mvc.ActionResult UpdateLibraryCatalogue(bool TryWaitingForCompletion) { var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpdateLibraryCatalogue); - UpdateLibraryCatalogueOverride(callInfo); + ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "TryWaitingForCompletion", TryWaitingForCompletion); + UpdateLibraryCatalogueOverride(callInfo, TryWaitingForCompletion); return callInfo; }