コード例 #1
0
        private static async Task <ScheduleView> GetScheduleView(Guid sid)
        {
            using (var scope = new Core.ScopeDbContext())
            {
                var db    = scope.GetDbContext();
                var model = db.Schedules.FirstOrDefault(x => x.Id == sid && x.Status != (int)ScheduleStatus.Deleted);
                if (model != null)
                {
                    ScheduleView view = new ScheduleView()
                    {
                        Schedule = model
                    };
                    view.Keepers = (from t in db.ScheduleKeepers
                                    join u in db.SystemUsers on t.UserId equals u.Id
                                    where t.ScheduleId == model.Id && !string.IsNullOrEmpty(u.Email)
                                    select new KeyValuePair <string, string>(u.RealName, u.Email)
                                    ).ToList();
                    view.Children = (from c in db.ScheduleReferences
                                     join t in db.Schedules on c.ChildId equals t.Id
                                     where c.ScheduleId == model.Id && c.ChildId != model.Id
                                     select new { t.Id, t.Title }
                                     ).ToDictionary(x => x.Id, x => x.Title);
                    await LoadPluginFile(db, model);

                    return(view);
                }
                throw new InvalidOperationException($"不存在的任务id:{sid}");
            }
        }
コード例 #2
0
 private static ScheduleContext GetScheduleContext(Guid sid)
 {
     using (var scope = new Core.ScopeDbContext())
     {
         var db    = scope.GetDbContext();
         var model = db.Schedules.FirstOrDefault(x => x.Id == sid && x.Status != (int)ScheduleStatus.Deleted);
         if (model != null)
         {
             ScheduleContext context = new ScheduleContext()
             {
                 Schedule = model
             };
             if (model.MetaType == (int)ScheduleMetaType.Http)
             {
                 context.HttpOption = db.ScheduleHttpOptions.FirstOrDefault(x => x.ScheduleId == sid);
             }
             context.Keepers = (from t in db.ScheduleKeepers
                                join u in db.SystemUsers on t.UserId equals u.Id
                                where t.ScheduleId == model.Id && !string.IsNullOrEmpty(u.Email)
                                select new KeyValuePair <string, string>(u.RealName, u.Email)
                                ).ToList();
             context.Children = (from c in db.ScheduleReferences
                                 join t in db.Schedules on c.ChildId equals t.Id
                                 where c.ScheduleId == model.Id && c.ChildId != model.Id
                                 select new { t.Id, t.Title }
                                 ).ToDictionary(x => x.Id, x => x.Title);
             return(context);
         }
         throw new InvalidOperationException($"不存在的任务id:{sid}");
     }
 }
コード例 #3
0
        public static void Register()
        {
            var setting = ConfigurationCache.NodeSetting;

            using (var scope = new Core.ScopeDbContext())
            {
                bool isCreate = false;
                var  db       = scope.GetDbContext();
                var  node     = db.ServerNodes.FirstOrDefault(x => x.NodeName == setting.IdentityName);
                if (node == null)
                {
                    isCreate = true;
                    node     = new ServerNodeEntity();
                }
                node.NodeName       = setting.IdentityName;
                node.NodeType       = setting.Role;
                node.MachineName    = Environment.MachineName;
                node.AccessProtocol = setting.Protocol;
                node.Host           = $"{setting.IP}:{setting.Port}";
                node.AccessSecret   = Guid.NewGuid().ToString("n");
                node.Status         = 2;
                node.LastUpdateTime = DateTime.Now;
                if (isCreate)
                {
                    db.ServerNodes.Add(node);
                }
                db.SaveChanges();
            }
        }
