From e12b22590df5c6194ca7e2927a7cff6213ac1567 Mon Sep 17 00:00:00 2001 From: ningshuxia <ningshuxia0927@outlook.com> Date: 星期五, 19 八月 2022 13:50:04 +0800 Subject: [PATCH] Merge branch 'master' of http://47.103.154.90:83/r/IStation/Service.V4.1 --- Server/IStation.Server.Job/helpers/ConfigHelper.cs | 29 + Server/IStation.Server.Job/custom_cron/service/CustomCronServiceJob.cs | 115 ++++ Server/IStation.Server.Job/helpers/JobHelper.cs | 37 + TopShelf/IStation.TopShelf.Job/Program.cs | 16 Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJob.cs | 112 ++++ Settings/IStation.Settings/paras_settings.json | 4 Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJobHelper.cs | 78 +++ TopShelf/IStation.TopShelf.Job/Service.cs | 40 + Server/IStation.Server.Job/custom_cron/service/CustomCronServiceJobHelper.cs | 70 ++ IStation.Server.Job.sln | 13 Server/IStation.Server.Job/interface/IJobHelper.cs | 27 + TopShelf/IStation.TopShelf.Job/IStation.TopShelf.Job.csproj | 15 Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJobNameHelper.cs | 48 ++ Server/IStation.Server.Job/custom_real/service/CustomRealServiceJob.cs | 115 ++++ Server/IStation.Server.Job/Program.cs | 6 Settings/IStation.Settings/models/job/Paras_Job.cs | 5 Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJob.cs | 112 ++++ Server/IStation.Server.Job/custom_real/job/CustomRealJobNameHelper.cs | 46 + Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJobHelper.cs | 78 +++ Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJobNameHelper.cs | 48 ++ Server/IStation.Server.Job/custom_real/job/CustomRealJob.cs | 50 ++ /dev/null | 12 Server/IStation.Server.Job/custom_real/service/CustomRealServiceJobHelper.cs | 70 ++ Server/IStation.Server.Job/IStation.Server.Job.csproj | 6 Settings/IStation.Settings/models/job/Paras_Job_Execution.cs | 26 + Server/IStation.Server.Job/custom_real/job/CustomRealJobHelper.cs | 75 +++ Server/IStation.Server.Job/custom_cron/cron/CustomCronJobHelper.cs | 74 +++ Server/IStation.Server.Job/custom_cron/cron/CustomCronJobNameHelper.cs | 46 + Server/IStation.Server.Job/custom_cron/cron/CustomCronJob.cs | 50 ++ 29 files changed, 1,408 insertions(+), 15 deletions(-) diff --git a/IStation.Server.Job.sln b/IStation.Server.Job.sln index ed286b8..363e19a 100644 --- a/IStation.Server.Job.sln +++ b/IStation.Server.Job.sln @@ -65,6 +65,10 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IStation.MemoryCache", "Component\IStation.MemoryCache\IStation.MemoryCache.csproj", "{57FE2AAD-6C18-4E86-A103-1865AF97F04A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IStation.TopShelf.Job", "TopShelf\IStation.TopShelf.Job\IStation.TopShelf.Job.csproj", "{417AD452-1359-4C86-B81A-E958BABC7879}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IStation.TopShelf", "Component\IStation.TopShelf\IStation.TopShelf.csproj", "{C2EC86B3-85F5-4CC6-800B-D7215F05372C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -159,6 +163,14 @@ {57FE2AAD-6C18-4E86-A103-1865AF97F04A}.Debug|Any CPU.Build.0 = Debug|Any CPU {57FE2AAD-6C18-4E86-A103-1865AF97F04A}.Release|Any CPU.ActiveCfg = Release|Any CPU {57FE2AAD-6C18-4E86-A103-1865AF97F04A}.Release|Any CPU.Build.0 = Release|Any CPU + {417AD452-1359-4C86-B81A-E958BABC7879}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {417AD452-1359-4C86-B81A-E958BABC7879}.Debug|Any CPU.Build.0 = Debug|Any CPU + {417AD452-1359-4C86-B81A-E958BABC7879}.Release|Any CPU.ActiveCfg = Release|Any CPU + {417AD452-1359-4C86-B81A-E958BABC7879}.Release|Any CPU.Build.0 = Release|Any CPU + {C2EC86B3-85F5-4CC6-800B-D7215F05372C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2EC86B3-85F5-4CC6-800B-D7215F05372C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2EC86B3-85F5-4CC6-800B-D7215F05372C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2EC86B3-85F5-4CC6-800B-D7215F05372C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -185,6 +197,7 @@ {521CC846-751A-4F9A-896B-E20011DEFF63} = {B2A37802-88E8-4029-8256-343C5AF13D18} {BA870208-76FA-471A-861A-328ED902069C} = {2235DB47-DB5E-4072-B147-0F2ECBD1CEC0} {57FE2AAD-6C18-4E86-A103-1865AF97F04A} = {CEA4D501-B221-4F3C-9277-A40D4524FFE3} + {C2EC86B3-85F5-4CC6-800B-D7215F05372C} = {CEA4D501-B221-4F3C-9277-A40D4524FFE3} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E02989A8-9B6F-43E5-AACA-790328215089} diff --git a/Server/IStation.Server.Job/IStation.Server.Job.csproj b/Server/IStation.Server.Job/IStation.Server.Job.csproj index d49c1ff..2f06a93 100644 --- a/Server/IStation.Server.Job/IStation.Server.Job.csproj +++ b/Server/IStation.Server.Job/IStation.Server.Job.csproj @@ -9,4 +9,10 @@ <RootNamespace>IStation.Server</RootNamespace> </PropertyGroup> + <ItemGroup> + <ProjectReference Include="..\..\Component\IStation.Quartz\IStation.Quartz.csproj" /> + <ProjectReference Include="..\..\Job\IStation.JobFactory\IStation.JobFactory.csproj" /> + <ProjectReference Include="..\..\Service\IStation.Service.Job\IStation.Service.Job.csproj" /> + </ItemGroup> + </Project> diff --git a/Server/IStation.Server.Job/Program.cs b/Server/IStation.Server.Job/Program.cs index 64e3d97..2af805b 100644 --- a/Server/IStation.Server.Job/Program.cs +++ b/Server/IStation.Server.Job/Program.cs @@ -1,14 +1,14 @@ 锘�// See https://aka.ms/new-console-template for more information -using IStation.Server; using IStation; +using IStation.Server; LogHelper.Info("鏈嶅姟姝e湪鍚姩..."); var jobHelper = new JobHelper(); -jobHelper.Start(); +jobHelper.StartJob(); AppDomain.CurrentDomain.ProcessExit += (sender, e) => { LogHelper.Info("鏈嶅姟姝e湪鍏抽棴..."); - jobHelper.Cancel(); + jobHelper.CancelJob(); LogHelper.Info("鏈嶅姟鍏抽棴锛�"); }; LogHelper.Info("鏈嶅姟鍚姩鎴愬姛锛�"); diff --git a/Server/IStation.Server.Job/custom_cron/cron/CustomCronJob.cs b/Server/IStation.Server.Job/custom_cron/cron/CustomCronJob.cs new file mode 100644 index 0000000..f0379fa --- /dev/null +++ b/Server/IStation.Server.Job/custom_cron/cron/CustomCronJob.cs @@ -0,0 +1,50 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夎鍒掍换鍔� + /// </summary> + public class CustomCronJob : Quartz.IJob + { + internal const string Instance = "Instance"; + + /// <summary> + /// + /// </summary> + public Task Execute(IJobExecutionContext context) + { + return Task.Run(() => + { + try + { + var dataMap = context.MergedJobDataMap; + var jobModel = (Model.CustomCronJob)dataMap[Instance]; + if (jobModel == null) + return; + var jobExecuter = JobFactory.CreateJob(jobModel.Execution); + if (jobExecuter == null) + { + LogHelper.Error($"鑷畾涔夎鍒掍换鍔�,ID:{jobModel.ID},NO:{jobModel.NO},Name:{jobModel.Name},Execution:{jobModel.Execution},鍒涘缓浠诲姟鎵ц瀵硅薄澶辫触锛�"); + return; + } + jobExecuter.Execute(); + } + catch (Exception ex) + { + LogHelper.Error("鑷畾涔夎鍒掍换鍔★紝鎵ц鍑洪敊", ex); + var e = new JobExecutionException(ex); + throw e; + } + + }); + + + } + } +} diff --git a/Server/IStation.Server.Job/custom_cron/cron/CustomCronJobHelper.cs b/Server/IStation.Server.Job/custom_cron/cron/CustomCronJobHelper.cs new file mode 100644 index 0000000..c353e4a --- /dev/null +++ b/Server/IStation.Server.Job/custom_cron/cron/CustomCronJobHelper.cs @@ -0,0 +1,74 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夎鍒掍换鍔¤緟鍔╃被 + /// </summary> + public class CustomCronJobHelper + { + private IScheduler _sched;//璋冨害鍣� + + /// <summary> + /// 瀹炰緥 + /// </summary> + public Model.CustomCronJob Instance { get; private set; } + + /// <summary> + /// 寮�濮嬩换鍔� + /// </summary> + public async Task StartJob(Model.CustomCronJob instance) + { + if (_sched != null) + return; + this.Instance = instance ?? throw new ArgumentNullException(); + var jobName = CustomCronJobNameHelper.GetJobName(instance); + var jobGroupName = CustomCronJobNameHelper.GetJobGroupName(instance); + var triggerName = CustomCronJobNameHelper.GetTriggerName(instance); + + // 1.鍒涘缓scheduler鐨勫紩鐢� + var fac = new Quartz.Impl.StdSchedulerFactory(); + _sched = await fac.GetScheduler(); + + //2.鍚姩 scheduler + await _sched.Start(); + + //3.鍒涘缓浠诲姟 + var job = JobBuilder.Create<CustomCronJob>() + .WithIdentity(jobName, jobGroupName) + .Build(); + job.JobDataMap.Put(CustomRealJob.Instance, instance); + + //4.鍒涘缓Trigger + var trigger = TriggerBuilder.Create() + .WithIdentity(triggerName, jobGroupName) + .WithCronSchedule(instance.Expression) + .Build(); + + //5.鍔犲叆璋冨害绠$悊鍣� + await _sched.ScheduleJob(job, trigger); + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + public async Task CancelJob() + { + if (_sched == null) + return; + var jobGroupName = CustomCronJobNameHelper.GetJobGroupName(this.Instance); + var triggerName = CustomCronJobNameHelper.GetTriggerName(this.Instance); + var triggerKey = new TriggerKey(triggerName, jobGroupName); + if (await _sched.CheckExists(triggerKey)) + { + await _sched.UnscheduleJob(triggerKey); + } + } + + } +} diff --git a/Server/IStation.Server.Job/custom_cron/cron/CustomCronJobNameHelper.cs b/Server/IStation.Server.Job/custom_cron/cron/CustomCronJobNameHelper.cs new file mode 100644 index 0000000..eeb232b --- /dev/null +++ b/Server/IStation.Server.Job/custom_cron/cron/CustomCronJobNameHelper.cs @@ -0,0 +1,46 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夎鍒掍换鍔″悕绉拌緟鍔╃被 + /// </summary> + public class CustomCronJobNameHelper + { + private const string _jobNameHeader = "CustomCronJob"; + private const string _jobGroupHeader = "CustomCronJobGroup"; + private const string _triggerNameHeader = "CustomCronJobTrigger"; + + /// <summary> + /// 鑾峰彇浠诲姟鍚嶇О + /// </summary> + public static string GetJobName(Model.CustomCronJob rhs) + { + var name = string.Format("{0}_{1}", _jobNameHeader, rhs.ID); + return name; + } + + /// <summary> + /// 鑾峰彇浠诲姟缁勫悕绉� + /// </summary> + public static string GetJobGroupName(Model.CustomCronJob rhs) + { + var name = string.Format("{0}_{1}", _jobGroupHeader, rhs.ID); + return name; + } + + /// <summary> + /// 鑾峰彇瑙﹀彂鍣ㄥ悕绉� + /// </summary> + public static string GetTriggerName(Model.CustomCronJob rhs) + { + var name = string.Format("{0}_{1}", _triggerNameHeader, rhs.ID); + return name; + } + + } +} diff --git a/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJob.cs b/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJob.cs new file mode 100644 index 0000000..ebd87f9 --- /dev/null +++ b/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJob.cs @@ -0,0 +1,112 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夎鍒掗噸澶嶄换鍔� + /// </summary> + public class CustomCronRepeatJob : Quartz.IJob + { + //鑷畾涔夎鍒掍换鍔″瓧鍏� + private static Dictionary<long,CustomCronJobHelper> _dict=new Dictionary<long, CustomCronJobHelper>(); + + /// <summary> + /// 浠诲姟id + /// </summary> + public long JobID { get; set; } + + /// <summary> + /// + /// </summary> + public Task Execute(IJobExecutionContext context) + { + return Task.Run(async () => + { + try + { + //鑾峰彇浠诲姟 + var model = new Service.CustomCronJob().GetByID(JobID); + + //鑾峰彇浠诲姟澶辫触鍚庯紝鍋滄浠诲姟骞剁Щ闄や换鍔¤緟鍔╃被 + if (model == null) + { + if (_dict.ContainsKey(JobID)) + { + await _dict[JobID].CancelJob(); + _dict.Remove(JobID); + } + return; + } + + //灏氭湭鍒涘缓璁″垝浠诲姟鏃讹紝鍒涘缓璁″垝浠诲姟杈呭姪绫� + if (!_dict.ContainsKey(JobID)) + { + var jobHelper = new CustomCronJobHelper(); + await jobHelper.StartJob(model); + _dict.Add(JobID, jobHelper); + return; + } + + //浠诲姟宸插瓨鍦紝妫�鏌ヤ换鍔℃墽琛岄棿闅旀槸鍚﹀彂鐢熷彉鍖栵紝鑻ュ彂鐢熷彉鍖栵紝閲嶇疆浠诲姟 + if (_dict[JobID].Instance.Expression != model.Expression) + { + await _dict[JobID].CancelJob(); + var jobHelper = new CustomCronJobHelper(); + await jobHelper.StartJob(model); + _dict[JobID] = jobHelper; + } + + } + catch (Exception ex) + { + LogHelper.Error("鑷畾涔夎鍒掗噸澶嶄换鍔★紝鎵ц鍑洪敊", ex); + var e = new JobExecutionException(ex); + throw e; + } + }); + + + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + /// <returns></returns> + public async Task CancelJob() + { + await CancelJob(JobID); + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + /// <param name="jobId">浠诲姟id</param> + public static async Task CancelJob(long jobId) + { + if (_dict.ContainsKey(jobId)) + { + await _dict[jobId].CancelJob(); + _dict.Remove(jobId); + } + + } + + /// <summary> + /// 鍙栦笅浠诲姟 + /// </summary> + public static async Task CancelJobs() + { + foreach (var key in _dict.Keys) + { + await CancelJob(key); + } + } + + } + +} diff --git a/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJobHelper.cs b/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJobHelper.cs new file mode 100644 index 0000000..049d60d --- /dev/null +++ b/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJobHelper.cs @@ -0,0 +1,78 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃堕噸澶嶄换鍔¤緟鍔╃被 + /// </summary> + public class CustomCronRepeatJobHelper + { + private IScheduler _sched;//璋冨害鍣� + + /// <summary> + /// 瀹炰緥 + /// </summary> + public Model.CustomCronJob Instance { get; private set; } + + /// <summary> + /// 寮�濮嬩换鍔� + /// </summary> + public async Task StartJob(Model.CustomCronJob instance) + { + if (_sched != null) + return; + this.Instance = instance ?? throw new ArgumentNullException(); + var jobName = CustomCronRepeatJobNameHelper.GetJobName(instance); + var jobGroupName = CustomCronRepeatJobNameHelper.GetJobGroupName(instance); + var triggerName = CustomCronRepeatJobNameHelper.GetTriggerName(instance); + + // 1.鍒涘缓scheduler鐨勫紩鐢� + var fac = new Quartz.Impl.StdSchedulerFactory(); + _sched = await fac.GetScheduler(); + + //2.鍚姩 scheduler + await _sched.Start(); + + //3.鍒涘缓浠诲姟 + var job = JobBuilder.Create<CustomCronRepeatJob>() + .WithIdentity(jobName, jobGroupName) + .UsingJobData("JobID", instance.ID) + .Build(); + + //4.鍒涘缓Trigger + var trigger = TriggerBuilder.Create() + .WithIdentity(triggerName, jobGroupName) + .WithSimpleSchedule(x => x.WithIntervalInMinutes(instance.Repeat) + .RepeatForever().WithMisfireHandlingInstructionNextWithRemainingCount()) + .Build(); + + //5.鍔犲叆璋冨害绠$悊鍣� + await _sched.ScheduleJob(job, trigger); + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + public async Task CancelJob() + { + if (_sched == null) + return; + var jobGroupName = CustomCronRepeatJobNameHelper.GetJobGroupName(this.Instance); + var triggerName = CustomCronRepeatJobNameHelper.GetTriggerName(this.Instance); + var triggerKey = new TriggerKey(triggerName, jobGroupName); + if (await _sched.CheckExists(triggerKey)) + { + await _sched.UnscheduleJob(triggerKey); + } + await CustomCronRepeatJob.CancelJob(this.Instance.ID); + } + + + } + +} diff --git a/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJobNameHelper.cs b/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJobNameHelper.cs new file mode 100644 index 0000000..a88e141 --- /dev/null +++ b/Server/IStation.Server.Job/custom_cron/repeat/CustomCronRepeatJobNameHelper.cs @@ -0,0 +1,48 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夎鍒掗噸澶嶄换鍔″悕绉拌緟鍔╃被 + /// </summary> + public class CustomCronRepeatJobNameHelper + { + private const string _jobNameHeader = "CustomCronRepeatJob"; + private const string _jobGroupHeader = "CustomCronRepeatJobGroup"; + private const string _triggerNameHeader = "CustomCronRepeatJobTrigger"; + + /// <summary> + /// 鑾峰彇浠诲姟鍚嶇О + /// </summary> + public static string GetJobName(Model.CustomCronJob rhs) + { + var name = string.Format("{0}_{1}", _jobNameHeader, rhs.ID); + return name; + } + + /// <summary> + /// 鑾峰彇浠诲姟缁勫悕绉� + /// </summary> + public static string GetJobGroupName(Model.CustomCronJob rhs) + { + var name = string.Format("{0}_{1}", _jobGroupHeader, rhs.ID); + return name; + } + + /// <summary> + /// 鑾峰彇瑙﹀彂鍣ㄥ悕绉� + /// </summary> + public static string GetTriggerName(Model.CustomCronJob rhs) + { + var name = string.Format("{0}_{1}", _triggerNameHeader, rhs.ID); + return name; + } + + + + } +} diff --git a/Server/IStation.Server.Job/custom_cron/service/CustomCronServiceJob.cs b/Server/IStation.Server.Job/custom_cron/service/CustomCronServiceJob.cs new file mode 100644 index 0000000..efd1000 --- /dev/null +++ b/Server/IStation.Server.Job/custom_cron/service/CustomCronServiceJob.cs @@ -0,0 +1,115 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夎鍒掓湇鍔′换鍔� + /// </summary> + public class CustomCronServiceJob : Quartz.IJob + { + private static List<CustomCronRepeatJobHelper> _jobHelpers = new List<CustomCronRepeatJobHelper>(); + + /// <summary> + /// + /// </summary> + public Task Execute(IJobExecutionContext context) + { + return Task.Run(async () => + { + try + { + #region 鍔犺浇鎵�鏈変换鍔� + + var jobList = new Service.CustomCronJob().GetAll(); + if (jobList == null || jobList.Count < 1) + { + LogHelper.Info("鑷畾涔夎鍒掓湇鍔′换鍔′腑锛屾湭妫�绱㈠埌鑷畾涔夎鍒掍换鍔′俊鎭�"); + CancelJobs(); + return; + } + jobList = jobList.Where(x => x.UseStatus == Model.eUseStatus.Enable).ToList(); + if (jobList.Count < 1) + { + LogHelper.Info("鑷畾涔夎鍒掓湇鍔′换鍔′腑锛屾湭妫�绱㈠埌鏈夋晥鑷畾涔夎鍒掍换鍔′俊鎭�"); + CancelJobs(); + return; + } + + #endregion + + #region 寮�鍚换鍔� + + foreach (var job in jobList) + { + var jobHelper = _jobHelpers.Find(t => t.Instance.ID == job.ID); + if (jobHelper == null) + { + jobHelper = new CustomCronRepeatJobHelper(); + await jobHelper.StartJob(job); + _jobHelpers.Add(jobHelper); + LogHelper.Info($"鑷畾涔夎鍒掓湇鍔′换鍔′腑锛欼D:{job.ID},NO:{job.NO},Name:{job.Name} 鐨勪换鍔″紑鍚紒"); + } + } + + #endregion + + #region 鍏抽棴浠诲姟 + + foreach (var jobHelper in _jobHelpers.ToList()) + { + var job = jobList.Find(t => t.ID == jobHelper.Instance.ID); + if (job == null) + { + await jobHelper.CancelJob(); + _jobHelpers.Remove(jobHelper); + LogHelper.Info($"鑷畾涔夎鍒掓湇鍔′换鍔′腑锛欼D:{job.ID},NO:{job.NO},Name:{job.Name} 鐨勪换鍔″叧闂紒"); + continue; + } + + if (job.Repeat != jobHelper.Instance.Repeat) + { + await jobHelper.CancelJob(); + _jobHelpers.Remove(jobHelper); + var rJobHelper = new CustomCronRepeatJobHelper(); + await rJobHelper.StartJob(job); + _jobHelpers.Add(rJobHelper); + } + } + + #endregion + + LogHelper.Info($"鑷畾涔夎鍒掓湇鍔′换鍔′腑锛屽紑鍚换鍔℃暟閲忎负{_jobHelpers.Count}!"); + + } + catch (Exception ex) + { + LogHelper.Error("鑷畾涔夎鍒掓湇鍔′换鍔′腑锛屾墽琛屽嚭閿�", ex); + var e = new JobExecutionException(ex); + throw e; + } + }); + + + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + public static void CancelJobs() + { + if (_jobHelpers != null && _jobHelpers.Count > 0) + { + _jobHelpers.ForEach(async x => await x.CancelJob()); + _jobHelpers.Clear(); + } + } + + + + } +} diff --git a/Server/IStation.Server.Job/custom_cron/service/CustomCronServiceJobHelper.cs b/Server/IStation.Server.Job/custom_cron/service/CustomCronServiceJobHelper.cs new file mode 100644 index 0000000..d169c62 --- /dev/null +++ b/Server/IStation.Server.Job/custom_cron/service/CustomCronServiceJobHelper.cs @@ -0,0 +1,70 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夎鍒掓湇鍔′换鍔¤緟鍔╃被 + /// </summary> + public class CustomCronServiceJobHelper : IJobHelper + { + private const string _jobName = "CustomCronServiceJobName"; + private const string _jobGroup = "CustomCronServiceJobGroup"; + private const string _triggerName = "CustomCronServiceJobTrigger"; + private static IScheduler _sched;//璋冨害鍣� + + /// <summary> + /// 寮�濮嬩换鍔� + /// </summary> + public async Task StartJob() + { + if (_sched != null) + return; + + // 1.鍒涘缓scheduler鐨勫紩鐢� + var fac = new Quartz.Impl.StdSchedulerFactory(); + _sched = await fac.GetScheduler(); + + //2.鍚姩 scheduler + await _sched.Start(); + + //3.鍒涘缓浠诲姟 + var job = JobBuilder.Create<CustomCronServiceJob>() + .WithIdentity(_jobName, _jobGroup) + .Build(); + + //4.鍒涘缓Trigger + var trigger = TriggerBuilder.Create() + .WithIdentity(_triggerName, _jobGroup) + .WithSimpleSchedule(x => x.WithIntervalInMinutes(ConfigHelper.CustomCronResetThreshold) + .RepeatForever() + .WithMisfireHandlingInstructionNextWithRemainingCount()) + .Build(); + + //5.鍔犲叆璋冨害绠$悊鍣� + await _sched.ScheduleJob(job, trigger); + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + public async Task CancelJob() + { + if (_sched == null) + return; + + var triggerKey = new TriggerKey(_triggerName, _jobGroup); + if (await _sched.CheckExists(triggerKey)) + { + await _sched.UnscheduleJob(triggerKey); + } + CustomCronServiceJob.CancelJobs(); + } + + + } +} diff --git a/Server/IStation.Server.Job/custom_real/CustomRealJob.cs b/Server/IStation.Server.Job/custom_real/CustomRealJob.cs deleted file mode 100644 index 7e74a54..0000000 --- a/Server/IStation.Server.Job/custom_real/CustomRealJob.cs +++ /dev/null @@ -1,12 +0,0 @@ -锘縰sing System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace IStation.Server.real -{ - internal class Class1 - { - } -} diff --git a/Server/IStation.Server.Job/custom_real/CustomRealJobHelper.cs b/Server/IStation.Server.Job/custom_real/CustomRealJobHelper.cs deleted file mode 100644 index 17101d6..0000000 --- a/Server/IStation.Server.Job/custom_real/CustomRealJobHelper.cs +++ /dev/null @@ -1,12 +0,0 @@ -锘縰sing System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace IStation.Server.real -{ - internal class CustomRealJobHelper - { - } -} diff --git a/Server/IStation.Server.Job/custom_real/CustomRealServiceJob.cs b/Server/IStation.Server.Job/custom_real/CustomRealServiceJob.cs deleted file mode 100644 index 6809b5c..0000000 --- a/Server/IStation.Server.Job/custom_real/CustomRealServiceJob.cs +++ /dev/null @@ -1,12 +0,0 @@ -锘縰sing System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace IStation.Server.real -{ - internal class CustomRealServiceJob - { - } -} diff --git a/Server/IStation.Server.Job/custom_real/CustomRealServiceJobHelper.cs b/Server/IStation.Server.Job/custom_real/CustomRealServiceJobHelper.cs deleted file mode 100644 index fc004bd..0000000 --- a/Server/IStation.Server.Job/custom_real/CustomRealServiceJobHelper.cs +++ /dev/null @@ -1,12 +0,0 @@ -锘縰sing System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace IStation.Server.real -{ - internal class CustomRealServiceJobHelper - { - } -} diff --git a/Server/IStation.Server.Job/custom_real/job/CustomRealJob.cs b/Server/IStation.Server.Job/custom_real/job/CustomRealJob.cs new file mode 100644 index 0000000..3c3f7f2 --- /dev/null +++ b/Server/IStation.Server.Job/custom_real/job/CustomRealJob.cs @@ -0,0 +1,50 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃朵换鍔� + /// </summary> + public class CustomRealJob : Quartz.IJob + { + internal const string Instance = "Instance"; + + /// <summary> + /// + /// </summary> + public Task Execute(IJobExecutionContext context) + { + return Task.Run(() => + { + try + { + var dataMap = context.MergedJobDataMap; + var jobModel = (Model.CustomRealJob)dataMap[Instance]; + if (jobModel == null) + return; + var jobExecuter = JobFactory.CreateJob(jobModel.Execution); + if (jobExecuter == null) + { + LogHelper.Error($"鑷畾涔夊疄鏃朵换鍔�,ID:{jobModel.ID},NO:{jobModel.NO},Name:{jobModel.Name},Execution:{jobModel.Execution},鍒涘缓浠诲姟瀵硅薄澶辫触锛�"); + return; + } + jobExecuter.Execute(); + } + catch (Exception ex) + { + LogHelper.Error("鑷畾涔夊疄鏃朵换鍔★紝鎵ц鍑洪敊", ex); + var e = new JobExecutionException(ex); + throw e; + } + + }); + } + + + } +} diff --git a/Server/IStation.Server.Job/custom_real/job/CustomRealJobHelper.cs b/Server/IStation.Server.Job/custom_real/job/CustomRealJobHelper.cs new file mode 100644 index 0000000..088133d --- /dev/null +++ b/Server/IStation.Server.Job/custom_real/job/CustomRealJobHelper.cs @@ -0,0 +1,75 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃朵换鍔¤緟鍔╃被 + /// </summary> + public class CustomRealJobHelper + { + private IScheduler _sched;//璋冨害鍣� + + /// <summary> + /// 瀹炰緥 + /// </summary> + public Model.CustomRealJob Instance { get; private set; } + + /// <summary> + /// 寮�濮嬩换鍔� + /// </summary> + public async Task StartJob(Model.CustomRealJob instance) + { + if (_sched != null) + return; + this.Instance = instance ?? throw new ArgumentNullException(); + var jobName = CustomRealJobNameHelper.GetJobName(instance); + var jobGroupName = CustomRealJobNameHelper.GetJobGroupName(instance); + var triggerName = CustomRealJobNameHelper.GetTriggerName(instance); + + // 1.鍒涘缓scheduler鐨勫紩鐢� + var fac = new Quartz.Impl.StdSchedulerFactory(); + _sched = await fac.GetScheduler(); + + //2.鍚姩 scheduler + await _sched.Start(); + + //3.鍒涘缓浠诲姟 + var job = JobBuilder.Create<CustomRealJob>() + .WithIdentity(jobName, jobGroupName) + .Build(); + job.JobDataMap.Put(CustomRealJob.Instance, instance); + + //4.鍒涘缓Trigger + var trigger = TriggerBuilder.Create() + .WithIdentity(triggerName, jobGroupName) + .WithSimpleSchedule(x => x.WithIntervalInSeconds(instance.Interval) + .RepeatForever().WithMisfireHandlingInstructionNextWithRemainingCount()) + .Build(); + + //5.鍔犲叆璋冨害绠$悊鍣� + await _sched.ScheduleJob(job, trigger); + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + public async Task CancelJob() + { + if (_sched == null) + return; + var jobGroupName = CustomRealJobNameHelper.GetJobGroupName(this.Instance); + var triggerName = CustomRealJobNameHelper.GetTriggerName(this.Instance); + var triggerKey = new TriggerKey(triggerName, jobGroupName); + if (await _sched.CheckExists(triggerKey)) + { + await _sched.UnscheduleJob(triggerKey); + } + } + + } +} diff --git a/Server/IStation.Server.Job/custom_real/job/CustomRealJobNameHelper.cs b/Server/IStation.Server.Job/custom_real/job/CustomRealJobNameHelper.cs new file mode 100644 index 0000000..9b98244 --- /dev/null +++ b/Server/IStation.Server.Job/custom_real/job/CustomRealJobNameHelper.cs @@ -0,0 +1,46 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃朵换鍔″悕绉拌緟鍔╃被 + /// </summary> + public class CustomRealJobNameHelper + { + private const string _jobNameHeader = "CustomRealJob"; + private const string _jobGroupHeader = "CustomRealJobGroup"; + private const string _triggerNameHeader = "CustomRealJobTrigger"; + + /// <summary> + /// 鑾峰彇浠诲姟鍚嶇О + /// </summary> + public static string GetJobName(Model.CustomRealJob rhs) + { + var name = string.Format("{0}_{1}", _jobNameHeader, rhs.ID); + return name; + } + + /// <summary> + /// 鑾峰彇浠诲姟缁勫悕绉� + /// </summary> + public static string GetJobGroupName(Model.CustomRealJob rhs) + { + var name = string.Format("{0}_{1}", _jobGroupHeader, rhs.ID); + return name; + } + + /// <summary> + /// 鑾峰彇瑙﹀彂鍣ㄥ悕绉� + /// </summary> + public static string GetTriggerName(Model.CustomRealJob rhs) + { + var name = string.Format("{0}_{1}", _triggerNameHeader, rhs.ID); + return name; + } + + } +} diff --git a/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJob.cs b/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJob.cs new file mode 100644 index 0000000..4585257 --- /dev/null +++ b/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJob.cs @@ -0,0 +1,112 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃堕噸澶嶄换鍔� + /// </summary> + public class CustomRealRepeatJob : Quartz.IJob + { + //鑷畾涔夊疄鏃朵换鍔″瓧鍏� + private static Dictionary<long,CustomRealJobHelper> _dict=new Dictionary<long, CustomRealJobHelper>(); + + /// <summary> + /// 浠诲姟id + /// </summary> + public long JobID { get; set; } + + /// <summary> + /// + /// </summary> + public Task Execute(IJobExecutionContext context) + { + return Task.Run(async () => + { + try + { + //鑾峰彇浠诲姟 + var model = new Service.CustomRealJob().GetByID(JobID); + + //鑾峰彇浠诲姟澶辫触鍚庯紝鍋滄浠诲姟骞剁Щ闄や换鍔¤緟鍔╃被 + if (model == null) + { + if (_dict.ContainsKey(JobID)) + { + await _dict[JobID].CancelJob(); + _dict.Remove(JobID); + } + return; + } + + //灏氭湭鍒涘缓瀹炴椂浠诲姟鏃讹紝鍒涘缓瀹炴椂浠诲姟杈呭姪绫� + if (!_dict.ContainsKey(JobID)) + { + var jobHelper = new CustomRealJobHelper(); + await jobHelper.StartJob(model); + _dict.Add(JobID, jobHelper); + return; + } + + //浠诲姟宸插瓨鍦紝妫�鏌ヤ换鍔℃墽琛岄棿闅旀槸鍚﹀彂鐢熷彉鍖栵紝鑻ュ彂鐢熷彉鍖栵紝閲嶇疆浠诲姟 + if (_dict[JobID].Instance.Interval != model.Interval) + { + await _dict[JobID].CancelJob(); + var jobHelper = new CustomRealJobHelper(); + await jobHelper.StartJob(model); + _dict[JobID] = jobHelper; + } + + } + catch (Exception ex) + { + LogHelper.Error("鑷畾涔夊疄鏃堕噸澶嶄换鍔★紝鎵ц鍑洪敊", ex); + var e = new JobExecutionException(ex); + throw e; + } + }); + + + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + /// <returns></returns> + public async Task CancelJob() + { + await CancelJob(JobID); + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + /// <param name="jobId">浠诲姟id</param> + public static async Task CancelJob(long jobId) + { + if (_dict.ContainsKey(jobId)) + { + await _dict[jobId].CancelJob(); + _dict.Remove(jobId); + } + + } + + /// <summary> + /// 鍙栦笅浠诲姟 + /// </summary> + public static async Task CancelJobs() + { + foreach (var key in _dict.Keys) + { + await CancelJob(key); + } + } + + } + +} diff --git a/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJobHelper.cs b/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJobHelper.cs new file mode 100644 index 0000000..2354ebd --- /dev/null +++ b/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJobHelper.cs @@ -0,0 +1,78 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃堕噸澶嶄换鍔¤緟鍔╃被 + /// </summary> + public class CustomRealRepeatJobHelper + { + private IScheduler _sched;//璋冨害鍣� + + /// <summary> + /// 瀹炰緥 + /// </summary> + public Model.CustomRealJob Instance { get; private set; } + + /// <summary> + /// 寮�濮嬩换鍔� + /// </summary> + public async Task StartJob(Model.CustomRealJob instance) + { + if (_sched != null) + return; + this.Instance = instance ?? throw new ArgumentNullException(); + var jobName = CustomRealRepeatJobNameHelper.GetJobName(instance); + var jobGroupName = CustomRealRepeatJobNameHelper.GetJobGroupName(instance); + var triggerName = CustomRealRepeatJobNameHelper.GetTriggerName(instance); + + // 1.鍒涘缓scheduler鐨勫紩鐢� + var fac = new Quartz.Impl.StdSchedulerFactory(); + _sched = await fac.GetScheduler(); + + //2.鍚姩 scheduler + await _sched.Start(); + + //3.鍒涘缓浠诲姟 + var job = JobBuilder.Create<CustomRealRepeatJob>() + .WithIdentity(jobName, jobGroupName) + .UsingJobData("JobID", instance.ID) + .Build(); + + //4.鍒涘缓Trigger + var trigger = TriggerBuilder.Create() + .WithIdentity(triggerName, jobGroupName) + .WithSimpleSchedule(x => x.WithIntervalInMinutes(instance.Repeat) + .RepeatForever().WithMisfireHandlingInstructionNextWithRemainingCount()) + .Build(); + + //5.鍔犲叆璋冨害绠$悊鍣� + await _sched.ScheduleJob(job, trigger); + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + public async Task CancelJob() + { + if (_sched == null) + return; + var jobGroupName = CustomRealRepeatJobNameHelper.GetJobGroupName(this.Instance); + var triggerName = CustomRealRepeatJobNameHelper.GetTriggerName(this.Instance); + var triggerKey = new TriggerKey(triggerName, jobGroupName); + if (await _sched.CheckExists(triggerKey)) + { + await _sched.UnscheduleJob(triggerKey); + } + await CustomRealRepeatJob.CancelJob(this.Instance.ID); + } + + + } + +} diff --git a/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJobNameHelper.cs b/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJobNameHelper.cs new file mode 100644 index 0000000..cd1b585 --- /dev/null +++ b/Server/IStation.Server.Job/custom_real/repeat/CustomRealRepeatJobNameHelper.cs @@ -0,0 +1,48 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃堕噸澶嶄换鍔″悕绉拌緟鍔╃被 + /// </summary> + public class CustomRealRepeatJobNameHelper + { + private const string _jobNameHeader = "CustomRealRepeatJob"; + private const string _jobGroupHeader = "CustomRealRepeatJobGroup"; + private const string _triggerNameHeader = "CustomRealRepeatJobTrigger"; + + /// <summary> + /// 鑾峰彇浠诲姟鍚嶇О + /// </summary> + public static string GetJobName(Model.CustomRealJob rhs) + { + var name = string.Format("{0}_{1}", _jobNameHeader, rhs.ID); + return name; + } + + /// <summary> + /// 鑾峰彇浠诲姟缁勫悕绉� + /// </summary> + public static string GetJobGroupName(Model.CustomRealJob rhs) + { + var name = string.Format("{0}_{1}", _jobGroupHeader, rhs.ID); + return name; + } + + /// <summary> + /// 鑾峰彇瑙﹀彂鍣ㄥ悕绉� + /// </summary> + public static string GetTriggerName(Model.CustomRealJob rhs) + { + var name = string.Format("{0}_{1}", _triggerNameHeader, rhs.ID); + return name; + } + + + + } +} diff --git a/Server/IStation.Server.Job/custom_real/service/CustomRealServiceJob.cs b/Server/IStation.Server.Job/custom_real/service/CustomRealServiceJob.cs new file mode 100644 index 0000000..b94c87a --- /dev/null +++ b/Server/IStation.Server.Job/custom_real/service/CustomRealServiceJob.cs @@ -0,0 +1,115 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃舵湇鍔′换鍔� + /// </summary> + public class CustomRealServiceJob:Quartz.IJob + { + private static List<CustomRealRepeatJobHelper> _jobHelpers = new List<CustomRealRepeatJobHelper>(); + + /// <summary> + /// + /// </summary> + public Task Execute(IJobExecutionContext context) + { + return Task.Run(async () => + { + try + { + #region 鍔犺浇鎵�鏈変换鍔� + + var jobList = new Service.CustomRealJob().GetAll(); + if (jobList == null || jobList.Count < 1) + { + LogHelper.Info("鑷畾涔夊疄鏃舵湇鍔′换鍔′腑锛屾湭妫�绱㈠埌鑷畾涔夊疄鏃朵换鍔′俊鎭�"); + CancelJobs(); + return; + } + jobList = jobList.Where(x => x.UseStatus == Model.eUseStatus.Enable).ToList(); + if (jobList.Count < 1) + { + LogHelper.Info("鑷畾涔夊疄鏃舵湇鍔′换鍔′腑锛屾湭妫�绱㈠埌鏈夋晥鑷畾涔夊疄鏃朵换鍔′俊鎭�"); + CancelJobs(); + return; + } + + #endregion + + #region 寮�鍚换鍔� + + foreach (var job in jobList) + { + var jobHelper = _jobHelpers.Find(t => t.Instance.ID == job.ID); + if (jobHelper == null) + { + jobHelper = new CustomRealRepeatJobHelper(); + await jobHelper.StartJob(job); + _jobHelpers.Add(jobHelper); + LogHelper.Info($"鑷畾涔夊疄鏃舵湇鍔′换鍔′腑锛欼D:{job.ID},NO:{job.NO},Name:{job.Name} 鐨勪换鍔″紑鍚紒"); + } + } + + #endregion + + #region 鍏抽棴浠诲姟 + + foreach (var jobHelper in _jobHelpers.ToList()) + { + var job = jobList.Find(t=>t.ID==jobHelper.Instance.ID); + if (job == null) + { + await jobHelper.CancelJob(); + _jobHelpers.Remove(jobHelper); + LogHelper.Info($"鑷畾涔夊疄鏃舵湇鍔′换鍔′腑锛欼D:{job.ID},NO:{job.NO},Name:{job.Name} 鐨勪换鍔″叧闂紒"); + continue; + } + + if (job.Repeat != jobHelper.Instance.Repeat) + { + await jobHelper.CancelJob(); + _jobHelpers.Remove(jobHelper); + var rJobHelper = new CustomRealRepeatJobHelper(); + await rJobHelper.StartJob(job); + _jobHelpers.Add(rJobHelper); + } + } + + #endregion + + LogHelper.Info($"鑷畾涔夊疄鏃舵湇鍔′换鍔′腑锛屽紑鍚换鍔℃暟閲忎负{_jobHelpers.Count}!"); + + } + catch (Exception ex) + { + LogHelper.Error("鑷畾涔夊疄鏃舵湇鍔′换鍔′腑锛屾墽琛屽嚭閿�", ex); + var e = new JobExecutionException(ex); + throw e; + } + }); + + + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + public static void CancelJobs() + { + if (_jobHelpers != null && _jobHelpers.Count > 0) + { + _jobHelpers.ForEach(async x => await x.CancelJob()); + _jobHelpers.Clear(); + } + } + + + + } +} diff --git a/Server/IStation.Server.Job/custom_real/service/CustomRealServiceJobHelper.cs b/Server/IStation.Server.Job/custom_real/service/CustomRealServiceJobHelper.cs new file mode 100644 index 0000000..1d7c19c --- /dev/null +++ b/Server/IStation.Server.Job/custom_real/service/CustomRealServiceJobHelper.cs @@ -0,0 +1,70 @@ +锘縰sing Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 鑷畾涔夊疄鏃舵湇鍔′换鍔¤緟鍔╃被 + /// </summary> + public class CustomRealServiceJobHelper : IJobHelper + { + private const string _jobName = "CustomRealServiceJobName"; + private const string _jobGroup = "CustomRealServiceJobGroup"; + private const string _triggerName = "CustomRealServiceJobTrigger"; + private static IScheduler _sched;//璋冨害鍣� + + /// <summary> + /// 寮�濮嬩换鍔� + /// </summary> + public async Task StartJob() + { + if (_sched != null) + return; + + // 1.鍒涘缓scheduler鐨勫紩鐢� + var fac = new Quartz.Impl.StdSchedulerFactory(); + _sched = await fac.GetScheduler(); + + //2.鍚姩 scheduler + await _sched.Start(); + + //3.鍒涘缓浠诲姟 + var job = JobBuilder.Create<CustomRealServiceJob>() + .WithIdentity(_jobName, _jobGroup) + .Build(); + + //4.鍒涘缓Trigger + var trigger = TriggerBuilder.Create() + .WithIdentity(_triggerName, _jobGroup) + .WithSimpleSchedule(x => x.WithIntervalInMinutes(ConfigHelper.CustomRealResetThreshold) + .RepeatForever() + .WithMisfireHandlingInstructionNextWithRemainingCount()) + .Build(); + + //5.鍔犲叆璋冨害绠$悊鍣� + await _sched.ScheduleJob(job, trigger); + } + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + public async Task CancelJob() + { + if (_sched == null) + return; + + var triggerKey = new TriggerKey(_triggerName, _jobGroup); + if (await _sched.CheckExists(triggerKey)) + { + await _sched.UnscheduleJob(triggerKey); + } + CustomRealServiceJob.CancelJobs(); + } + + + } +} diff --git a/Server/IStation.Server.Job/helpers/ConfigHelper.cs b/Server/IStation.Server.Job/helpers/ConfigHelper.cs new file mode 100644 index 0000000..9c9121f --- /dev/null +++ b/Server/IStation.Server.Job/helpers/ConfigHelper.cs @@ -0,0 +1,29 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + internal class ConfigHelper + { + /// <summary> + /// 鑷畾涔夊疄鏃堕噸缃榾鍊� + /// </summary> + public static int CustomRealResetThreshold + { + get { return Settings.Job.Execution.CustomRealResetThreshold; } + } + + /// <summary> + /// 鑷畾涔夎鍒掗噸缃榾鍊� + /// </summary> + public static int CustomCronResetThreshold + { + get { return Settings.Job.Execution.CustomCronResetThreshold; } + } + + + } +} diff --git a/Server/IStation.Server.Job/helpers/JobHelper.cs b/Server/IStation.Server.Job/helpers/JobHelper.cs new file mode 100644 index 0000000..757ccc0 --- /dev/null +++ b/Server/IStation.Server.Job/helpers/JobHelper.cs @@ -0,0 +1,37 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 浠诲姟杈呭姪绫� + /// </summary> + public class JobHelper + { + private List<IJobHelper> _jobHelpers = new List<IJobHelper>() + { + new CustomCronServiceJobHelper(), + new CustomRealServiceJobHelper() + }; + + /// <summary> + /// + /// </summary> + public void StartJob() + { + _jobHelpers.ForEach(async x => await x.StartJob()); + } + + /// <summary> + /// + /// </summary> + public void CancelJob() + { + _jobHelpers.ForEach(async x => await x.CancelJob()); + } + + } +} diff --git a/Server/IStation.Server.Job/interface/IJobHelper.cs b/Server/IStation.Server.Job/interface/IJobHelper.cs new file mode 100644 index 0000000..6aaa888 --- /dev/null +++ b/Server/IStation.Server.Job/interface/IJobHelper.cs @@ -0,0 +1,27 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation.Server +{ + /// <summary> + /// 浠诲姟杈呭姪绫绘帴鍙� + /// </summary> + public interface IJobHelper + { + /// <summary> + /// 寮�濮嬩换鍔� + /// </summary> + Task StartJob(); + + /// <summary> + /// 鍙栨秷浠诲姟 + /// </summary> + Task CancelJob(); + + } + + +} diff --git a/Settings/IStation.Settings/models/job/Paras_Job.cs b/Settings/IStation.Settings/models/job/Paras_Job.cs index 3842856..5f5e704 100644 --- a/Settings/IStation.Settings/models/job/Paras_Job.cs +++ b/Settings/IStation.Settings/models/job/Paras_Job.cs @@ -15,5 +15,10 @@ /// 鏁版嵁搴� /// </summary> public Paras_Job_DataBase DataBase { get; set; } + + /// <summary> + /// 鎵ц鍙傛暟 + /// </summary> + public Paras_Job_Execution Execution { get; set; } } } diff --git a/Settings/IStation.Settings/models/job/Paras_Job_Execution.cs b/Settings/IStation.Settings/models/job/Paras_Job_Execution.cs new file mode 100644 index 0000000..6ff3200 --- /dev/null +++ b/Settings/IStation.Settings/models/job/Paras_Job_Execution.cs @@ -0,0 +1,26 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IStation +{ + /// <summary> + /// 浠诲姟鎵ц鍙傛暟 + /// </summary> + public class Paras_Job_Execution + { + /// <summary> + /// 鑷畾涔夊疄鏃堕噸缃榾鍊硷紙鍒嗛挓锛� + /// </summary> + public int CustomRealResetThreshold { get; set; } + + /// <summary> + /// 鑷畾涔夎鍒掗噸缃榾鍊硷紙鍒嗛挓锛� + /// </summary> + public int CustomCronResetThreshold { get; set; } + + } + +} diff --git a/Settings/IStation.Settings/paras_settings.json b/Settings/IStation.Settings/paras_settings.json index 3ed60ae..789080a 100644 --- a/Settings/IStation.Settings/paras_settings.json +++ b/Settings/IStation.Settings/paras_settings.json @@ -163,6 +163,10 @@ "Job": { "DataBase": { "ConnectString": "PORT=5432;DATABASE=istation_job_test;HOST=101.133.223.111;PASSWORD=Eventech2010;USER ID=postgres;" + }, + "Execution": { + "CustomRealResetThreshold": 60, + "CustomCronResetThreshold": 1440 } }, diff --git a/TopShelf/IStation.TopShelf.Job/IStation.TopShelf.Job.csproj b/TopShelf/IStation.TopShelf.Job/IStation.TopShelf.Job.csproj new file mode 100644 index 0000000..c1f99ff --- /dev/null +++ b/TopShelf/IStation.TopShelf.Job/IStation.TopShelf.Job.csproj @@ -0,0 +1,15 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <OutputType>Exe</OutputType> + <TargetFramework>net6.0</TargetFramework> + <ImplicitUsings>enable</ImplicitUsings> + <Nullable>enable</Nullable> + </PropertyGroup> + + <ItemGroup> + <ProjectReference Include="..\..\Component\IStation.TopShelf\IStation.TopShelf.csproj" /> + <ProjectReference Include="..\..\Server\IStation.Server.Job\IStation.Server.Job.csproj" /> + </ItemGroup> + +</Project> diff --git a/TopShelf/IStation.TopShelf.Job/Program.cs b/TopShelf/IStation.TopShelf.Job/Program.cs new file mode 100644 index 0000000..e79ec33 --- /dev/null +++ b/TopShelf/IStation.TopShelf.Job/Program.cs @@ -0,0 +1,16 @@ +锘�// See https://aka.ms/new-console-template for more information +using IStation.TopShelf; +using Topshelf; + +HostFactory.Run(x => +{ + x.Service<Service>(); + x.RunAsLocalSystem(); + x.SetDescription("鏅烘収娉电珯Core鐗堜换鍔$▼搴�"); + x.SetDisplayName("IStaion.Core.Server.Job"); + x.SetServiceName("IStaion.Core.Server.Job"); + x.EnableServiceRecovery(r => r.RestartService(TimeSpan.FromSeconds(120))); + x.StartAutomatically(); + + +}); \ No newline at end of file diff --git a/TopShelf/IStation.TopShelf.Job/Service.cs b/TopShelf/IStation.TopShelf.Job/Service.cs new file mode 100644 index 0000000..ed38665 --- /dev/null +++ b/TopShelf/IStation.TopShelf.Job/Service.cs @@ -0,0 +1,40 @@ +锘縰sing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Topshelf; +using IStation.Server; + +namespace IStation.TopShelf +{ + /// <summary> + /// + /// </summary> + public class Service : ServiceControl + { + private readonly JobHelper _jobHelper = new JobHelper(); + + /// <summary> + /// + /// </summary> + /// <param name="hostControl"></param> + /// <returns></returns> + public bool Start(HostControl hostControl) + { + _jobHelper.StartJob(); + return true; + } + + /// <summary> + /// + /// </summary> + /// <param name="hostControl"></param> + /// <returns></returns> + public bool Stop(HostControl hostControl) + { + _jobHelper.CancelJob(); + return true; + } + } +} -- Gitblit v1.9.3