using FluentScheduler;
using Newtonsoft.Json;
using Rhea.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tiger.IBusiness;
using Tiger.Model;
using Tiger.Model.Minsun;
namespace Tiger.Business
{
///
///
///
public class InterfaceServiceNew: IInterfaceService
{
#region Sundial计划调度 旧版本使用
public Sundial.ISchedulerFactory _schedulerFactory { get; set; }
///
/// 设置计划任务工厂类
///
///
public void SetSchedulerFactory(Sundial.ISchedulerFactory schedulerFactory)
{
_schedulerFactory = schedulerFactory;
}
///
/// 根据实体类名及作业名称添加作业
///
///
///
///
public ApiAction AddJob(TJob newEntity, TskJobParam jobParam) where TJob : class, Sundial.IJob
{
ApiAction apiAction = new();
Sundial.TriggerBuilder triggerBuilder = Sundial.Triggers.Period(jobParam.Period*60*1000).LoadFrom(new
{
TriggerId = jobParam.JobName + "_trigger1",
});
_schedulerFactory.AddJob(jobParam.JobName, triggerBuilder);
var trigger = GetJob(jobParam.JobName).GetTrigger($"{jobParam.JobName}_trigger1");
TSK_JOB entity = ReturnDetail(jobParam.JobName);
entity.Remark = jobParam.Remark;
entity.JobType = typeof(TJob).Name;
entity.JobName = jobParam.JobName;
entity.TriggersWithGhost = new List { JsonConvert.DeserializeObject(JsonConvert.SerializeObject(trigger)) };
entity.Triggers[0].Args = jobParam.Period.ToString();
apiAction = SaveJob(entity);
apiAction.Data = entity;
return apiAction;
}
///
/// 根据作业名称添加作业
///
///
///
///
public ApiAction AddJob(string jobname, params Sundial.TriggerBuilder[] triggerBuilders) where TJob : class, Sundial.IJob
{
ApiAction apiAction = new();
triggerBuilders[0].LoadFrom(new
{
TriggerId = jobname + "_trigger1",
});
_schedulerFactory.AddJob(jobname, triggerBuilders);
var trigger = GetJob(jobname).GetTrigger($"{jobname}_trigger1");
TSK_JOB entity = ReturnDetail(jobname);
entity.TriggersWithGhost = new List { JsonConvert.DeserializeObject(JsonConvert.SerializeObject(trigger)) };
apiAction = SaveJob(entity);
apiAction.Data = entity;
return apiAction;
}
///
/// 更新作业
///
///
///
public ApiAction UpdateJob(TSK_JOB job)
{
ApiAction apiAction = new ApiAction();
Sundial.IScheduler scheduler = GetJob(job.JobName);
var trigger = scheduler.GetTrigger($"{job.JobName}_trigger1");
if (trigger.Status == Sundial.TriggerStatus.Running)
{
apiAction.IsSuccessed = false;
apiAction.Message = $"作业[{job.JobName}]正在运行不能编辑";
}
var triggerEntity = Biz.Db.Queryable().Where(x => x.JobId == job.ID).First();
if (triggerEntity != null)
{
triggerEntity.Status = (int)trigger.Status;
triggerEntity.Args = job.uPeriod.ToString();
}
var db = Business.Biz.Db;
//保存到数据库
var dbTran = db.UseTran(() =>
{
if (job != null)
{
db.Updateable(job, "system").ExecuteCommand();
}
if (triggerEntity != null)
{
db.Updateable(triggerEntity, "system").ExecuteCommand();
}
});
if (!dbTran.IsSuccess)
{
apiAction.GetResponse().CatchExceptionWithLog(dbTran.ErrorException, $"作业保存到数据库异常");
}
//更新触发器周期
scheduler.UpdateTrigger($"{job.JobName}_trigger1", triggerBuilder =>
{
triggerBuilder.SetArgs(job.uPeriod * 60 * 1000);
}); ;
return apiAction;
}
private TSK_JOB ReturnDetail(string jobname)
{
var jobDetail = GetJob(jobname).GetJobDetail();
return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(jobDetail));
}
///
/// 启动所有作业
///
public void StartAllJob()
{
_schedulerFactory.StartAll();
}
///
/// 启动单个作业
///
///
public void StartJob(string jobname)
{
// 带返回值
Sundial.IScheduler scheduler;
var scheduleResult = _schedulerFactory.TryRunJob(jobname, out scheduler);
}
///
/// 获取单个作业
///
///
///
public Sundial.IScheduler GetJob(string jobname)
{
Sundial.IScheduler scheduler;
var scheduleResult = _schedulerFactory.TryGetJob(jobname, out scheduler);
return scheduler;
}
///
/// 获取所有作业
///
///
public List GetJobs()
{
return _schedulerFactory.GetJobs().ToList();
}
///
/// 暂停作业
///
///
public void PauseJob(string jobname)
{
var scheduler = GetJob(jobname);
if (scheduler != null)
{
scheduler.Pause();
}
}
///
/// 删除作业
///
///
public void RemoveJob(string jobname)
{
var scheduler = GetJob(jobname);
if (scheduler != null)
{
scheduler.Remove();
}
}
///
/// 从数据库加载作业
///
public void AddJobFromDB()
{
try
{
var jobs = Biz.Db.Queryable().IncludesAllFirstLayer().ToList();
foreach (var job in jobs)
{
Type type = Type.GetType($"{job.AssemblyName}.{job.JobType},{job.AssemblyName}", throwOnError: true);
_schedulerFactory.AddJob(type, job.JobName, Sundial.Triggers.Period(Convert.ToInt32(job.Triggers?[0].Args ?? "3") * 60 * 1000));
if (job.Triggers[0]?.Status == 3)
{
Work.DoAsync(() =>
{
Thread.Sleep(2000);
PauseJob(job.JobName);
});
}
}
}
catch (System.Exception ex)
{
Logger.Console.Fatal(ex, "Add Job From DB Exception");
}
}
///
/// 作业保存到数据库
///
///
private ApiAction SaveJob(TSK_JOB entity)
{
var action = new ApiAction();
entity.ID = Guid.NewGuid().ToString("N");
entity.Triggers[0].JobId = entity.ID;
if (Biz.Db.Queryable().Where(x => x.JobName == entity.JobName && x.JobType == entity.JobType && x.AssemblyName == entity.AssemblyName).Any())
{
action.IsSuccessed = false;
action.Message = $"作业已经存在,不能保存数据";
return action;
}
var db = Business.Biz.Db;
//保存到数据库
var dbTran = db.UseTran(() =>
{
if (entity != null)
{
db.Insertable(entity, "system").ExecuteCommand();
}
if (entity.Triggers.Any())
{
db.Insertable(entity.Triggers, "system").ExecuteCommand();
}
});
if (!dbTran.IsSuccess)
{
action.GetResponse().CatchExceptionWithLog(dbTran.ErrorException, $"作业保存到数据库异常");
}
return action;
}
#endregion
#region 新版本计划调度 FluentScheduler
///
/// 初始化计划调度
///
public void JobInitialize()
{
JobManager.Initialize();
JobManager.JobException += info => Logger.Scheduler.Error("An error just happened with a scheduled job: " + info.Exception);
JobManager.JobStart += info => Logger.Scheduler.Info($"{info.Name}: started");
JobManager.JobEnd += info => Logger.Scheduler.Info($"{info.Name}: ended ({info.Duration})");
}
///
/// 添加工作任务
///
///
///
///
///
public ApiAction AddJob(TJob newEntity, FluentJobParam jobParam) where TJob : class, IJob
{
ApiAction apiAction = new();
try
{
JobManager.AddJob((s) => s.ToRunEvery(5).Seconds());
//Sundial.TriggerBuilder triggerBuilder = Sundial.Triggers.Period(jobParam.Period * 60 * 1000).LoadFrom(new
//{
// TriggerId = jobParam.JobName + "_trigger1",
//});
//_schedulerFactory.AddJob(jobParam.JobName, triggerBuilder);
//var trigger = GetJob(jobParam.JobName).GetTrigger($"{jobParam.JobName}_trigger1");
//TSK_JOB entity = ReturnDetail(jobParam.JobName);
//entity.Remark = jobParam.Remark;
//entity.JobType = typeof(TJob).Name;
//entity.JobName = jobParam.JobName;
//entity.TriggersWithGhost = new List { JsonConvert.DeserializeObject(JsonConvert.SerializeObject(trigger)) };
//entity.Triggers[0].Args = jobParam.Period.ToString();
//apiAction = SaveJob(entity);
//apiAction.Data = entity;
}
catch (System.Exception ex)
{
Logger.Console.Fatal(ex, "Add Job From DB Exception");
}
return apiAction;
}
///
/// 从数据库批量添加任务
///
public void AddJobsFromDB()
{
try
{
var jobs = Biz.Db.Queryable().IncludesAllFirstLayer().ToList();
// 声明一个Registry类
var registry = new Registry();
foreach (var job in jobs)
{
Type type = Type.GetType($"{job.AssemblyName}.{job.JobType},{job.AssemblyName}", throwOnError: true);
dynamic _type = Activator.CreateInstance(type);
TrigArgs args = JsonConvert.DeserializeObject(job.Triggers[0].Args);
Schedule schedule = Schedule(_type,job.JobName, registry);
SpecificTimeUnit specificTimeUnit = null;
TimeUnit timeUnit = null;
if (args.NonReentrant == "Y") { schedule = schedule.NonReentrant(); }
if (args.ToRunNow == "Y") { specificTimeUnit = schedule.ToRunNow(); }
if (args.ToRunOnceIn > 0) { timeUnit = schedule.ToRunOnceIn(args.ToRunOnceIn); }
else if (args.ToRunEvery >= 0) { timeUnit = schedule.ToRunEvery(args.ToRunEvery); }
//按时间类型来运行
switch (args.Type)
{
case TrigArgs.EveryType.Milliseconds:
timeUnit.Milliseconds();
break;
case TrigArgs.EveryType.Seconds:
timeUnit.Seconds();
break;
case TrigArgs.EveryType.Minutes:
timeUnit.Minutes();
break;
case TrigArgs.EveryType.Hours:
if (args.Minutes > 0)
{
timeUnit.Hours().At(args.Minutes);
}
else
{
timeUnit.Hours();
}
break;
case TrigArgs.EveryType.Days:
if (args.Hours>0 && args.Minutes > 0 )
{
timeUnit.Days().At(args.Hours, args.Minutes);
}
else
{
timeUnit.Days();
}
break;
case TrigArgs.EveryType.Weeks:
if (args.Hours > 0 && args.Minutes > 0)
{
timeUnit.Weeks().At(args.Hours, args.Minutes);
}
else
{
timeUnit.Weeks();
}
break;
case TrigArgs.EveryType.Weekdays:
if (args.Hours > 0 && args.Minutes > 0)
{
timeUnit.Weekdays().At(args.Hours, args.Minutes);
}
else
{
timeUnit.Weekdays();
}
break;
}
}
}
catch (System.Exception ex)
{
Logger.Console.Fatal(ex, "Add Job From DB Exception");
}
}
///
/// 根据实体名注册计划
///
///
///
///
///
///
private Schedule Schedule(TJob entity, string JobName, Registry registry) where TJob : class, IJob
{
return registry.Schedule().WithName(JobName);
}
///
/// 停止服务
///
public void Stop()
{
JobManager.Stop();
}
///
/// 在任务完成后等待或者停止
///
public void StopAndBlock() {
JobManager.StopAndBlock();
}
#endregion
}
}