Update: Plugin Updating
Updating plugins from the plugin catalogue, and automatic updating of plugins after a newer version of Disco is installed.
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Quartz;
|
||||
|
||||
namespace Disco.Services.Tasks
|
||||
{
|
||||
|
||||
}
|
||||
@@ -1,190 +1,193 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Quartz;
|
||||
using Quartz.Impl;
|
||||
using Disco.Data.Repository;
|
||||
|
||||
namespace Disco.Services.Tasks
|
||||
{
|
||||
public static class ScheduledTasks
|
||||
{
|
||||
internal const string SchedulerGroupName = "DiscoScheduledTasks";
|
||||
private static IScheduler _TaskScheduler;
|
||||
|
||||
private static object _RunningTasksLock = new object();
|
||||
private static List<ScheduledTaskStatus> _RunningTasks = new List<ScheduledTaskStatus>();
|
||||
|
||||
public static void InitalizeScheduledTasks(DiscoDataContext dbContext, ISchedulerFactory SchedulerFactory)
|
||||
{
|
||||
ScheduledTasksLog.LogInitializingScheduledTasks();
|
||||
|
||||
try
|
||||
{
|
||||
_TaskScheduler = SchedulerFactory.GetScheduler();
|
||||
_TaskScheduler.Start();
|
||||
|
||||
// Scheduled Cleanup
|
||||
ScheduledTaskCleanup.Schedule(_TaskScheduler);
|
||||
|
||||
// Discover DiscoScheduledTask
|
||||
var appDomain = AppDomain.CurrentDomain;
|
||||
|
||||
var scheduledTaskTypes = (from a in appDomain.GetAssemblies()
|
||||
where !a.GlobalAssemblyCache && !a.IsDynamic
|
||||
from type in a.GetTypes()
|
||||
where typeof(ScheduledTask).IsAssignableFrom(type) && !type.IsAbstract
|
||||
select type);
|
||||
foreach (Type scheduledTaskType in scheduledTaskTypes)
|
||||
{
|
||||
ScheduledTask instance = (ScheduledTask)Activator.CreateInstance(scheduledTaskType);
|
||||
try
|
||||
{
|
||||
instance.InitalizeScheduledTask(dbContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ScheduledTasksLog.LogInitializeException(ex, scheduledTaskType);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ScheduledTasksLog.LogInitializeException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static ScheduledTaskStatus GetTaskStatus(string TaskSessionId)
|
||||
{
|
||||
return _RunningTasks.Where(t => t.SessionId == TaskSessionId).FirstOrDefault();
|
||||
}
|
||||
public static List<ScheduledTaskStatus> GetTaskStatuses(Type TaskType)
|
||||
{
|
||||
return _RunningTasks.Where(t => t.TaskType == TaskType).ToList();
|
||||
}
|
||||
public static List<ScheduledTaskStatus> GetTaskStatuses()
|
||||
{
|
||||
return _RunningTasks.ToList();
|
||||
}
|
||||
|
||||
public static ScheduledTaskStatus RegisterTask(ScheduledTask Task)
|
||||
{
|
||||
return RegisterTask(Task, null);
|
||||
}
|
||||
public static ScheduledTaskStatus RegisterTask(ScheduledTask Task, TriggerBuilder TaskBuilder)
|
||||
{
|
||||
var sessionId = Guid.NewGuid().ToString("D");
|
||||
var triggerKey = GenerateTriggerKey();
|
||||
var taskType = Task.GetType();
|
||||
|
||||
var taskStatus = new ScheduledTaskStatus(Task, sessionId, triggerKey.Name);
|
||||
|
||||
lock (_RunningTasksLock)
|
||||
{
|
||||
if (Task.SingleInstanceTask)
|
||||
{
|
||||
var existingGuid = _RunningTasks.Where(t => t.IsRunning && t.TaskType == taskType).Select(t => t.SessionId).FirstOrDefault();
|
||||
if (existingGuid != null)
|
||||
throw new InvalidOperationException(string.Format("This Single-Instance Task is already running, SessionId: {0}", existingGuid));
|
||||
}
|
||||
_RunningTasks.Add(taskStatus);
|
||||
}
|
||||
|
||||
if (TaskBuilder != null)
|
||||
{
|
||||
ITrigger trigger = TaskBuilder.WithIdentity(triggerKey).Build();
|
||||
IJobDetail jobDetails = new JobDetailImpl(sessionId, taskType)
|
||||
{
|
||||
Description = Task.TaskName,
|
||||
JobDataMap = trigger.JobDataMap
|
||||
};
|
||||
|
||||
_TaskScheduler.ScheduleJob(jobDetails, trigger);
|
||||
|
||||
var nextTriggerTime = trigger.GetNextFireTimeUtc();
|
||||
if (nextTriggerTime.HasValue)
|
||||
taskStatus.SetNextScheduledTimestamp(nextTriggerTime.Value.LocalDateTime);
|
||||
}
|
||||
|
||||
return taskStatus;
|
||||
}
|
||||
public static bool UnregisterTask(this ScheduledTask Task)
|
||||
{
|
||||
lock (_RunningTasksLock)
|
||||
{
|
||||
if (_RunningTasks.Contains(Task.Status))
|
||||
{
|
||||
//_RunningTasks.Remove(Task.Status);
|
||||
_TaskScheduler.UnscheduleJob(Task.ExecutionContext.Trigger.Key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool UnregisterTask(this ScheduledTaskStatus TaskStatus)
|
||||
{
|
||||
lock (_RunningTasksLock)
|
||||
{
|
||||
if (_RunningTasks.Contains(TaskStatus))
|
||||
{
|
||||
//_RunningTasks.Remove(Task.Status);
|
||||
_TaskScheduler.UnscheduleJob(new TriggerKey(TaskStatus.TriggerKey, SchedulerGroupName));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static TriggerKey GenerateTriggerKey()
|
||||
{
|
||||
return new TriggerKey(Guid.NewGuid().ToString("D"), SchedulerGroupName);
|
||||
}
|
||||
|
||||
public static ScheduledTaskStatus GetDiscoScheduledTaskStatus(this IJobExecutionContext context)
|
||||
{
|
||||
return GetTaskStatus(context.JobDetail.Key.Name);
|
||||
}
|
||||
|
||||
private class ScheduledTaskCleanup : IJob
|
||||
{
|
||||
public void Execute(IJobExecutionContext context)
|
||||
{
|
||||
lock (ScheduledTasks._RunningTasksLock)
|
||||
{
|
||||
// Lifetime = 5mins
|
||||
var expiredTime = DateTime.Now.AddMinutes(-1);
|
||||
var expiredTasks = ScheduledTasks._RunningTasks.Where(
|
||||
t => !t.IsRunning &&
|
||||
!t.NextScheduledTimestamp.HasValue &&
|
||||
t.FinishedTimestamp < expiredTime
|
||||
).ToArray();
|
||||
|
||||
foreach (var expiredTask in expiredTasks)
|
||||
ScheduledTasks._RunningTasks.Remove(expiredTask);
|
||||
}
|
||||
}
|
||||
public static void Schedule(IScheduler TaskScheduler)
|
||||
{
|
||||
// Next 10min interval
|
||||
DateTime now = DateTime.Now;
|
||||
int mins = (10 - (now.Minute % 10));
|
||||
if (mins < 2)
|
||||
mins += 10;
|
||||
DateTimeOffset startAt = new DateTimeOffset(now).AddMinutes(mins).AddSeconds(now.Second * -1).AddMilliseconds(now.Millisecond * -1);
|
||||
ITrigger trigger = TriggerBuilder.Create()
|
||||
.StartAt(startAt)
|
||||
.WithSchedule(SimpleScheduleBuilder.RepeatMinutelyForever(10))
|
||||
.WithIdentity("ScheduledTaskCleanupTrigger", ScheduledTasks.SchedulerGroupName + "_System")
|
||||
.Build();
|
||||
|
||||
IJobDetail job = JobBuilder.Create<ScheduledTaskCleanup>()
|
||||
.WithIdentity("ScheduledTaskCleanupJob", ScheduledTasks.SchedulerGroupName + "_System")
|
||||
.Build();
|
||||
|
||||
_TaskScheduler.ScheduleJob(job, trigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Quartz;
|
||||
using Quartz.Impl;
|
||||
using Disco.Data.Repository;
|
||||
|
||||
namespace Disco.Services.Tasks
|
||||
{
|
||||
public static class ScheduledTasks
|
||||
{
|
||||
internal const string SchedulerGroupName = "DiscoScheduledTasks";
|
||||
private static IScheduler _TaskScheduler;
|
||||
|
||||
private static object _RunningTasksLock = new object();
|
||||
private static List<ScheduledTaskStatus> _RunningTasks = new List<ScheduledTaskStatus>();
|
||||
|
||||
public static void InitalizeScheduledTasks(DiscoDataContext dbContext, ISchedulerFactory SchedulerFactory, bool InitiallySchedule)
|
||||
{
|
||||
ScheduledTasksLog.LogInitializingScheduledTasks();
|
||||
|
||||
try
|
||||
{
|
||||
_TaskScheduler = SchedulerFactory.GetScheduler();
|
||||
_TaskScheduler.Start();
|
||||
|
||||
// Scheduled Cleanup
|
||||
ScheduledTaskCleanup.Schedule(_TaskScheduler);
|
||||
|
||||
if (InitiallySchedule)
|
||||
{
|
||||
// Discover DiscoScheduledTask
|
||||
var appDomain = AppDomain.CurrentDomain;
|
||||
|
||||
var scheduledTaskTypes = (from a in appDomain.GetAssemblies()
|
||||
where !a.GlobalAssemblyCache && !a.IsDynamic
|
||||
from type in a.GetTypes()
|
||||
where typeof(ScheduledTask).IsAssignableFrom(type) && !type.IsAbstract
|
||||
select type);
|
||||
foreach (Type scheduledTaskType in scheduledTaskTypes)
|
||||
{
|
||||
ScheduledTask instance = (ScheduledTask)Activator.CreateInstance(scheduledTaskType);
|
||||
try
|
||||
{
|
||||
instance.InitalizeScheduledTask(dbContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ScheduledTasksLog.LogInitializeException(ex, scheduledTaskType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ScheduledTasksLog.LogInitializeException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static ScheduledTaskStatus GetTaskStatus(string TaskSessionId)
|
||||
{
|
||||
return _RunningTasks.Where(t => t.SessionId == TaskSessionId).FirstOrDefault();
|
||||
}
|
||||
public static List<ScheduledTaskStatus> GetTaskStatuses(Type TaskType)
|
||||
{
|
||||
return _RunningTasks.Where(t => t.TaskType == TaskType).ToList();
|
||||
}
|
||||
public static List<ScheduledTaskStatus> GetTaskStatuses()
|
||||
{
|
||||
return _RunningTasks.ToList();
|
||||
}
|
||||
|
||||
public static ScheduledTaskStatus RegisterTask(ScheduledTask Task)
|
||||
{
|
||||
return RegisterTask(Task, null);
|
||||
}
|
||||
public static ScheduledTaskStatus RegisterTask(ScheduledTask Task, TriggerBuilder TaskBuilder)
|
||||
{
|
||||
var sessionId = Guid.NewGuid().ToString("D");
|
||||
var triggerKey = GenerateTriggerKey();
|
||||
var taskType = Task.GetType();
|
||||
|
||||
var taskStatus = new ScheduledTaskStatus(Task, sessionId, triggerKey.Name);
|
||||
|
||||
lock (_RunningTasksLock)
|
||||
{
|
||||
if (Task.SingleInstanceTask)
|
||||
{
|
||||
var existingGuid = _RunningTasks.Where(t => t.IsRunning && t.TaskType == taskType).Select(t => t.SessionId).FirstOrDefault();
|
||||
if (existingGuid != null)
|
||||
throw new InvalidOperationException(string.Format("This Single-Instance Task is already running, SessionId: {0}", existingGuid));
|
||||
}
|
||||
_RunningTasks.Add(taskStatus);
|
||||
}
|
||||
|
||||
if (TaskBuilder != null)
|
||||
{
|
||||
ITrigger trigger = TaskBuilder.WithIdentity(triggerKey).Build();
|
||||
IJobDetail jobDetails = new JobDetailImpl(sessionId, taskType)
|
||||
{
|
||||
Description = Task.TaskName,
|
||||
JobDataMap = trigger.JobDataMap
|
||||
};
|
||||
|
||||
_TaskScheduler.ScheduleJob(jobDetails, trigger);
|
||||
|
||||
var nextTriggerTime = trigger.GetNextFireTimeUtc();
|
||||
if (nextTriggerTime.HasValue)
|
||||
taskStatus.SetNextScheduledTimestamp(nextTriggerTime.Value.LocalDateTime);
|
||||
}
|
||||
|
||||
return taskStatus;
|
||||
}
|
||||
public static bool UnregisterTask(this ScheduledTask Task)
|
||||
{
|
||||
lock (_RunningTasksLock)
|
||||
{
|
||||
if (_RunningTasks.Contains(Task.Status))
|
||||
{
|
||||
//_RunningTasks.Remove(Task.Status);
|
||||
_TaskScheduler.UnscheduleJob(Task.ExecutionContext.Trigger.Key);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool UnregisterTask(this ScheduledTaskStatus TaskStatus)
|
||||
{
|
||||
lock (_RunningTasksLock)
|
||||
{
|
||||
if (_RunningTasks.Contains(TaskStatus))
|
||||
{
|
||||
//_RunningTasks.Remove(Task.Status);
|
||||
_TaskScheduler.UnscheduleJob(new TriggerKey(TaskStatus.TriggerKey, SchedulerGroupName));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static TriggerKey GenerateTriggerKey()
|
||||
{
|
||||
return new TriggerKey(Guid.NewGuid().ToString("D"), SchedulerGroupName);
|
||||
}
|
||||
|
||||
public static ScheduledTaskStatus GetDiscoScheduledTaskStatus(this IJobExecutionContext context)
|
||||
{
|
||||
return GetTaskStatus(context.JobDetail.Key.Name);
|
||||
}
|
||||
|
||||
private class ScheduledTaskCleanup : IJob
|
||||
{
|
||||
public void Execute(IJobExecutionContext context)
|
||||
{
|
||||
lock (ScheduledTasks._RunningTasksLock)
|
||||
{
|
||||
// Lifetime = 5mins
|
||||
var expiredTime = DateTime.Now.AddMinutes(-1);
|
||||
var expiredTasks = ScheduledTasks._RunningTasks.Where(
|
||||
t => !t.IsRunning &&
|
||||
!t.NextScheduledTimestamp.HasValue &&
|
||||
t.FinishedTimestamp < expiredTime
|
||||
).ToArray();
|
||||
|
||||
foreach (var expiredTask in expiredTasks)
|
||||
ScheduledTasks._RunningTasks.Remove(expiredTask);
|
||||
}
|
||||
}
|
||||
public static void Schedule(IScheduler TaskScheduler)
|
||||
{
|
||||
// Next 10min interval
|
||||
DateTime now = DateTime.Now;
|
||||
int mins = (10 - (now.Minute % 10));
|
||||
if (mins < 2)
|
||||
mins += 10;
|
||||
DateTimeOffset startAt = new DateTimeOffset(now).AddMinutes(mins).AddSeconds(now.Second * -1).AddMilliseconds(now.Millisecond * -1);
|
||||
ITrigger trigger = TriggerBuilder.Create()
|
||||
.StartAt(startAt)
|
||||
.WithSchedule(SimpleScheduleBuilder.RepeatMinutelyForever(10))
|
||||
.WithIdentity("ScheduledTaskCleanupTrigger", ScheduledTasks.SchedulerGroupName + "_System")
|
||||
.Build();
|
||||
|
||||
IJobDetail job = JobBuilder.Create<ScheduledTaskCleanup>()
|
||||
.WithIdentity("ScheduledTaskCleanupJob", ScheduledTasks.SchedulerGroupName + "_System")
|
||||
.Build();
|
||||
|
||||
_TaskScheduler.ScheduleJob(job, trigger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user