Merge branch 'master' of http://git.newlifex.com/NewLife/AntJob
This commit is contained in:
commit
7a123c2d3f
|
@ -1046,6 +1046,17 @@
|
|||
<td>最后一次时间</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>QuietTime</td>
|
||||
<td>免打扰</td>
|
||||
<td>String</td>
|
||||
<td>50</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>设置免打扰时间段,例如09:00-12:00,13:00-18:00</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Data</td>
|
||||
<td>附加数据</td>
|
||||
|
|
|
@ -355,5 +355,39 @@ public partial class Job : EntityBase<Job>
|
|||
Mode = Mode,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>检查是否免打扰模式</summary>
|
||||
/// <returns></returns>
|
||||
public Boolean CheckQuiet(DateTime time)
|
||||
{
|
||||
var qt = QuietTime;
|
||||
if (qt.IsNullOrEmpty()) return false;
|
||||
|
||||
foreach (var item in qt.Split(",", StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
var ss = item.Split("-");
|
||||
if (ss.Length != 2) continue;
|
||||
|
||||
if (TimeSpan.TryParse(ss[0], out var start) &&
|
||||
TimeSpan.TryParse(ss[1], out var end))
|
||||
{
|
||||
// 如果时间在免打扰时间段内,则返回true。需要判断time.TimeOfDay是否在start和end之间,注意跨天的情况
|
||||
if (start < end)
|
||||
{
|
||||
// 正常时间段,不跨天
|
||||
if (time.TimeOfDay >= start && time.TimeOfDay < end)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 跨天时间段
|
||||
if (time.TimeOfDay >= start || time.TimeOfDay < end)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
}
|
|
@ -285,6 +285,14 @@ public partial class Job
|
|||
[BindColumn("LastTime", "最后时间。最后一次时间", "")]
|
||||
public DateTime LastTime { get => _LastTime; set { if (OnPropertyChanging("LastTime", value)) { _LastTime = value; OnPropertyChanged("LastTime"); } } }
|
||||
|
||||
private String _QuietTime;
|
||||
/// <summary>免打扰。设置免打扰时间段,例如09:00-12:00,13:00-18:00</summary>
|
||||
[DisplayName("免打扰")]
|
||||
[Description("免打扰。设置免打扰时间段,例如09:00-12:00,13:00-18:00")]
|
||||
[DataObjectField(false, false, true, 50)]
|
||||
[BindColumn("QuietTime", "免打扰。设置免打扰时间段,例如09:00-12:00,13:00-18:00", "")]
|
||||
public String QuietTime { get => _QuietTime; set { if (OnPropertyChanging("QuietTime", value)) { _QuietTime = value; OnPropertyChanged("QuietTime"); } } }
|
||||
|
||||
private String _Data;
|
||||
/// <summary>附加数据。执行作业任务时附带的数据,可以是Json配置,也可以是Sql模板或C#模板</summary>
|
||||
[DisplayName("附加数据")]
|
||||
|
@ -414,6 +422,7 @@ public partial class Job
|
|||
"Speed" => _Speed,
|
||||
"LastStatus" => _LastStatus,
|
||||
"LastTime" => _LastTime,
|
||||
"QuietTime" => _QuietTime,
|
||||
"Data" => _Data,
|
||||
"CreateUserID" => _CreateUserID,
|
||||
"CreateUser" => _CreateUser,
|
||||
|
@ -461,6 +470,7 @@ public partial class Job
|
|||
case "Speed": _Speed = value.ToInt(); break;
|
||||
case "LastStatus": _LastStatus = (JobStatus)value.ToInt(); break;
|
||||
case "LastTime": _LastTime = value.ToDateTime(); break;
|
||||
case "QuietTime": _QuietTime = Convert.ToString(value); break;
|
||||
case "Data": _Data = Convert.ToString(value); break;
|
||||
case "CreateUserID": _CreateUserID = value.ToInt(); break;
|
||||
case "CreateUser": _CreateUser = Convert.ToString(value); break;
|
||||
|
@ -588,6 +598,9 @@ public partial class Job
|
|||
/// <summary>最后时间。最后一次时间</summary>
|
||||
public static readonly Field LastTime = FindByName("LastTime");
|
||||
|
||||
/// <summary>免打扰。设置免打扰时间段,例如09:00-12:00,13:00-18:00</summary>
|
||||
public static readonly Field QuietTime = FindByName("QuietTime");
|
||||
|
||||
/// <summary>附加数据。执行作业任务时附带的数据,可以是Json配置,也可以是Sql模板或C#模板</summary>
|
||||
public static readonly Field Data = FindByName("Data");
|
||||
|
||||
|
@ -717,6 +730,9 @@ public partial class Job
|
|||
/// <summary>最后时间。最后一次时间</summary>
|
||||
public const String LastTime = "LastTime";
|
||||
|
||||
/// <summary>免打扰。设置免打扰时间段,例如09:00-12:00,13:00-18:00</summary>
|
||||
public const String QuietTime = "QuietTime";
|
||||
|
||||
/// <summary>附加数据。执行作业任务时附带的数据,可以是Json配置,也可以是Sql模板或C#模板</summary>
|
||||
public const String Data = "Data";
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
<Column Name="Speed" DataType="Int32" Description="速度" Category="统计" />
|
||||
<Column Name="LastStatus" DataType="Int32" Description="最后状态。最后一次状态" Category="统计" Type="JobStatus" />
|
||||
<Column Name="LastTime" DataType="DateTime" Description="最后时间。最后一次时间" Category="统计" />
|
||||
<Column Name="QuietTime" DataType="String" Description="免打扰。设置免打扰时间段,该时间段内不生成作业任务,例如09:00-12:00,13:00-18:00" />
|
||||
<Column Name="Data" DataType="String" Length="-1" Description="附加数据。执行作业任务时附带的数据,可以是Json配置,也可以是Sql模板或C#模板" />
|
||||
<Column Name="CreateUserID" DataType="Int32" Description="创建人" Category="扩展" />
|
||||
<Column Name="CreateUser" DataType="String" Description="创建者" Category="扩展" />
|
||||
|
|
Binary file not shown.
|
@ -145,7 +145,9 @@ public class JobService(AppService appService, ICacheProvider cacheProvider, ITr
|
|||
app = App.FindByID(app.ID) ?? app;
|
||||
if (!app.Enable) return [];
|
||||
|
||||
// 作业是否启用,是否处于免打扰时间
|
||||
var job = app.Jobs.FirstOrDefault(e => e.Name == jobName);
|
||||
if (job != null && (!job.Enable || job.CheckQuiet(DateTime.Now))) return [];
|
||||
|
||||
// 全局锁,确保单个作业只有一个线程在分配作业
|
||||
using var ck = _cacheProvider.AcquireLock($"antjob:lock:{job.ID}", 15_000);
|
||||
|
|
|
@ -23,7 +23,7 @@ public class JobController : AntEntityController<Job>
|
|||
LogOnChange = true;
|
||||
|
||||
ListFields.RemoveField("ClassName", "Step", "Cron", "Topic", "MessageCount", "Time", "End");
|
||||
ListFields.RemoveField("Times", "Speed");
|
||||
ListFields.RemoveField("Times", "Speed", "QuietTime");
|
||||
ListFields.RemoveField("MaxError", "MaxRetry", "MaxTime", "MaxRetain", "MaxIdle", "ErrorDelay", "Deadline");
|
||||
ListFields.RemoveCreateField().RemoveUpdateField();
|
||||
ListFields.AddListField("UpdateTime");
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\AntJob.Data\AntJob.Data.csproj" />
|
||||
<ProjectReference Include="..\AntJob.Extensions\AntJob.Extensions.csproj" />
|
||||
<ProjectReference Include="..\AntJob\AntJob.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using AntJob.Data.Entity;
|
||||
using Xunit;
|
||||
|
||||
namespace AntTest;
|
||||
|
||||
public class JobTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("09:00-12:00", "2024-01-01 10:00", true)] // 区间内
|
||||
[InlineData("09:00-12:00", "2024-01-01 08:59", false)] // 区间外
|
||||
[InlineData("09:00-12:00", "2024-01-01 12:00", false)] // 上界不含
|
||||
public void CheckQuiet_SinglePeriod_SameDay(String quietTime, String time, Boolean expected)
|
||||
{
|
||||
var job = new Job { QuietTime = quietTime };
|
||||
var dt = DateTime.Parse(time);
|
||||
Assert.Equal(expected, job.CheckQuiet(dt));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("23:00-02:00", "2024-01-01 23:30", true)] // 跨天,前一天区间内
|
||||
[InlineData("23:00-02:00", "2024-01-02 01:30", true)] // 跨天,后一天区间内
|
||||
[InlineData("23:00-02:00", "2024-01-01 22:59", false)] // 区间外
|
||||
[InlineData("23:00-02:00", "2024-01-02 02:00", false)] // 上界不含
|
||||
public void CheckQuiet_SinglePeriod_CrossDay(String quietTime, String time, Boolean expected)
|
||||
{
|
||||
var job = new Job { QuietTime = quietTime };
|
||||
var dt = DateTime.Parse(time);
|
||||
Assert.Equal(expected, job.CheckQuiet(dt));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("09:00-12:00,13:00-18:00", "2024-01-01 10:00", true)] // 第一个区间内
|
||||
[InlineData("09:00-12:00,13:00-18:00", "2024-01-01 14:00", true)] // 第二个区间内
|
||||
[InlineData("09:00-12:00,13:00-18:00", "2024-01-01 12:30", false)] // 两区间外
|
||||
public void CheckQuiet_MultiPeriod_SameDay(String quietTime, String time, Boolean expected)
|
||||
{
|
||||
var job = new Job { QuietTime = quietTime };
|
||||
var dt = DateTime.Parse(time);
|
||||
Assert.Equal(expected, job.CheckQuiet(dt));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("23:00-02:00,09:00-12:00", "2024-01-01 23:30", true)] // 跨天区间内
|
||||
[InlineData("23:00-02:00,09:00-12:00", "2024-01-02 01:30", true)] // 跨天区间内
|
||||
[InlineData("23:00-02:00,09:00-12:00", "2024-01-01 10:00", true)] // 当天区间内
|
||||
[InlineData("23:00-02:00,09:00-12:00", "2024-01-01 08:00", false)] // 所有区间外
|
||||
public void CheckQuiet_MultiPeriod_CrossDay(String quietTime, String time, Boolean expected)
|
||||
{
|
||||
var job = new Job { QuietTime = quietTime };
|
||||
var dt = DateTime.Parse(time);
|
||||
Assert.Equal(expected, job.CheckQuiet(dt));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("23:00-02:00", "2024-01-01 01:00", true)] // 跨天,凌晨,属于前一天的免打扰
|
||||
[InlineData("23:00-02:00", "2024-01-02 01:00", true)] // 跨天,凌晨,属于前一天的免打扰
|
||||
[InlineData("23:00-02:00", "2024-01-01 02:00", false)] // 上界不含
|
||||
public void CheckQuiet_CrossDay_EdgeCases(String quietTime, String time, Boolean expected)
|
||||
{
|
||||
var job = new Job { QuietTime = quietTime };
|
||||
var dt = DateTime.Parse(time);
|
||||
Assert.Equal(expected, job.CheckQuiet(dt));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue