Update: SignalR 2.0.3 Migration; Noticeboards
Migrate all SignalR 1.x Persistent Connections to SignalR 2.x Hubs. Abstracts ScheduledTaskStatus with core interface and adds a Mock for optional status reporting. Noticeboards rewritten (with new theme) to be more resilient and accurate.
This commit is contained in:
+19
-1
@@ -6,12 +6,22 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Services.Tasks
|
||||
{
|
||||
public interface IScheduledTaskBasicStatus
|
||||
public interface IScheduledTaskStatus
|
||||
{
|
||||
byte Progress { get; }
|
||||
string CurrentProcess { get; }
|
||||
string CurrentDescription { get; }
|
||||
|
||||
bool IgnoreCurrentProcessChanges { get; set; }
|
||||
bool IgnoreCurrentDescription { get; set; }
|
||||
double ProgressMultiplier { get; set; }
|
||||
byte ProgressOffset { get; set; }
|
||||
|
||||
string FinishedMessage { get; }
|
||||
string FinishedUrl { get; }
|
||||
|
||||
Exception TaskException { get; }
|
||||
|
||||
void UpdateStatus(byte Progress);
|
||||
void UpdateStatus(double Progress);
|
||||
void UpdateStatus(string CurrentDescription);
|
||||
@@ -19,5 +29,13 @@ namespace Disco.Services.Tasks
|
||||
void UpdateStatus(double Progress, string CurrentDescription);
|
||||
void UpdateStatus(byte Progress, string CurrentProcess, string CurrentDescription);
|
||||
void UpdateStatus(double Progress, string CurrentProcess, string CurrentDescription);
|
||||
|
||||
void SetFinishedUrl(string FinishedUrl);
|
||||
void SetFinishedMessage(string FinishedMessage);
|
||||
void Finished();
|
||||
void Finished(string FinishedMessage);
|
||||
void Finished(string FinishedMessage, string FinishedUrl);
|
||||
|
||||
void SetTaskException(Exception TaskException);
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,8 @@ namespace Disco.Services.Tasks
|
||||
|
||||
public virtual bool CancelInitiallySupported { get { return true; } }
|
||||
public virtual bool SingleInstanceTask { get { return true; } }
|
||||
public virtual bool IsSilent { get { return false; } }
|
||||
public virtual bool LogExceptionsOnly { get { return false; } }
|
||||
|
||||
public abstract string TaskName { get; }
|
||||
protected abstract void ExecuteTask();
|
||||
|
||||
|
||||
@@ -6,19 +6,30 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Services.Tasks
|
||||
{
|
||||
public class ScheduledTaskMockStatus : IScheduledTaskBasicStatus
|
||||
public class ScheduledTaskMockStatus : IScheduledTaskStatus
|
||||
{
|
||||
private byte progress;
|
||||
private string currentProcess;
|
||||
private string currentDescription;
|
||||
public byte Progress { get; set; }
|
||||
public string CurrentProcess { get; set; }
|
||||
public string CurrentDescription { get; set; }
|
||||
|
||||
public byte Progress { get { return this.progress; } }
|
||||
public string CurrentProcess { get { return this.currentProcess; } }
|
||||
public string CurrentDescription { get { return this.currentDescription; } }
|
||||
public bool IgnoreCurrentProcessChanges { get; set; }
|
||||
public bool IgnoreCurrentDescription { get; set; }
|
||||
public double ProgressMultiplier { get; set; }
|
||||
public byte ProgressOffset { get; set; }
|
||||
|
||||
public string FinishedMessage { get; set; }
|
||||
public string FinishedUrl { get; set; }
|
||||
|
||||
public Exception TaskException { get; set; }
|
||||
|
||||
private byte CalculateProgressValue(byte Progress)
|
||||
{
|
||||
return (byte)((Progress * this.ProgressMultiplier) + this.ProgressOffset);
|
||||
}
|
||||
|
||||
public void UpdateStatus(byte Progress)
|
||||
{
|
||||
this.progress = Progress;
|
||||
this.Progress = CalculateProgressValue(Progress);
|
||||
}
|
||||
public void UpdateStatus(double Progress)
|
||||
{
|
||||
@@ -26,12 +37,14 @@ namespace Disco.Services.Tasks
|
||||
}
|
||||
public void UpdateStatus(string CurrentDescription)
|
||||
{
|
||||
this.currentDescription = CurrentDescription;
|
||||
if (!IgnoreCurrentDescription)
|
||||
this.CurrentDescription = CurrentDescription;
|
||||
}
|
||||
public void UpdateStatus(byte Progress, string CurrentDescription)
|
||||
{
|
||||
this.progress = Progress;
|
||||
this.currentDescription = CurrentDescription;
|
||||
this.Progress = CalculateProgressValue(Progress);
|
||||
if (!IgnoreCurrentDescription)
|
||||
this.CurrentDescription = CurrentDescription;
|
||||
}
|
||||
public void UpdateStatus(double Progress, string CurrentDescription)
|
||||
{
|
||||
@@ -39,15 +52,46 @@ namespace Disco.Services.Tasks
|
||||
}
|
||||
public void UpdateStatus(byte Progress, string CurrentProcess, string CurrentDescription)
|
||||
{
|
||||
this.progress = Progress;
|
||||
this.currentProcess = CurrentProcess;
|
||||
this.currentDescription = CurrentDescription;
|
||||
this.Progress = CalculateProgressValue(Progress);
|
||||
if (!IgnoreCurrentProcessChanges)
|
||||
this.CurrentProcess = CurrentProcess;
|
||||
if (!IgnoreCurrentDescription)
|
||||
this.CurrentDescription = CurrentDescription;
|
||||
}
|
||||
public void UpdateStatus(double Progress, string CurrentProcess, string CurrentDescription)
|
||||
{
|
||||
UpdateStatus((byte)Progress, CurrentProcess, CurrentDescription);
|
||||
}
|
||||
|
||||
public void SetFinishedUrl(string FinishedUrl)
|
||||
{
|
||||
this.FinishedUrl = FinishedUrl;
|
||||
}
|
||||
public void SetFinishedMessage(string FinishedMessage)
|
||||
{
|
||||
this.FinishedMessage = FinishedMessage;
|
||||
}
|
||||
public void Finished()
|
||||
{
|
||||
Finished(this.FinishedMessage, this.FinishedUrl);
|
||||
}
|
||||
public void Finished(string FinishedMessage)
|
||||
{
|
||||
Finished(FinishedMessage, this.FinishedUrl);
|
||||
}
|
||||
public void Finished(string FinishedMessage, string FinishedUrl)
|
||||
{
|
||||
this.FinishedMessage = FinishedMessage;
|
||||
this.FinishedUrl = FinishedUrl;
|
||||
}
|
||||
|
||||
public void SetTaskException(Exception TaskException)
|
||||
{
|
||||
this.TaskException = TaskException;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static ScheduledTaskMockStatus Create()
|
||||
{
|
||||
return new ScheduledTaskMockStatus();
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
using Disco.Services.Web.Signalling;
|
||||
using Microsoft.AspNet.SignalR;
|
||||
using Microsoft.AspNet.SignalR.Hubs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Linq;
|
||||
using System.Linq;
|
||||
|
||||
namespace Disco.Services.Tasks
|
||||
{
|
||||
using System.Reactive.Subjects;
|
||||
using ChangedItem = KeyValuePair<string, object>;
|
||||
|
||||
[HubName("scheduledTaskNotifications"), DiscoHubAuthorize()]
|
||||
public class ScheduledTaskNotificationsHub : Hub
|
||||
{
|
||||
private const string NotificationsPrefix = "Logging_";
|
||||
private static Subject<Tuple<string, IEnumerable<ChangedItem>>> taskUpdatesStream = new Subject<Tuple<string, IEnumerable<ChangedItem>>>();
|
||||
private static IDisposable taskUpdatesStreamSubscription;
|
||||
|
||||
internal static void Initialize()
|
||||
{
|
||||
if (taskUpdatesStreamSubscription == null)
|
||||
{
|
||||
lock (taskUpdatesStream)
|
||||
{
|
||||
if (taskUpdatesStreamSubscription == null)
|
||||
{
|
||||
taskUpdatesStreamSubscription = taskUpdatesStream
|
||||
.DelayBuffer(TimeSpan.FromMilliseconds(200))
|
||||
.Subscribe(BroadcastBufferedEvents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void PublishEvent(string TaskSessionId, IEnumerable<ChangedItem> ChangedItems)
|
||||
{
|
||||
taskUpdatesStream.OnNext(Tuple.Create(TaskSessionId, ChangedItems));
|
||||
}
|
||||
|
||||
public override System.Threading.Tasks.Task OnConnected()
|
||||
{
|
||||
var taskSessionId = Context.QueryString["TaskSessionId"];
|
||||
|
||||
if (string.IsNullOrEmpty(taskSessionId))
|
||||
throw new ArgumentNullException("TaskSessionId");
|
||||
|
||||
var status = ScheduledTasks.GetTaskStatus(taskSessionId);
|
||||
|
||||
if (status == null)
|
||||
throw new ArgumentException("Invalid ScheduledTask SessionId", "TaskSessionId");
|
||||
|
||||
// Send Status:
|
||||
var currentStatus = ScheduledTaskStatusLive.FromScheduledTaskStatus(status, null);
|
||||
Clients.Caller.initializeTaskStatus(currentStatus);
|
||||
|
||||
// Add to Group
|
||||
var groupName = NotificationsPrefix + taskSessionId;
|
||||
Groups.Add(Context.ConnectionId, groupName);
|
||||
|
||||
return base.OnConnected();
|
||||
}
|
||||
|
||||
private static void BroadcastBufferedEvents(IEnumerable<Tuple<string, IEnumerable<ChangedItem>>> Events)
|
||||
{
|
||||
var connectionManager = GlobalHost.ConnectionManager;
|
||||
var context = connectionManager.GetHubContext<ScheduledTaskNotificationsHub>();
|
||||
|
||||
var taskStatusEvents = Events.GroupBy(e => e.Item1).Select(taskEventsGroup =>
|
||||
{
|
||||
Dictionary<string, object> changes = new Dictionary<string, object>();
|
||||
|
||||
foreach (var changeEvents in taskEventsGroup.Select(taskEvents => taskEvents.Item2))
|
||||
foreach (var changeEvent in changeEvents)
|
||||
changes[changeEvent.Key] = changeEvent.Value;
|
||||
|
||||
return Tuple.Create(taskEventsGroup.Key, changes);
|
||||
});
|
||||
|
||||
foreach (var taskStatusEvent in taskStatusEvents)
|
||||
{
|
||||
var groupName = NotificationsPrefix + taskStatusEvent.Item1;
|
||||
context.Clients.Group(groupName).updateTaskStatus(taskStatusEvent.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Services.Tasks
|
||||
{
|
||||
public class ScheduledTaskStatus : IScheduledTaskBasicStatus
|
||||
using ChangedItem = KeyValuePair<string, object>;
|
||||
|
||||
public class ScheduledTaskStatus : IScheduledTaskStatus
|
||||
{
|
||||
#region Backing Fields
|
||||
|
||||
@@ -52,6 +54,11 @@ namespace Disco.Services.Tasks
|
||||
public string CurrentProcess { get { return this._currentProcess; } }
|
||||
public string CurrentDescription { get { return this._currentDescription; } }
|
||||
|
||||
public bool IgnoreCurrentProcessChanges { get; set; }
|
||||
public bool IgnoreCurrentDescription { get; set; }
|
||||
public double ProgressMultiplier { get; set; }
|
||||
public byte ProgressOffset { get; set; }
|
||||
|
||||
public Exception TaskException { get { return this._taskException; } }
|
||||
public bool CancelSupported { get { return this._cancelSupported; } }
|
||||
public bool IsCanceling { get { return this._isCanceling; } }
|
||||
@@ -73,21 +80,13 @@ namespace Disco.Services.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
public Task CompletionTask
|
||||
{
|
||||
get
|
||||
{
|
||||
return _tcs.Task;
|
||||
}
|
||||
}
|
||||
public Task CompletionTask { get { return _tcs.Task; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
public delegate void UpdatedBroadcastEvent(ScheduledTaskStatusLive SessionStatus);
|
||||
public delegate void UpdatedEvent(ScheduledTaskStatus sender, string[] ChangedProperties);
|
||||
public delegate void UpdatedEvent(ScheduledTaskStatus sender, KeyValuePair<string, object>[] ChangedProperties);
|
||||
public delegate void CancelingEvent(ScheduledTaskStatus sender);
|
||||
public static event UpdatedBroadcastEvent UpdatedBroadcast;
|
||||
public event UpdatedEvent Updated;
|
||||
public event CancelingEvent Canceling;
|
||||
#endregion
|
||||
@@ -112,10 +111,15 @@ namespace Disco.Services.Tasks
|
||||
}
|
||||
|
||||
#region Progress Actions
|
||||
private byte CalculateProgressValue(byte Progress)
|
||||
{
|
||||
return (byte)((Progress * this.ProgressMultiplier) + this.ProgressOffset);
|
||||
}
|
||||
|
||||
public void UpdateStatus(byte Progress)
|
||||
{
|
||||
this._progress = Progress;
|
||||
UpdateTriggered(new string[] { "Progress" });
|
||||
this._progress = CalculateProgressValue(Progress);
|
||||
UpdateTriggered("Progress", this._progress);
|
||||
}
|
||||
public void UpdateStatus(double Progress)
|
||||
{
|
||||
@@ -123,14 +127,27 @@ namespace Disco.Services.Tasks
|
||||
}
|
||||
public void UpdateStatus(string CurrentDescription)
|
||||
{
|
||||
this._currentDescription = CurrentDescription;
|
||||
UpdateTriggered(new string[] { "CurrentDescription" });
|
||||
if (!IgnoreCurrentDescription)
|
||||
{
|
||||
this._currentDescription = CurrentDescription;
|
||||
UpdateTriggered("CurrentDescription", this._currentDescription);
|
||||
}
|
||||
}
|
||||
public void UpdateStatus(byte Progress, string CurrentDescription)
|
||||
{
|
||||
this._progress = Progress;
|
||||
this._currentDescription = CurrentDescription;
|
||||
UpdateTriggered(new string[] { "Progress", "CurrentDescription" });
|
||||
this._progress = CalculateProgressValue(Progress);
|
||||
|
||||
var changedProperties = new List<ChangedItem>() {
|
||||
new ChangedItem("Progress", Progress)
|
||||
};
|
||||
|
||||
if (!IgnoreCurrentDescription)
|
||||
{
|
||||
this._currentDescription = CurrentDescription;
|
||||
changedProperties.Add(new ChangedItem("CurrentDescription", CurrentDescription));
|
||||
}
|
||||
|
||||
UpdateTriggered(changedProperties.ToArray());
|
||||
}
|
||||
public void UpdateStatus(double Progress, string CurrentDescription)
|
||||
{
|
||||
@@ -138,10 +155,24 @@ namespace Disco.Services.Tasks
|
||||
}
|
||||
public void UpdateStatus(byte Progress, string CurrentProcess, string CurrentDescription)
|
||||
{
|
||||
this._progress = Progress;
|
||||
this._currentProcess = CurrentProcess;
|
||||
this._currentDescription = CurrentDescription;
|
||||
UpdateTriggered(new string[] { "Progress", "CurrentProcess", "CurrentDescription" });
|
||||
this._progress = CalculateProgressValue(Progress);
|
||||
|
||||
var changedProperties = new List<ChangedItem>() {
|
||||
new ChangedItem("Progress", Progress)
|
||||
};
|
||||
|
||||
if (!IgnoreCurrentProcessChanges)
|
||||
{
|
||||
this._currentProcess = CurrentProcess;
|
||||
changedProperties.Add(new ChangedItem("CurrentProcess", CurrentProcess));
|
||||
}
|
||||
if (!IgnoreCurrentDescription)
|
||||
{
|
||||
this._currentDescription = CurrentDescription;
|
||||
changedProperties.Add(new ChangedItem("CurrentDescription", CurrentDescription));
|
||||
}
|
||||
|
||||
UpdateTriggered(changedProperties.ToArray());
|
||||
}
|
||||
public void UpdateStatus(double Progress, string CurrentProcess, string CurrentDescription)
|
||||
{
|
||||
@@ -157,7 +188,7 @@ namespace Disco.Services.Tasks
|
||||
if (_cancelSupported)
|
||||
{ // Cancelling
|
||||
this._isCanceling = true;
|
||||
UpdateTriggered(new string[] { "IsCancelling" });
|
||||
UpdateTriggered("IsCancelling", true);
|
||||
if (this.Canceling != null)
|
||||
Canceling(this);
|
||||
return true;
|
||||
@@ -177,7 +208,7 @@ namespace Disco.Services.Tasks
|
||||
if (this._cancelSupported != CancelSupported)
|
||||
{
|
||||
this._cancelSupported = CancelSupported;
|
||||
UpdateTriggered(new string[] { "CancelSupported" });
|
||||
UpdateTriggered("CancelSupported", CancelSupported);
|
||||
}
|
||||
}
|
||||
public void SetTaskException(Exception TaskException)
|
||||
@@ -185,7 +216,7 @@ namespace Disco.Services.Tasks
|
||||
if (this._taskException != TaskException)
|
||||
{
|
||||
this._taskException = TaskException;
|
||||
UpdateTriggered(new string[] { "TaskException" });
|
||||
UpdateTriggered("TaskExceptionMessage", (this._taskException == null ? null : this._taskException.Message));
|
||||
}
|
||||
}
|
||||
public void SetIsSilent(bool IsSilent)
|
||||
@@ -198,7 +229,7 @@ namespace Disco.Services.Tasks
|
||||
if (this._finishedUrl != FinishedUrl)
|
||||
{
|
||||
this._finishedUrl = FinishedUrl;
|
||||
UpdateTriggered(new string[] { "FinishedUrl" });
|
||||
UpdateTriggered("FinishedUrl", FinishedUrl);
|
||||
}
|
||||
}
|
||||
public void SetFinishedMessage(string FinishedMessage)
|
||||
@@ -206,7 +237,7 @@ namespace Disco.Services.Tasks
|
||||
if (this._finishedMessage != FinishedMessage)
|
||||
{
|
||||
this._finishedMessage = FinishedMessage;
|
||||
UpdateTriggered(new string[] { "FinishedMessage" });
|
||||
UpdateTriggered("FinishedMessage", FinishedMessage);
|
||||
}
|
||||
}
|
||||
public void SetNextScheduledTimestamp(DateTime? NextScheduledTimestamp)
|
||||
@@ -214,59 +245,62 @@ namespace Disco.Services.Tasks
|
||||
if (this._nextScheduledTimestamp != NextScheduledTimestamp)
|
||||
{
|
||||
this._nextScheduledTimestamp = NextScheduledTimestamp;
|
||||
UpdateTriggered(new string[] { "NextScheduledTimestamp" });
|
||||
UpdateTriggered("NextScheduledTimestamp", NextScheduledTimestamp);
|
||||
}
|
||||
}
|
||||
public void Started()
|
||||
{
|
||||
List<string> changedProperties = new List<string>() { "IsRunning", "StartedTimestamp" };
|
||||
var changedProperties = new List<ChangedItem>();
|
||||
|
||||
// Change StartedTimestamp
|
||||
this._startedTimestamp = DateTime.Now;
|
||||
changedProperties.Add(new ChangedItem("StartedTimestamp", this.StartedTimestamp));
|
||||
|
||||
if (this._finishedTimestamp != null)
|
||||
{
|
||||
this._finishedTimestamp = null;
|
||||
changedProperties.Add(new ChangedItem("FinishedTimestamp", this._finishedTimestamp));
|
||||
}
|
||||
|
||||
if (this._nextScheduledTimestamp != null)
|
||||
{
|
||||
this._nextScheduledTimestamp = null;
|
||||
changedProperties.Add("NextScheduledTimestamp");
|
||||
}
|
||||
if (this._finishedTimestamp != null)
|
||||
{
|
||||
this._finishedTimestamp = null;
|
||||
changedProperties.Add("FinishedTimestamp");
|
||||
changedProperties.Add(new ChangedItem("NextScheduledTimestamp", this._nextScheduledTimestamp));
|
||||
}
|
||||
|
||||
changedProperties.Add(new ChangedItem("IsRunning", this.IsRunning));
|
||||
|
||||
if (this._progress != 0)
|
||||
{
|
||||
this._progress = 0;
|
||||
changedProperties.Add("Progress");
|
||||
changedProperties.Add(new ChangedItem("Progress", this._progress));
|
||||
}
|
||||
if (this._currentProcess != "Starting")
|
||||
{
|
||||
this._currentProcess = "Starting";
|
||||
changedProperties.Add("CurrentProcess");
|
||||
changedProperties.Add(new ChangedItem("CurrentProcess", this._currentProcess));
|
||||
}
|
||||
if (this._currentDescription != "Initializing Task for Execution")
|
||||
{
|
||||
this._currentDescription = "Initializing Task for Execution";
|
||||
changedProperties.Add("CurrentDescription");
|
||||
changedProperties.Add(new ChangedItem("CurrentDescription", this._currentDescription));
|
||||
}
|
||||
if (this._taskException != null)
|
||||
{
|
||||
this._taskException = null;
|
||||
changedProperties.Add("TaskException");
|
||||
changedProperties.Add(new ChangedItem("TaskExceptionMessage", (this._taskException == null ? null : this._taskException.Message)));
|
||||
}
|
||||
if (this._cancelSupported != this._cancelInitiallySupported)
|
||||
{
|
||||
this._cancelSupported = this._cancelInitiallySupported;
|
||||
changedProperties.Add("CancelSupported");
|
||||
}
|
||||
{
|
||||
this._isCanceling = false;
|
||||
changedProperties.Add("IsCanceling");
|
||||
changedProperties.Add(new ChangedItem("CancelSupported", this._cancelSupported));
|
||||
}
|
||||
if (this._isCanceling)
|
||||
{
|
||||
this._isCanceling = false;
|
||||
changedProperties.Add("IsCanceling");
|
||||
changedProperties.Add(new ChangedItem("IsCanceling", this._isCanceling));
|
||||
}
|
||||
|
||||
UpdateTriggered(changedProperties.ToArray());
|
||||
}
|
||||
public void Finished()
|
||||
@@ -279,26 +313,29 @@ namespace Disco.Services.Tasks
|
||||
}
|
||||
public void Finished(string FinishedMessage, string FinishedUrl)
|
||||
{
|
||||
List<string> changedProperties = new List<string>() { "IsRunning", "FinishedTimestamp" };
|
||||
var changedProperties = new List<ChangedItem>();
|
||||
|
||||
this._finishedTimestamp = DateTime.Now;
|
||||
changedProperties.Add(new ChangedItem("FinishedTimestamp", this._finishedTimestamp));
|
||||
changedProperties.Add(new ChangedItem("IsRunning", this.IsRunning));
|
||||
|
||||
if (FinishedMessage != this._finishedMessage)
|
||||
{
|
||||
this._finishedMessage = FinishedMessage;
|
||||
changedProperties.Add("FinishedMessage");
|
||||
changedProperties.Add(new ChangedItem("FinishedMessage", this._finishedMessage));
|
||||
}
|
||||
if (FinishedUrl != this._finishedUrl)
|
||||
{
|
||||
this._finishedUrl = FinishedUrl;
|
||||
changedProperties.Add("FinishedUrl");
|
||||
changedProperties.Add(new ChangedItem("FinishedUrl", this._finishedUrl));
|
||||
}
|
||||
|
||||
if (this._isCanceling)
|
||||
{
|
||||
this._isCanceling = false;
|
||||
changedProperties.Add("IsCanceling");
|
||||
changedProperties.Add(new ChangedItem("IsCanceling", this._isCanceling));
|
||||
}
|
||||
|
||||
UpdateTriggered(changedProperties.ToArray());
|
||||
}
|
||||
internal void Finally()
|
||||
@@ -311,53 +348,58 @@ namespace Disco.Services.Tasks
|
||||
this._tcs.Task.Dispose();
|
||||
this._tcs = new TaskCompletionSource<ScheduledTaskStatus>();
|
||||
|
||||
List<string> changedProperties = new List<string>();
|
||||
var changedProperties = new List<ChangedItem>();
|
||||
|
||||
if (this._nextScheduledTimestamp != NextScheduledTimestamp)
|
||||
{
|
||||
this._nextScheduledTimestamp = NextScheduledTimestamp;
|
||||
changedProperties.Add("NextScheduledTimestamp");
|
||||
changedProperties.Add(new ChangedItem("NextScheduledTimestamp", this._nextScheduledTimestamp));
|
||||
}
|
||||
|
||||
if (this._startedTimestamp != null)
|
||||
{
|
||||
this._startedTimestamp = null;
|
||||
changedProperties.Add("StartedTimestamp");
|
||||
changedProperties.Add(new ChangedItem("StartedTimestamp", this._startedTimestamp));
|
||||
}
|
||||
if (this._finishedTimestamp != null)
|
||||
{
|
||||
this._finishedTimestamp = null;
|
||||
changedProperties.Add("FinishedTimestamp");
|
||||
changedProperties.Add(new ChangedItem("FinishedTimestamp", this._finishedTimestamp));
|
||||
}
|
||||
if (this._finishedMessage != null)
|
||||
{
|
||||
this._finishedMessage = null;
|
||||
changedProperties.Add("FinishedMessage");
|
||||
changedProperties.Add(new ChangedItem("FinishedMessage", this._finishedMessage));
|
||||
}
|
||||
if (this._finishedUrl != null)
|
||||
{
|
||||
this._finishedUrl = null;
|
||||
changedProperties.Add("FinishedUrl");
|
||||
changedProperties.Add(new ChangedItem("FinishedUrl", this._finishedUrl));
|
||||
}
|
||||
if (this._progress != 0)
|
||||
{
|
||||
this._progress = 0;
|
||||
changedProperties.Add("Progress");
|
||||
changedProperties.Add(new ChangedItem("Progress", this._progress));
|
||||
}
|
||||
this.ProgressMultiplier = 0;
|
||||
this.ProgressOffset = 0;
|
||||
this.IgnoreCurrentDescription = false;
|
||||
this.IgnoreCurrentProcessChanges = false;
|
||||
|
||||
if (this._currentProcess != "Scheduled")
|
||||
{
|
||||
this._currentProcess = "Scheduled";
|
||||
changedProperties.Add("CurrentProcess");
|
||||
changedProperties.Add(new ChangedItem("CurrentProcess", this._currentProcess));
|
||||
}
|
||||
if (this._currentDescription != "Scheduled Task for Execution")
|
||||
{
|
||||
this._currentDescription = "Scheduled Task for Execution";
|
||||
changedProperties.Add("CurrentDescription");
|
||||
changedProperties.Add(new ChangedItem("CurrentDescription", this._currentDescription));
|
||||
}
|
||||
if (this._isCanceling)
|
||||
{
|
||||
this._isCanceling = false;
|
||||
changedProperties.Add("IsCanceling");
|
||||
changedProperties.Add(new ChangedItem("IsCanceling", this._isCanceling));
|
||||
}
|
||||
UpdateTriggered(changedProperties.ToArray());
|
||||
}
|
||||
@@ -373,15 +415,20 @@ namespace Disco.Services.Tasks
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void UpdateTriggered(string[] ChangedProperties)
|
||||
private void UpdateTriggered(string ChangedProperty, object NewValue)
|
||||
{
|
||||
UpdateTriggered(new ChangedItem[] { new ChangedItem(ChangedProperty, NewValue) });
|
||||
}
|
||||
|
||||
private void UpdateTriggered(params ChangedItem[] ChangedProperties)
|
||||
{
|
||||
this._statusVersion++;
|
||||
|
||||
if (Updated != null)
|
||||
Updated(this, ChangedProperties);
|
||||
|
||||
if (!_isSilent && UpdatedBroadcast != null)
|
||||
UpdatedBroadcast.Invoke(ScheduledTaskStatusLive.FromScheduledTaskStatus(this, ChangedProperties));
|
||||
if (!_isSilent)
|
||||
ScheduledTaskNotificationsHub.PublishEvent(this.SessionId, ChangedProperties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,16 @@ namespace Disco.Services.Tasks
|
||||
// Scheduled Cleanup
|
||||
ScheduledTaskCleanup.Schedule(_TaskScheduler);
|
||||
|
||||
ScheduledTaskNotificationsHub.Initialize();
|
||||
|
||||
if (InitiallySchedule)
|
||||
{
|
||||
// Discover DiscoScheduledTask
|
||||
var appDomain = AppDomain.CurrentDomain;
|
||||
var scheduledTasksHostAssemblyName = typeof(ScheduledTask).Assembly.GetName().Name;
|
||||
|
||||
var scheduledTaskTypes = (from a in appDomain.GetAssemblies()
|
||||
where !a.GlobalAssemblyCache && !a.IsDynamic
|
||||
where !a.GlobalAssemblyCache && !a.IsDynamic && a.GetReferencedAssemblies().Any(ra => ra.Name == scheduledTasksHostAssemblyName)
|
||||
from type in a.GetTypes()
|
||||
where typeof(ScheduledTask).IsAssignableFrom(type) && !type.IsAbstract
|
||||
select type);
|
||||
|
||||
Reference in New Issue
Block a user