コード例 #4
0
        /// <summary>
        /// 更新节点状态
        /// </summary>
        /// <param name="isStarted"></param>
        /// <param name="isOnStop"></param>
        private static void MarkNode(bool isStarted, bool isOnStop = false)
        {
            var setting = ConfigurationCache.NodeSetting;

            using (var scope = new Core.ScopeDbContext())
            {
                bool isCreate = false;
                var  db       = scope.GetDbContext();
                var  node     = db.ServerNodes.FirstOrDefault(x => x.NodeName == setting.IdentityName);
                if (isStarted)
                {
                    if (node == null)
                    {
                        isCreate = true;
                        node     = new ServerNodeEntity();
                    }
                    string secret = Guid.NewGuid().ToString("n");
                    node.NodeName       = setting.IdentityName;
                    node.NodeType       = setting.Role;
                    node.MachineName    = setting.MachineName;
                    node.AccessProtocol = setting.Protocol;
                    node.Host           = $"{setting.IP}:{setting.Port}";
                    node.Priority       = setting.Priority;
                    node.MaxConcurrency = setting.MaxConcurrency;
                    node.Status         = 2;
                    node.AccessSecret   = secret;
                    if (isCreate)
                    {
                        db.ServerNodes.Add(node);
                    }
                    else
                    {
                        db.ServerNodes.Update(node);
                    }
                    if (db.SaveChanges() > 0)
                    {
                        AccessSecret = secret;
                    }
                }
                else
                {
                    if (node != null)
                    {
                        node.Status       = isOnStop ? 0 : 1;
                        node.AccessSecret = null;
                        db.ServerNodes.Update(node);
                        if (db.SaveChanges() > 0)
                        {
                            AccessSecret = string.Empty;
                        }
                    }
                    //释放锁
                    db.Database.ExecuteSqlRaw(
                        $"update schedulelocks set status=0,lockedtime=null,lockednode=null where status=1 and lockednode='{setting.IdentityName}'");
                }
            }
        }
コード例 #5
0
 public static void Shutdown()
 {
     using (var scope = new Core.ScopeDbContext())
     {
         var db   = scope.GetDbContext();
         var node = db.ServerNodes.FirstOrDefault(x => x.NodeName == ConfigurationCache.NodeSetting.IdentityName);
         if (node != null)
         {
             node.Status = 0;
             db.SaveChanges();
         }
     }
 }
コード例 #6
0
        /// <summary>
        /// 根据任务id插入
        /// </summary>
        /// <param name="sid"></param>
        /// <returns></returns>
        public static async Task <bool> InsertById(Guid sid)
        {
            bool success = false;

            using (var scope = new Core.ScopeDbContext())
            {
                var entity = await scope.GetDbContext().ScheduleDelayeds.FirstOrDefaultAsync(x => x.Id == sid && x.Status != (int)ScheduleDelayStatus.Ready);

                if (entity != null)
                {
                    return(InsertByEntity(entity));
                }
            }
            return(success);
        }
コード例 #7
0
 /// <summary>
 /// 节点恢复就绪任务
 /// </summary>
 private static void ReadyRecovery()
 {
     using (var scope = new Core.ScopeDbContext())
     {
         var db = scope.GetDbContext();
         List <ScheduleDelayedEntity> list = (from t in db.ScheduleDelayeds
                                              join e in db.ScheduleExecutors on t.Id equals e.ScheduleId
                                              where e.WorkerName == ConfigurationCache.NodeSetting.IdentityName && t.Status == (int)ScheduleDelayStatus.Ready
                                              select t).ToList();
         list.AsParallel().ForAll(t =>
         {
             InsertByEntity(t);
         });
     }
 }
コード例 #8
0
 private static void StartedEvent(Guid sid, DateTime?nextRunTime)
 {
     using (var scope = new Core.ScopeDbContext())
     {
         var db = scope.GetDbContext();
         //每次运行成功后更新任务的运行情况
         var task = db.Schedules.FirstOrDefault(x => x.Id == sid);
         if (task == null)
         {
             return;
         }
         task.LastRunTime    = DateTime.Now;
         task.NextRunTime    = nextRunTime;
         task.TotalRunCount += 1;
         db.SaveChanges();
     }
 }
コード例 #9
0
        /// <summary>
        /// 更新节点状态
        /// </summary>
        /// <param name="isStarted"></param>
        /// <param name="isOnStop"></param>
        private static void MarkNode(bool isStarted, bool isOnStop = false)
        {
            var setting = ConfigurationCache.NodeSetting;

            using (var scope = new Core.ScopeDbContext())
            {
                bool isCreate = false;
                var  db       = scope.GetDbContext();
                var  node     = db.ServerNodes.FirstOrDefault(x => x.NodeName == setting.IdentityName);
                if (isStarted)
                {
                    if (node == null)
                    {
                        isCreate = true;
                        node     = new ServerNodeEntity();
                    }
                    node.NodeName       = setting.IdentityName;
                    node.NodeType       = setting.Role;
                    node.MachineName    = Environment.MachineName;
                    node.AccessProtocol = setting.Protocol;
                    node.Host           = $"{setting.IP}:{setting.Port}";
                    node.Priority       = setting.Priority;
                    node.Status         = 2;
                    node.AccessSecret   = Guid.NewGuid().ToString("n");
                    if (isCreate)
                    {
                        db.ServerNodes.Add(node);
                    }
                }
                else
                {
                    if (node != null)
                    {
                        node.Status = isOnStop ? 0 : 1;
                        if (isOnStop)
                        {
                            node.AccessSecret = null;
                        }
                    }
                }
                if (db.SaveChanges() > 0)
                {
                    AccessSecret = node.AccessSecret;
                }
            }
        }
コード例 #10
0
        /// <summary>
        /// 根据条件删除日志
        /// </summary>
        /// <param name="sid"></param>
        /// <param name="category"></param>
        /// <param name="startdate"></param>
        /// <param name="enddate"></param>
        /// <returns></returns>
        public async Task <int> DeleteLog(Guid?sid, int?category, DateTime?startdate, DateTime?enddate)
        {
            IQueryable <SystemLogEntity> query = _repositoryFactory.SystemLogs.Table;
            StringBuilder sqlBulder            = new StringBuilder("delete from systemlogs where 1=1 ");

            if (sid.HasValue)
            {
                query = query.Where(x => x.ScheduleId == sid.Value);
                sqlBulder.Append($"and scheduleid='{sid.Value}' ");
            }
            if (category.HasValue)
            {
                query = query.Where(x => x.Category == category.Value);
                sqlBulder.Append($"and category={category.Value} ");
            }
            if (startdate.HasValue)
            {
                query = query.Where(x => x.CreateTime >= startdate.Value);
                sqlBulder.Append($"and createtime>='{startdate.Value.ToString("yyyy-MM-dd")}' ");
            }
            if (enddate.HasValue)
            {
                query = query.Where(x => x.CreateTime < enddate.Value);
                sqlBulder.Append($"and createtime<'{enddate.Value.ToString("yyyy-MM-dd")}' ");
            }
            int rows = await query.CountAsync();

            _ = Task.Run(() =>
            {
                using (var scope = new Core.ScopeDbContext())
                {
                    scope.GetDbContext().Database.ExecuteSqlRaw(sqlBulder.ToString());
                }
            });
            return(rows);
        }
コード例 #11
0
        private static async Task Start(IHosSchedule schedule)
        {
            JobDataMap map = new JobDataMap
            {
                new KeyValuePair <string, object> ("instance", schedule),
            };
            string jobKey = schedule.Main.Id.ToString();

            try
            {
                IJobDetail job = JobBuilder.Create().OfType(schedule.GetQuartzJobType()).WithIdentity(jobKey).UsingJobData(map).Build();

                //添加监听器
                var listener = new JobRunListener(jobKey);
                listener.OnSuccess += StartedEvent;
                _scheduler.ListenerManager.AddJobListener(listener, KeyMatcher <JobKey> .KeyEquals(new JobKey(jobKey)));

                ITrigger trigger = GetTrigger(schedule.Main);
                await _scheduler.ScheduleJob(job, trigger, schedule.CancellationTokenSource.Token);

                using (var scope = new Core.ScopeDbContext())
                {
                    var db   = scope.GetDbContext();
                    var task = db.Schedules.FirstOrDefault(x => x.Id == schedule.Main.Id);
                    if (task != null)
                    {
                        task.NextRunTime = TimeZoneInfo.ConvertTimeFromUtc(trigger.GetNextFireTimeUtc().Value.UtcDateTime, TimeZoneInfo.Local);
                        await db.SaveChangesAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new SchedulerException(ex);
            }
            LogHelper.Info($"任务[{schedule.Main.Title}]启动成功!", schedule.Main.Id);

            _ = Task.Run(async() =>
            {
                while (true)
                {
                    if (schedule.RunnableInstance == null)
                    {
                        break;
                    }
                    var log = schedule.RunnableInstance.ReadLog();
                    if (log != null)
                    {
                        LogManager.Queue.Write(new SystemLogEntity
                        {
                            Category   = log.Category,
                            Message    = log.Message,
                            ScheduleId = log.ScheduleId,
                            Node       = log.Node,
                            StackTrace = log.StackTrace,
                            TraceId    = log.TraceId,
                            CreateTime = log.CreateTime
                        });
                    }
                    else
                    {
                        await Task.Delay(3000);
                    }
                }
            });
        }
コード例 #12
0
        /// <summary>
        /// worker健康检查
        /// </summary>
        public void WorkerHealthCheck()
        {
            var workers = _repositoryFactory.ServerNodes.Where(x => x.NodeType == "worker" && x.Status != 0).ToList();

            if (!workers.Any())
            {
                return;
            }
            //允许最大失败次数
            int allowMaxFailed = ConfigurationCache.GetField <int>("System_WorkerUnHealthTimes");

            if (allowMaxFailed <= 0)
            {
                allowMaxFailed = 3;
            }
            //遍历处理
            workers.ForEach(async(w) =>
            {
                using (var scope = new Core.ScopeDbContext())
                {
                    var db = scope.GetDbContext();
                    _serverClient.Server = w;
                    //初始化计数器
                    ConfigurationCache.WorkerUnHealthCounter.TryAdd(w.NodeName, 0);
                    var success = await _serverClient.HealthCheck();
                    if (success)
                    {
                        w.LastUpdateTime = DateTime.Now;
                        db.ServerNodes.Update(w);
                        await db.SaveChangesAsync();
                        ConfigurationCache.WorkerUnHealthCounter[w.NodeName] = 0;
                    }
                    else
                    {
                        //获取已失败次数
                        int failedCount = ConfigurationCache.WorkerUnHealthCounter[w.NodeName];
                        System.Threading.Interlocked.Increment(ref failedCount);
                        if (failedCount >= allowMaxFailed)
                        {
                            w.Status = 0;//标记下线,实际上可能存在因为网络抖动等原因导致检查失败但worker进程还在运行的情况
                            db.ServerNodes.Update(w);
                            //释放该节点占据的锁
                            var locks = db.ScheduleLocks.Where(x => x.LockedNode == w.NodeName && x.Status == 1).ToList();
                            locks.ForEach(x =>
                            {
                                x.Status     = 0;
                                x.LockedNode = null;
                                x.LockedTime = null;
                            });
                            db.ScheduleLocks.UpdateRange(locks);
                            await db.SaveChangesAsync();
                            //重置计数器
                            ConfigurationCache.WorkerUnHealthCounter[w.NodeName] = 0;
                        }
                        else
                        {
                            ConfigurationCache.WorkerUnHealthCounter[w.NodeName] = failedCount;
                        }
                    }
                }
            });
        }