Example #1
0
        public async Task <Result <JobTaskStatus> > StartJobTask(long sid)
        {
            var result = new Result <JobTaskStatus> {
                Message = "启动任务成功!"
            };

            try
            {
                result = await StartWithRetry(sid);

                if (result.Success && result.Data != JobTaskStatus.Running)
                {
                    using var _quartzDao = new QuartzDao();
                    var isOk = await _quartzDao.UpdateJobTaskStatusAsync(sid, JobTaskStatus.Running);

                    result.Data = isOk ? JobTaskStatus.Running : result.Data;
                }
            }
            catch (Exception ex)
            {
                result.Success     = false;
                result.Message     = $"节点[{CoreGlobal.NodeSetting.NodeName}]任务调度平台启动任务失败!";
                result.ErrorDetail = ex.Message;
                _logger.LogError(ex, $"节点[{CoreGlobal.NodeSetting.NodeName}]任务调度平台启动任务失败!");
            }
            return(result);
        }
Example #2
0
        private async Task RunningRecoveryAsync()
        {
            //任务恢复:查找那些绑定了本节点并且在状态是运行中的任务执行启动操作
            using var _quartzDao = new QuartzDao();
            var list = await _quartzDao.QueryRunningJobTaskIdsAsync(CoreGlobal.NodeSetting.NodeName);

            _logger.LogInformation($"[{CoreGlobal.NodeSetting.NodeName}]任务恢复 {list.ToJson()}");
            list?.AsParallel().ForAll(async sid => await StartWithRetry(sid));
        }
Example #3
0
        private async Task LoadPluginFile(QuartzDao _quartzDao, JobTasksEntity model)
        {
            var master = await _quartzDao.QueryJobNodeByTypeAsync("master");

            if (master == null)
            {
                throw new InvalidOperationException("cannot find master.");
            }
            //var sourcePath = Path.Combine(Environment.CurrentDirectory, "wwwroot", "tasks", model.AssemblyName);
        }
Example #4
0
        /// <summary>
        /// 更新节点状态
        /// </summary>
        /// <param name="isStarted"></param>
        /// <param name="isOnStop"></param>
        private async Task MarkNodeAsync(bool isStarted, bool isOnStop = false)
        {
            using var _quartzDao = new QuartzDao();
            bool isCreate = false;
            bool isSave   = false;
            var  node     = await _quartzDao.QueryJobNodeByIdAsync(CoreGlobal.NodeSetting.NodeName);

            if (isStarted)
            {
                if (node == null)
                {
                    isCreate     = true;
                    node         = new JobNodesEntity();
                    node.GenerID = (await _quartzDao.QueryJobNodeMaxGId()) + 1;
                }
                node.NodeName       = CoreGlobal.NodeSetting.NodeName;
                node.NodeType       = CoreGlobal.NodeSetting.NodeType;
                node.MachineName    = Environment.MachineName;
                node.AccessProtocol = CoreGlobal.NodeSetting.Protocol;
                node.Host           = $"{CoreGlobal.NodeSetting.IP}:{CoreGlobal.NodeSetting.Port}";
                node.Priority       = CoreGlobal.NodeSetting.Priority;
                node.Status         = NodeStatus.Run;
                node.AccessSecret   = Guid.NewGuid().ToString("n");
                node.LastUpdateTime = DateTime.Now;
                isSave = await _quartzDao.UpdateJobNodeStatusAsync(node) > 0;

                if (isCreate)
                {
                    await _quartzDao.AddJobNodeAsync(node);
                }
            }
            else
            {
                if (node != null)
                {
                    node.Status = isOnStop ? NodeStatus.Down : NodeStatus.Off;
                    isSave      = await _quartzDao.UpdateJobNodeStatusAsync(node) > 0;

                    if (isOnStop)
                    {
                        node.AccessSecret = null;
                    }
                }
            }
            if (isSave)
            {
                AccessSecret = node.AccessSecret;
            }
            CoreGlobal.NodeSetting.AccessSecret = AccessSecret;
            CoreGlobal.Generator = new Generator((short)node.GenerID, DateTime.Today);
        }
Example #5
0
        private async Task StartedEventAsync(long sid, DateTime?nextRunTime)
        {
            using var _quartzDao = new QuartzDao();
            //每次运行成功后更新任务的运行情况
            var task = await _quartzDao.QueryJobTaskAsync(sid);

            if (task == null)
            {
                return;
            }
            task.LastRunTime    = DateTime.Now;
            task.NextRunTime    = nextRunTime;
            task.TotalRunCount += 1;
            await _quartzDao.UpdateJobTaskAsync(task);
        }
Example #6
0
        private async Task <JobTaskView> GetJobTaskViewAsync(long sid)
        {
            using var _quartzDao = new QuartzDao();
            var model = await _quartzDao.QueryJobTaskAsync(sid);

            if (model != null)
            {
                JobTaskView view = new JobTaskView()
                {
                    JobTask = model
                };

                //await LoadPluginFile(_quartzDao, model);
                return(view);
            }
            throw new InvalidOperationException($"不存在的任务id:{sid}");
        }
Example #7
0
        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                using var _quartzDao = new QuartzDao();

                var stoppedList = await _quartzDao.QueryStopJobTaskIdsAsync(CoreGlobal.NodeSetting.NodeName);

                foreach (var sid in stoppedList)
                {
                    var result = await Stop(sid, context.Scheduler);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"节点[{CoreGlobal.NodeSetting.NodeName}]任务调度平台清理失败!{ex.Message}");
            }
        }
Example #8
0
        /// <summary>
        ///立即运行一次任务
        /// </summary>
        /// <param name="sid"></param>
        public async Task <Result <ResultStatus> > RunOnceTask(long sid)
        {
            var result = new Result <ResultStatus> {
                Data = ResultStatus.Success, Message = $"运行一次成功!"
            };

            try
            {
                using var _quartzDao = new QuartzDao();
                var task = await _quartzDao.QueryJobTaskAsync(sid);

                if (task == null)
                {
                    result.Data    = ResultStatus.Failed;
                    result.Success = false;
                    result.Message = "任务不存在!";
                    return(result);
                }
                if (task.Status != JobTaskStatus.Running)
                {
                    result.Data    = ResultStatus.Failed;
                    result.Success = false;
                    result.Message = "在运行状态下才能运行一次任务!";
                    return(result);
                }
                var ret = await RunOnce(sid);

                if (ret.Success)
                {
                    var isOk = await _quartzDao.UpdateJobTaskStatusAsync(sid, task.Status, count : 1);

                    result.Data    = isOk ? ResultStatus.Success : ResultStatus.Failed;
                    result.Message = $"运行一次任务{(isOk ? "成功" : "失败")}!";
                }
            }
            catch (Exception exp)
            {
                _logger.LogError(exp, $"节点[{CoreGlobal.NodeSetting.NodeName}][({sid})]运行一次任务失败!");
                result.Success     = false;
                result.Message     = $"运行一次任务失败";
                result.ErrorDetail = exp.Message;
            }
            return(result);
        }
Example #9
0
        /// <summary>
        /// 停止一个任务
        /// </summary>
        /// <param name="sid"></param>
        /// <returns></returns>
        public async Task <Result <JobTaskStatus> > StopTask(long sid)
        {
            var result = new Result <JobTaskStatus>();

            try
            {
                using var _quartzDao = new QuartzDao();
                var task = await _quartzDao.QueryJobTaskAsync(sid);

                if (task == null)
                {
                    result.Success = false;
                    result.Message = $"任务不存在!";
                    return(result);
                }
                result.Data = task.Status;
                if (task.Status <= JobTaskStatus.Stop)
                {
                    result.Success = false;
                    result.Message = "大于停止状态下才能恢复运行!";
                    return(result);
                }

                var ret = await Stop(sid);

                if (ret.Success)
                {
                    var isOk = await _quartzDao.UpdateJobTaskStatusAsync(sid, JobTaskStatus.Stop, true);

                    result.Data    = isOk ? JobTaskStatus.Stop : result.Data;
                    result.Message = $"停止运行任务成功!任务状态:[{result.Data.GetDescription()}]";
                }
            }
            catch (Exception exp)
            {
                _logger.LogError(exp, $"节点[{CoreGlobal.NodeSetting.NodeName}][({sid})]停止运行任务失败!");
                result.Success     = false;
                result.Message     = $"停止运行任务失败!任务状态:[{result.Data.GetDescription()}]";
                result.ErrorDetail = exp.Message;
            }
            return(result);
        }
Example #10
0
        /// <summary>
        /// 暂停一个任务
        /// </summary>
        /// <param name="sid"></param>
        /// <returns></returns>
        public async Task <Result <JobTaskStatus> > PauseTask(long sid)
        {
            var result = new Result <JobTaskStatus>();

            try
            {
                using var _quartzDao = new QuartzDao();
                var task = await _quartzDao.QueryJobTaskAsync(sid);

                if (task == null)
                {
                    result.Success = false;
                    result.Message = $"任务不存在!";
                    return(result);
                }
                result.Data = task.Status;
                if (task.Status != JobTaskStatus.Running)
                {
                    result.Success = false;
                    result.Message = "在运行状态下才能暂停任务!";
                    return(result);
                }

                var ret = await Pause(sid);

                if (ret.Success)
                {
                    var isOk = await _quartzDao.UpdateJobTaskStatusAsync(sid, JobTaskStatus.Paused, true);

                    result.Data    = isOk ? JobTaskStatus.Paused : result.Data;
                    result.Message = $"暂停成功!任务状态:[{result.Data.GetDescription()}]";
                }
            }
            catch (Exception exp)
            {
                _logger.LogError(exp, $"节点[{CoreGlobal.NodeSetting.NodeName}][({sid})]任务暂停运行失败!");
                result.Success     = false;
                result.Message     = $"暂停失败!任务状态:[{result.Data.GetDescription()}]";
                result.ErrorDetail = exp.Message;
            }
            return(result);
        }
Example #11
0
        public async Task Execute(IJobExecutionContext context)
        {
            _sid = long.Parse(context.JobDetail.Key.Name);
            using (var _quartzDao = new QuartzDao())
            {
                var getLocked = true;
                if (getLocked)
                {
                    IJobDetail job = context.JobDetail;
                    _logger.LogInformation($"节点[{node}] 准备执行任务[{job.JobDataMap["name"]}({_sid})]....");
                    try
                    {
                        if (job.JobDataMap["instance"] is TaskBase instance)
                        {
                            long traceId = await _quartzDao.GreateRunTrace(_sid, node);

                            Stopwatch   stopwatch = new Stopwatch();
                            TaskContext tctx      = new TaskContext(instance)
                            {
                                NodeName   = node,
                                Title      = $"{job.JobDataMap["name"]}",
                                TaskId     = _sid,
                                TraceId    = traceId,
                                ParamsDict = job.JobDataMap["params"] as Dictionary <string, object>
                            };
                            if (context.MergedJobDataMap["PreviousResult"] is object prev)
                            {
                                tctx.PreviousResult = prev;
                            }
                            try
                            {
                                stopwatch.Restart();
                                await instance.InnerRun(tctx);

                                stopwatch.Stop();
                                await _quartzDao.UpdateRunTrace(traceId, Math.Round(stopwatch.Elapsed.TotalSeconds, 3), Contract.Models.TaskRunResult.Success);

                                _logger.LogInformation($"任务[{job.JobDataMap["name"]}({_sid})]运行成功!{traceId} 用时{stopwatch.Elapsed.TotalMilliseconds.ToString()}ms");
                                //保存运行结果用于子任务触发
                                context.Result = tctx.Result;
                            }
                            catch (RunConflictException conflict)
                            {
                                stopwatch.Stop();
                                await _quartzDao.UpdateRunTrace(traceId, Math.Round(stopwatch.Elapsed.TotalSeconds, 3), Contract.Models.TaskRunResult.Conflict);

                                throw conflict;
                            }
                            catch (Exception e)
                            {
                                stopwatch.Stop();
                                await _quartzDao.UpdateRunTrace(traceId, Math.Round(stopwatch.Elapsed.TotalSeconds, 3), Contract.Models.TaskRunResult.Failed);

                                _logger.LogError(e, $"任务[{job.JobDataMap["name"]}({_sid})]运行失败!{traceId} ");
                                //这里抛出的异常会在JobListener的JobWasExecuted事件中接住
                                //如果吃掉异常会导致程序误以为本次任务执行成功
                                throw new BusinessRunException(e);
                            }
                        }
                    }
                    finally
                    {
                        //为了避免各节点之间的时间差,延迟1秒释放锁
                        System.Threading.Thread.Sleep(1000);
                    }
                }
                else
                {
                    //LogHelper.Info($"节点{node}抢锁失败!", _sid);
                    //throw new JobExecutionException("lock_failed");
                }
            }
            //return Task.FromResult(0);
        }