From 6f3b05c06125b457d0c78e259f3befe4910881cf Mon Sep 17 00:00:00 2001
From: Ben Lin <maobin001@msn.com>
Date: 星期日, 27 十月 2024 16:54:29 +0800
Subject: [PATCH] 计划任务更新

---
 Tiger.Business/Services/Base/InterfaceServiceNew.cs |  350 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 322 insertions(+), 28 deletions(-)

diff --git a/Tiger.Business/Services/Base/InterfaceServiceNew.cs b/Tiger.Business/Services/Base/InterfaceServiceNew.cs
index 76a0bfb..93e4aea 100644
--- a/Tiger.Business/Services/Base/InterfaceServiceNew.cs
+++ b/Tiger.Business/Services/Base/InterfaceServiceNew.cs
@@ -1,29 +1,37 @@
-锘縰sing Newtonsoft.Json;
+锘縰sing FluentScheduler;
+using Newtonsoft.Json;
 using Rhea.Common;
 using Sundial;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
+using System.Security.Cryptography;
 using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using Tiger.IBusiness;
 using Tiger.Model;
+using Tiger.Model.Entitys.MES.Position;
 using Tiger.Model.Minsun;
-using static System.Collections.Specialized.BitVector32;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser;
+using static Tiger.Model.TrigArgs;
 
 namespace Tiger.Business
 {
-    public class InterfaceServiceNew: IInterfaceService
+    /// <summary>
+    /// 
+    /// </summary>
+    public class InterfaceServiceNew : IInterfaceService
     {
+        #region Sundial璁″垝璋冨害 鏃х増鏈娇鐢�
 
-        public ISchedulerFactory _schedulerFactory { get; set; }
+        public Sundial.ISchedulerFactory _schedulerFactory { get; set; }
         /// <summary>
         /// 璁剧疆璁″垝浠诲姟宸ュ巶绫�
         /// </summary>
         /// <param name="schedulerFactory"></param>
-        public void SetSchedulerFactory(ISchedulerFactory schedulerFactory)
+        public void SetSchedulerFactory(Sundial.ISchedulerFactory schedulerFactory)
         {
             _schedulerFactory = schedulerFactory;
         }
@@ -34,10 +42,10 @@
         /// <typeparam name="TJob"></typeparam>
         /// <param name="newEntity"></param>
         /// <param name="jobParam"></param>
-        public ApiAction AddJob<TJob>(TJob newEntity, TskJobParam jobParam) where TJob : class, IJob
+        public ApiAction AddJob<TJob>(TJob newEntity, TskJobParam jobParam) where TJob : class, Sundial.IJob
         {
             ApiAction apiAction = new();
-            TriggerBuilder triggerBuilder = Triggers.Period(jobParam.Period*60*1000).LoadFrom(new
+            Sundial.TriggerBuilder triggerBuilder = Sundial.Triggers.Period(jobParam.Period * 60 * 1000).LoadFrom(new
             {
                 TriggerId = jobParam.JobName + "_trigger1",
             });
@@ -60,7 +68,7 @@
         /// <typeparam name="TJob"></typeparam>
         /// <param name="jobname"></param>
         /// <param name="triggerBuilders"></param>
-        public ApiAction AddJob<TJob>(string jobname, params TriggerBuilder[] triggerBuilders) where TJob : class, IJob
+        public ApiAction AddJob<TJob>(string jobname, params Sundial.TriggerBuilder[] triggerBuilders) where TJob : class, Sundial.IJob
         {
             ApiAction apiAction = new();
             triggerBuilders[0].LoadFrom(new
@@ -84,9 +92,9 @@
         public ApiAction UpdateJob(TSK_JOB job)
         {
             ApiAction apiAction = new ApiAction();
-            IScheduler scheduler = GetJob(job.JobName);
+            Sundial.IScheduler scheduler = GetJob(job.JobName);
             var trigger = scheduler.GetTrigger($"{job.JobName}_trigger1");
-            if (trigger.Status == TriggerStatus.Running)
+            if (trigger.Status == Sundial.TriggerStatus.Running)
             {
                 apiAction.IsSuccessed = false;
                 apiAction.Message = $"浣滀笟[{job.JobName}]姝e湪杩愯涓嶈兘缂栬緫";
@@ -143,7 +151,8 @@
         public void StartJob(string jobname)
         {
             // 甯﹁繑鍥炲��
-            var scheduleResult = _schedulerFactory.TryRunJob(jobname);
+            Sundial.IScheduler scheduler;
+            var scheduleResult = _schedulerFactory.TryRunJob(jobname, out scheduler);
         }
 
         /// <summary>
@@ -151,9 +160,9 @@
         /// </summary>
         /// <param name="jobname"></param>
         /// <returns></returns>
-        public IScheduler GetJob(string jobname)
+        public Sundial.IScheduler GetJob(string jobname)
         {
-            IScheduler scheduler;
+            Sundial.IScheduler scheduler;
             var scheduleResult = _schedulerFactory.TryGetJob(jobname, out scheduler);
             return scheduler;
         }
@@ -162,7 +171,7 @@
         /// 鑾峰彇鎵�鏈変綔涓�
         /// </summary>
         /// <returns></returns>
-        public List<IScheduler> GetJobs()
+        public List<Sundial.IScheduler> GetJobs()
         {
             return _schedulerFactory.GetJobs().ToList();
         }
@@ -199,20 +208,20 @@
         {
             try
             {
-	            var jobs = Biz.Db.Queryable<TSK_JOB>().IncludesAllFirstLayer().ToList();
-	            foreach (var job in jobs)
-	            {
-	                Type type = Type.GetType($"{job.AssemblyName}.{job.JobType},{job.AssemblyName}", throwOnError: true);
-	                _schedulerFactory.AddJob(type, job.JobName, 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);
-	                    });
-	                }
-	            }
+                var jobs = Biz.Db.Queryable<TSK_JOB>().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)
             {
@@ -254,5 +263,290 @@
             }
             return action;
         }
+        #endregion
+
+        #region 鏂扮増鏈鍒掕皟搴� FluentScheduler
+        /// <summary>
+        /// 鍒濆鍖栬鍒掕皟搴�
+        /// </summary>
+        public void JobInitialize()
+        {
+            JobManager.Initialize(AddJobsFromDB());
+            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\r\n");
+            JobManager.JobEnd += info => Logger.Scheduler.Info($"{info.Name}: ended ({info.Duration})\r\n");
+            SaveRunningStatus(); //淇濆瓨鐘舵��
+        }
+
+        private void SaveRunningStatus()
+        {
+            List<TSK_TRIG> listTrig = new List<TSK_TRIG>();
+            foreach (var schedule in JobManager.RunningSchedules)
+            {
+                var job = Biz.Db.Queryable<TSK_JOB>().Where(q => q.JobName == schedule.Name).First();
+                if (job != null)
+                {
+                    TSK_TRIG trig = new TSK_TRIG();
+                    trig = Biz.Db.Queryable<TSK_TRIG>().Where(q => q.JobId == job.ID).First();
+                    trig.Status = TSK_TRIG.Statuss.Running.GetValue();
+                    trig.StartTime = DateTime.Now;
+                    listTrig.Add(trig);
+                }
+            }
+            var db = Biz.Db;
+            //淇濆瓨鍒版暟鎹簱
+            var dbTran = db.UseTran(() =>
+            {
+                if (listTrig.Count > 0)
+                {
+                    db.Updateable(listTrig, "system").UpdateColumns(q => new { q.Status, q.UPDATE_USER, q.UPDATE_TIME }).ExecuteCommand();
+                }
+            });
+            if (!dbTran.IsSuccess)
+            {
+                Logger.Scheduler.Trace(dbTran.ErrorException, $"浣滀笟淇濆瓨鍒版暟鎹簱寮傚父");
+            }
+        }
+
+        /// <summary>
+        /// 娣诲姞宸ヤ綔浠诲姟
+        /// </summary>
+        /// <typeparam name="TJob"></typeparam>
+        /// <param name="newEntity"></param>
+        /// <param name="jobParam"></param>
+        /// <returns></returns>
+        public ApiAction AddTskJob<TJob>(TJob newEntity, FluentJobParam jobParam) where TJob : class, ITJob
+        {
+            ApiAction apiAction = new();
+            try
+            {
+                if (!JobManager.AllSchedules.Any(q => q.Name == jobParam.JobName))
+                {
+                    JobManager.AddJob<TJob>((s) => GenerateSchedule(jobParam.Args, s.WithName(jobParam.JobName)));
+                    string guid = Guid.NewGuid().ToString("N");
+                    TSK_JOB job = Biz.Db.Queryable<TSK_JOB>().Where(x => x.JobName == jobParam.JobName).First() ?? new()
+                    {
+                        ID = guid,
+                        Remark = jobParam.Remark,
+                        JobType = jobParam.JobName,
+                        AssemblyName = jobParam.AssemblyName,
+                        JobName = jobParam.JobName,
+                    };
+                    var trigger = Biz.Db.Queryable<TSK_TRIG>().Where(x => x.JobId == job.ID).First() ?? new TSK_TRIG()
+                    {
+                        JobId = guid,
+                        StartTime = DateTime.Now,
+                        NumberOfRuns = 1,
+                    };
+                    trigger.Args = JsonConvert.SerializeObject(jobParam.Args);
+                    trigger.Status = TSK_TRIG.Statuss.Running.GetValue();
+                    var db = Biz.Db;
+                    //淇濆瓨鍒版暟鎹簱
+                    var dbTran = db.UseTran(() =>
+                    {
+                        var y = db.Storageable(job)
+                           .WhereColumns(t => new { t.JobName, t.GHOST_ROW })
+                           .ToStorage();
+                        y.AsInsertable.ExecuteCommand();
+                        y.AsUpdateable.IgnoreColumns(x => x.ID).ExecuteCommand();
+
+                        var z = db.Storageable(trigger)
+                           .WhereColumns(t => new { t.JobId, t.GHOST_ROW })
+                           .ToStorage();
+                        z.AsInsertable.ExecuteCommand();
+                        z.AsUpdateable.IgnoreColumns(x => x.ID).ExecuteCommand();
+                    });
+                    if (!dbTran.IsSuccess)
+                    {
+                        apiAction.CatchExceptionWithLog(dbTran.ErrorException, $"娣诲姞宸ヤ綔浠诲姟鏃朵繚瀛樺埌鏁版嵁搴撳紓甯�");
+                    }
+                }
+
+            }
+            catch (System.Exception ex)
+            {
+                apiAction.CatchExceptionWithLog(ex);
+            }
+            if (!apiAction.IsSuccessed) { JobManager.RemoveJob(jobParam.JobName); }
+            return apiAction;
+        }
+
+        /// <summary>
+        /// 鍒犻櫎浣滀笟
+        /// </summary>
+        /// <param name="jobname"></param>
+        public void RemovefJob(string jobname)
+        {
+            if (JobManager.AllSchedules.Any(q => q.Name == jobname))
+            {
+                string guid = Guid.NewGuid().ToString("N");
+                TSK_JOB job = Biz.Db.Queryable<TSK_JOB>().Where(x => x.JobName == jobname).First();
+                var trigger = Biz.Db.Queryable<TSK_TRIG>().Where(x => x.JobId == job.ID).First();
+                trigger.Status = TSK_TRIG.Statuss.Stop.GetValue();
+                var db = Biz.Db;
+                //淇濆瓨鍒版暟鎹簱
+                var dbTran = db.UseTran(() =>
+                {
+                    db.Updateable(trigger, "system_job").UpdateColumns(q=>new { q.Status,q.UPDATE_TIME,q.UPDATE_USER}).ExecuteCommand();
+                });
+                if (!dbTran.IsSuccess)
+                {
+                    Logger.Scheduler.Fatal(dbTran.ErrorException, $"娣诲姞宸ヤ綔浠诲姟鏃朵繚瀛樺埌鏁版嵁搴撳紓甯�");
+                }
+            }
+            JobManager.RemoveJob(jobname);
+        }
+
+        /// <summary>
+        /// 浠庢暟鎹簱鎵归噺娣诲姞浠诲姟
+        /// </summary>
+        public Registry AddJobsFromDB()
+        {
+            // 澹版槑涓�涓猂egistry绫�
+            var registry = new Registry();
+            try
+            {
+                var jobs = Biz.Db.Queryable<TSK_JOB>().IncludesAllFirstLayer().ToList();
+                foreach (var job in jobs)
+                {
+                    if (job.JobName == "fU9C_MES_GetWo" || job.JobName == "fTest")
+                    {
+                        Type type = Type.GetType($"{job.AssemblyName}.{job.JobType},{job.AssemblyName}", throwOnError: true);
+                        dynamic _type = Activator.CreateInstance(type);
+                        TrigArgs args = JsonConvert.DeserializeObject<TrigArgs>(job.Triggers[0].Args);
+                        Schedule schedule = Schedule(_type, job.JobName, registry);
+                        //鐢熸垚璁″垝
+                        GenerateSchedule(args, schedule);
+                    }
+                }
+            }
+            catch (System.Exception ex)
+            {
+                Logger.Console.Fatal(ex, "Add Job From DB Exception");
+            }
+            return registry;
+        }
+
+        /// <summary>
+        /// 鏍规嵁瀹炰綋鍚嶆敞鍐岃鍒�
+        /// </summary>
+        /// <typeparam name="TJob"></typeparam>
+        /// <param name="entity"></param>
+        /// <param name="JobName"></param>
+        /// <param name="registry"></param>
+        /// <returns></returns>
+        private Schedule Schedule<TJob>(TJob entity, string JobName, Registry registry) where TJob : class, ITJob
+        {
+            return registry.Schedule<TJob>().WithName(typeof(TJob).Name);
+        }
+
+        /// <summary>
+        /// 鐢熸垚璁″垝
+        /// </summary>
+        /// <param name="args"></param>
+        /// <param name="schedule"></param>
+        private void GenerateSchedule(TrigArgs args, Schedule schedule)
+        {
+            SpecificTimeUnit specificTimeUnit = null;
+            TimeUnit timeUnit = null;
+            if (args.NonReentrant == "Y") { schedule = schedule.NonReentrant(); } //灏辨槸鏄惁璺熶箣鍓嶇殑杩樻病杩愯瀹岀殑璁″垝鍚屾椂杩愯銆�
+            switch (args.runType)
+            {
+                case RunType.ToRunNow:
+                    specificTimeUnit = schedule.ToRunNow(); //椹笂杩愯
+                    break;
+                case RunType.ToRunOnceAt:
+                    specificTimeUnit = schedule.ToRunOnceAt(args.ToRunOnceAtDt.AddMinutes(args.NowAddMinutes)); //杩愯涓�娆″湪鍝釜鏃堕棿,
+                    break;
+                case RunType.ToRunOnceIn:
+                    timeUnit = schedule.ToRunOnceIn(args.ToRunOnceIn); //鍦ㄥ灏戝悗杩愯涓�娆�
+                    break;
+                case RunType.ToRunEvery:
+                    timeUnit = schedule.ToRunEvery(args.ToRunEvery); //姣忛殧澶氬皯杩愯涓�鍥�
+                    break;
+            }
+            if (specificTimeUnit != null) { timeUnit = specificTimeUnit.AndEvery(args.ToRunEvery); } //姣忛殧澶氬皯杩愯涓�鍥烇紝鍔犲湪ToRunNow銆乀oRunOnceAt鍚庨潰
+            //鎸夋椂闂寸被鍨嬫潵杩愯
+            switch (args.Type)
+            {
+                case TrigArgs.EveryType.Milliseconds:
+                    timeUnit.Milliseconds();
+                    break;
+                case TrigArgs.EveryType.Seconds:
+                    timeUnit.Seconds(); //琛ㄧず鎸夌锛屽灏戠瑕佺湅鍓嶉潰Every鐨勬暟锛屾瘮濡傦細ToRunEvery(5).Seconds() 杩欎釜灏辫〃绀� 闅�5绉掕繍琛屼竴娆�
+                    break;
+                case TrigArgs.EveryType.Minutes:
+                    timeUnit.Minutes();
+                    break;
+                case TrigArgs.EveryType.Hours:
+                    if (args.Minutes > 0)
+                    {
+                        timeUnit.Hours().At(args.Minutes); //琛ㄧず鎸夋瘡灏忔椂鐨勫垎閽燂紝澶氬皯鍒嗚鐪嬪墠闈very鐨勬暟锛屾瘮濡傦細ToRunEvery(1).Hours().At(5) 杩欎釜灏辫〃绀� 闅�1灏忔椂鐨勭5鍒嗛挓杩愯涓�娆�
+                    }
+                    else
+                    {
+                        timeUnit.Hours();
+                    }
+                    break;
+                case TrigArgs.EveryType.Days:
+                    if (args.Hours > 0)
+                    {
+                        timeUnit.Days().At(args.Hours, args.Minutes); //琛ㄧず鎸夊ぉ锛屽灏戝ぉ瑕佺湅鍓嶉潰Every鐨勬暟锛屾瘮濡傦細ToRunEvery(2).Days().At(14, 15) 杩欎釜灏辫〃绀� 闅�2澶╃殑14:15杩愯涓�娆�
+                    }
+                    else
+                    {
+                        timeUnit.Days();
+                    }
+                    break;
+                case TrigArgs.EveryType.Weeks:
+                    if (args.Hours > 0)
+                    {
+                        timeUnit.Weeks().At(args.Hours, args.Minutes); //琛ㄧず鎸夊懆锛屽灏戝懆瑕佺湅鍓嶉潰Every鐨勬暟锛屾瘮濡傦細ToRunEvery(1).Weeks().At(14, 15) 杩欎釜灏辫〃绀� 闅�1鍛ㄧ殑14:15杩愯涓�娆�
+                    }
+                    else
+                    {
+                        timeUnit.Weeks();
+                    }
+                    break;
+                case TrigArgs.EveryType.Weekdays:
+                    if (args.Hours > 0)
+                    {
+                        timeUnit.Weekdays().At(args.Hours, args.Minutes);
+                    }
+                    else
+                    {
+                        timeUnit.Weekdays();
+                    }
+                    break;
+                case TrigArgs.EveryType.Months:
+                    if (args.Days > 0 && args.Hours > 0)
+                    {
+                        timeUnit.Months().On(args.Days).At(args.Hours, args.Minutes);
+                    }
+                    else
+                    {
+                        timeUnit.Months();
+                    }
+                    break;
+            }
+        }
+
+        /// <summary>
+        /// 鍋滄鏈嶅姟
+        /// </summary>
+        public void Stop()
+        {
+            JobManager.Stop();
+        }
+
+        /// <summary>
+        /// 鍦ㄤ换鍔″畬鎴愬悗绛夊緟鎴栬�呭仠姝�
+        /// </summary>
+        public void StopAndBlock()
+        {
+            JobManager.StopAndBlock();
+        }
+
+        #endregion
     }
 }

--
Gitblit v1.9.3