Fixes Schedulers bugs
This commit is contained in:
parent
e8ed10a67b
commit
c8a8be8894
7 changed files with 65 additions and 43 deletions
|
@ -110,7 +110,7 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
{
|
{
|
||||||
var taskThread = new Thread(() => RunBackgroundTask(task)) { Priority = ThreadPriority.Highest };
|
var taskThread = new Thread(() => RunBackgroundTask(task)) { Priority = ThreadPriority.Highest };
|
||||||
taskThread.Start();
|
taskThread.Start();
|
||||||
TaskManager.AddTaskThread(task, taskThread);
|
TaskManager.AddTaskThread(task.Id, taskThread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +132,7 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
var objTask = (SchedulerTask)Activator.CreateInstance(Type.GetType(schedule.Task.TaskType));
|
var objTask = (SchedulerTask)Activator.CreateInstance(Type.GetType(schedule.Task.TaskType));
|
||||||
|
|
||||||
objTask.DoWork();
|
objTask.DoWork();
|
||||||
|
// Thread.Sleep(40000);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -160,24 +160,39 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
if (schedule == null)
|
if (schedule == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (TaskController.GetScheduleTasks(scheduleId).Any(x => x.Status == BackgroundTaskStatus.Run
|
||||||
|
|| x.Status == BackgroundTaskStatus.Starting))
|
||||||
|
return 0;
|
||||||
|
|
||||||
var parameters = schedule.ScheduleInfo.Parameters.Select(
|
var parameters = schedule.ScheduleInfo.Parameters.Select(
|
||||||
prm => new BackgroundTaskParameter(prm.ParameterId, prm.ParameterValue)).ToList();
|
prm => new BackgroundTaskParameter(prm.ParameterId, prm.ParameterValue)).ToList();
|
||||||
|
|
||||||
|
var packageInfo = PackageController.GetPackage(schedule.ScheduleInfo.PackageId);
|
||||||
var backgroundTask = new BackgroundTask(
|
var backgroundTask = new BackgroundTask(
|
||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
Guid.NewGuid().ToString("N"),
|
Guid.NewGuid().ToString("N"),
|
||||||
SecurityContext.User.UserId,
|
SecurityContext.User.UserId,
|
||||||
SecurityContext.User.IsPeer
|
SecurityContext.User.IsPeer
|
||||||
? SecurityContext.User.OwnerId
|
? SecurityContext.User.OwnerId
|
||||||
: SecurityContext.User.UserId, "SCHEDULER", "RUN_SCHEDULE",
|
: packageInfo.UserId, "SCHEDULER", "RUN_SCHEDULE",
|
||||||
schedule.ScheduleInfo.ScheduleName,
|
schedule.ScheduleInfo.ScheduleName,
|
||||||
schedule.ScheduleInfo.ScheduleId,
|
schedule.ScheduleInfo.ScheduleId,
|
||||||
schedule.ScheduleInfo.ScheduleId,
|
schedule.ScheduleInfo.ScheduleId,
|
||||||
schedule.ScheduleInfo.PackageId,
|
schedule.ScheduleInfo.PackageId,
|
||||||
schedule.ScheduleInfo.MaxExecutionTime, parameters) { Status = BackgroundTaskStatus.Starting };
|
schedule.ScheduleInfo.MaxExecutionTime, parameters) { Status = BackgroundTaskStatus.Starting };
|
||||||
|
|
||||||
TaskController.AddTask(backgroundTask);
|
TaskController.AddTask(backgroundTask);
|
||||||
|
|
||||||
|
// update next run (if required)
|
||||||
|
CalculateNextStartTime(schedule.ScheduleInfo);
|
||||||
|
|
||||||
|
// disable run once task
|
||||||
|
if (schedule.ScheduleInfo.ScheduleType == ScheduleType.OneTime)
|
||||||
|
schedule.ScheduleInfo.Enabled = false;
|
||||||
|
|
||||||
|
schedule.ScheduleInfo.LastRun = DateTime.Now;
|
||||||
|
UpdateSchedule(schedule.ScheduleInfo);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,7 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
else
|
else
|
||||||
throw new Exception(String.Format("Could not create scheduled task of '{0}' type",
|
throw new Exception(String.Format("Could not create scheduled task of '{0}' type",
|
||||||
task.TaskType));
|
task.TaskType));
|
||||||
|
// Thread.Sleep(40000);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,7 +69,7 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddTask(BackgroundTask task)
|
public static int AddTask(BackgroundTask task)
|
||||||
{
|
{
|
||||||
int taskId = DataProvider.AddBackgroundTask(task.Guid, task.TaskId, task.ScheduleId, task.PackageId, task.UserId,
|
int taskId = DataProvider.AddBackgroundTask(task.Guid, task.TaskId, task.ScheduleId, task.PackageId, task.UserId,
|
||||||
task.EffectiveUserId, task.TaskName, task.ItemId, task.ItemName,
|
task.EffectiveUserId, task.TaskName, task.ItemId, task.ItemName,
|
||||||
|
@ -80,6 +80,7 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
AddTaskParams(taskId, task.Params);
|
AddTaskParams(taskId, task.Params);
|
||||||
|
|
||||||
DataProvider.AddBackgroundTaskStack(taskId);
|
DataProvider.AddBackgroundTaskStack(taskId);
|
||||||
|
return taskId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateTask(BackgroundTask task)
|
public static void UpdateTask(BackgroundTask task)
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
@ -46,7 +47,7 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
{
|
{
|
||||||
private static Hashtable eventHandlers = null;
|
private static Hashtable eventHandlers = null;
|
||||||
//using id instead of guid
|
//using id instead of guid
|
||||||
private static Dictionary<int, Thread> _taskThreadsDictionary = new Dictionary<int, Thread>();
|
private static ConcurrentDictionary<int, Thread> _taskThreadsDictionary = new ConcurrentDictionary<int, Thread>();
|
||||||
|
|
||||||
// purge timer, used for killing old tasks from the hash
|
// purge timer, used for killing old tasks from the hash
|
||||||
static Timer purgeTimer = new Timer(new TimerCallback(PurgeCompletedTasks),
|
static Timer purgeTimer = new Timer(new TimerCallback(PurgeCompletedTasks),
|
||||||
|
@ -162,11 +163,9 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
String itemNameStr = itemName != null
|
String itemNameStr = itemName != null
|
||||||
? itemName.ToString()
|
? itemName.ToString()
|
||||||
: String.Empty;
|
: String.Empty;
|
||||||
|
|
||||||
BackgroundTask task = new BackgroundTask(Guid, taskId, userId, effectiveUserId, source, taskName, itemNameStr,
|
BackgroundTask task = new BackgroundTask(Guid, taskId, userId, effectiveUserId, source, taskName, itemNameStr,
|
||||||
itemId, scheduleId, packageId, maximumExecutionTime, parameters);
|
itemId, scheduleId, packageId, maximumExecutionTime, parameters);
|
||||||
|
|
||||||
AddTaskThread(task, Thread.CurrentThread);
|
|
||||||
|
|
||||||
List<BackgroundTask> tasks = TaskController.GetTasks(Guid);
|
List<BackgroundTask> tasks = TaskController.GetTasks(Guid);
|
||||||
|
|
||||||
|
@ -188,7 +187,8 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
// call event handler
|
// call event handler
|
||||||
CallTaskEventHandler(task, false);
|
CallTaskEventHandler(task, false);
|
||||||
|
|
||||||
TaskController.AddTask(task);
|
int newTaskId = TaskController.AddTask(task);
|
||||||
|
AddTaskThread(newTaskId, Thread.CurrentThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteParameter(string parameterName, object parameterValue)
|
public static void WriteParameter(string parameterName, object parameterValue)
|
||||||
|
@ -551,12 +551,12 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
task.NotifyOnComplete = true;
|
task.NotifyOnComplete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void AddTaskThread(BackgroundTask task, Thread taskThread)
|
internal static void AddTaskThread(int taskId, Thread taskThread)
|
||||||
{
|
{
|
||||||
if (_taskThreadsDictionary.ContainsKey(task.Id))
|
if (_taskThreadsDictionary.ContainsKey(taskId))
|
||||||
_taskThreadsDictionary[task.Id] = taskThread;
|
_taskThreadsDictionary[taskId] = taskThread;
|
||||||
else
|
else
|
||||||
_taskThreadsDictionary.Add(task.Id, taskThread);
|
_taskThreadsDictionary.AddOrUpdate(taskId, taskThread, (key, oldValue) => taskThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StopTask(string taskId)
|
public static void StopTask(string taskId)
|
||||||
|
@ -579,8 +579,11 @@ namespace WebsitePanel.EnterpriseServer
|
||||||
{
|
{
|
||||||
if (_taskThreadsDictionary.ContainsKey(key))
|
if (_taskThreadsDictionary.ContainsKey(key))
|
||||||
{
|
{
|
||||||
_taskThreadsDictionary[key].Abort();
|
if (_taskThreadsDictionary[key] != null)
|
||||||
_taskThreadsDictionary.Remove(key);
|
if (_taskThreadsDictionary[key].IsAlive)
|
||||||
|
_taskThreadsDictionary[key].Abort();
|
||||||
|
Thread deleted;
|
||||||
|
_taskThreadsDictionary.TryRemove(key,out deleted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
<%@ Register Src="UserControls/Quota.ascx" TagName="Quota" TagPrefix="uc4" %>
|
<%@ Register Src="UserControls/Quota.ascx" TagName="Quota" TagPrefix="uc4" %>
|
||||||
<%@ Import Namespace="WebsitePanel.Portal" %>
|
<%@ Import Namespace="WebsitePanel.Portal" %>
|
||||||
|
|
||||||
|
<asp:Timer runat="server" Interval="5000" ID="tasksTimer" />
|
||||||
|
|
||||||
<div class="FormButtonsBar">
|
<div class="FormButtonsBar">
|
||||||
<div class="Left">
|
<div class="Left">
|
||||||
<asp:Button ID="btnAddItem" runat="server" meta:resourcekey="btnAddItem" Text="Add Scheduled Task" CssClass="Button3" OnClick="btnAddItem_Click" />
|
<asp:Button ID="btnAddItem" runat="server" meta:resourcekey="btnAddItem" Text="Add Scheduled Task" CssClass="Button3" OnClick="btnAddItem_Click" />
|
||||||
|
@ -15,6 +17,12 @@
|
||||||
<uc1:SearchBox ID="searchBox" runat="server" />
|
<uc1:SearchBox ID="searchBox" runat="server" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<asp:UpdatePanel runat="server" ID="schedulesUpdatePanel" UpdateMode="Conditional">
|
||||||
|
<Triggers>
|
||||||
|
<asp:AsyncPostBackTrigger ControlID="tasksTimer" EventName="Tick" />
|
||||||
|
</Triggers>
|
||||||
|
<ContentTemplate>
|
||||||
<asp:GridView id="gvSchedules" runat="server" AutoGenerateColumns="False"
|
<asp:GridView id="gvSchedules" runat="server" AutoGenerateColumns="False"
|
||||||
DataSourceID="odsSchedules" AllowPaging="True" AllowSorting="True" EmptyDataText="gvSchedules"
|
DataSourceID="odsSchedules" AllowPaging="True" AllowSorting="True" EmptyDataText="gvSchedules"
|
||||||
OnRowCommand="gvSchedules_RowCommand" CssSelectorClass="NormalGridView"
|
OnRowCommand="gvSchedules_RowCommand" CssSelectorClass="NormalGridView"
|
||||||
|
@ -86,4 +94,7 @@
|
||||||
<asp:ControlParameter ControlID="searchBox" Name="filterColumn" PropertyName="FilterColumn" />
|
<asp:ControlParameter ControlID="searchBox" Name="filterColumn" PropertyName="FilterColumn" />
|
||||||
<asp:ControlParameter ControlID="searchBox" Name="filterValue" PropertyName="FilterValue" />
|
<asp:ControlParameter ControlID="searchBox" Name="filterValue" PropertyName="FilterValue" />
|
||||||
</SelectParameters>
|
</SelectParameters>
|
||||||
</asp:ObjectDataSource>
|
</asp:ObjectDataSource>
|
||||||
|
|
||||||
|
</ContentTemplate>
|
||||||
|
</asp:UpdatePanel>
|
|
@ -1,31 +1,3 @@
|
||||||
// Copyright (c) 2012, Outercurve Foundation.
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
// are permitted provided that the following conditions are met:
|
|
||||||
//
|
|
||||||
// - Redistributions of source code must retain the above copyright notice, this
|
|
||||||
// list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
|
||||||
// and/or other materials provided with the distribution.
|
|
||||||
//
|
|
||||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from this
|
|
||||||
// software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// <auto-generated>
|
// <auto-generated>
|
||||||
// This code was generated by a tool.
|
// This code was generated by a tool.
|
||||||
|
@ -40,6 +12,15 @@ namespace WebsitePanel.Portal {
|
||||||
|
|
||||||
public partial class Schedules {
|
public partial class Schedules {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// tasksTimer control.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Auto-generated field.
|
||||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||||
|
/// </remarks>
|
||||||
|
protected global::System.Web.UI.Timer tasksTimer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// btnAddItem control.
|
/// btnAddItem control.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -67,6 +48,15 @@ namespace WebsitePanel.Portal {
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected global::WebsitePanel.Portal.SearchBox searchBox;
|
protected global::WebsitePanel.Portal.SearchBox searchBox;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// schedulesUpdatePanel control.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Auto-generated field.
|
||||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||||
|
/// </remarks>
|
||||||
|
protected global::System.Web.UI.UpdatePanel schedulesUpdatePanel;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// gvSchedules control.
|
/// gvSchedules control.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue