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:
Gary Sharp
2013-02-14 19:00:01 +11:00
parent 734b02fa1d
commit 8f769809c2
53 changed files with 3795 additions and 2975 deletions
@@ -1,10 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quartz;
namespace Disco.Services.Tasks
{
}
+193 -190
View File
@@ -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);
}
}
}
}