예제 #1
0
        /// <summary>
        /// 停止或者暂停项目
        /// </summary>
        /// <param name="jobname"></param>
        /// <returns></returns>
        public string PauseOrRestartJob(string jobname)
        {
            try
            {
                using (var connection = JobStorage.Current.GetConnection())
                {
                    Dictionary <string, string> dictionary = connection.GetAllEntriesFromHash("recurring-job:" + jobname);
                    if (dictionary == null || dictionary.Count == 0)
                    {
                        return("not found recurring-job:" + jobname);
                    }

                    if (!dictionary.TryGetValue(nameof(Job), out var jobDetail))
                    {
                        return("not found recurring-job:" + jobname);
                    }

                    var RecurringJob = InvocationData.DeserializePayload(jobDetail).DeserializeJob();

                    var job = CodingUtil.FromJson <HttpJobItem>(RecurringJob.Args.FirstOrDefault()?.ToString());

                    if (job == null)
                    {
                        return("fail parse recurring-job:" + jobname);
                    }

                    using (var tran = connection.CreateWriteTransaction())
                    {
                        //拿到所有的设置
                        var conts = connection.GetAllItemsFromSet($"JobPauseOf:{jobname}");

                        //有就先清掉
                        foreach (var pair in conts)
                        {
                            tran.RemoveFromSet($"JobPauseOf:{jobname}", pair);
                        }

                        var cron = conts.FirstOrDefault(r => r.StartsWith("Cron:"));
                        if (!string.IsNullOrEmpty(cron))
                        {
                            cron = cron.Replace("Cron:", "");
                        }
                        //如果包含有true 的 说明已经设置了 暂停 要把改成 启动 并且拿到 Cron 进行更新
                        if (conts.Contains("true"))
                        {
                            tran.AddToSet($"JobPauseOf:{jobname}", "false");
                            if (!string.IsNullOrEmpty(cron))
                            {
                                job.Cron = cron;
                                AddHttprecurringjob(job);
                            }
                        }
                        else
                        {
                            tran.AddToSet($"JobPauseOf:{jobname}", "true");
                            tran.AddToSet($"JobPauseOf:{jobname}", "Cron:" + job.Cron);
                            job.Cron = "";
                            AddHttprecurringjob(job);
                        }

                        tran.Commit();
                    }
                }

                return(string.Empty);
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.PauseOrRestartJob", ex);
                return(ex.Message);
            }
        }
        private static void OnVerify(object state)
        {
            mDetectionTimer.Change(-1, -1);
            try
            {
                using (var connection = JobStorage.Current.GetConnection())
                    using (var lockStorage = connection.AcquireDistributedLock("JobAgentServer", TimeSpan.FromSeconds(30)))//防止多个server端竞争
                    {
                        //拿到有上报的jobId集合
                        var jobIdList = connection.GetAllItemsFromSet(keyPrefix);

                        if (!jobIdList.Any())
                        {
                            return;
                        }

                        foreach (var jobId in jobIdList)
                        {
                            JobData jobData = connection.GetJobData(jobId);

                            //拿到真正的运行结果
                            var hashKey = keyPrefix + jobId;
                            var result  = connection.GetAllEntriesFromHash(hashKey);
                            using (var tran = connection.CreateWriteTransaction())
                            {
                                //job已经不存在了 就直接删除set
                                if (jobData == null)
                                {
                                    tran.RemoveFromSet(keyPrefix, jobId);
                                    tran.Commit();
                                    continue;
                                }

                                double totalMilliseconds = (DateTime.UtcNow - jobData.CreatedAt).TotalMilliseconds;
                                long   latency           = (long)totalMilliseconds;

                                //如果job存在 但是没有拿到hash数据 认为成功
                                if (result == null || !result.Any())
                                {
                                    tran.SetJobState(jobId, new SucceededState(jobId, latency, latency));
                                    tran.RemoveFromSet(keyPrefix, jobId);
                                    tran.RemoveHash(hashKey);
                                    tran.Commit();
                                    continue;
                                }

                                var            resultOfAgent = result.First();
                                JobAgentResult resultData    = CodingUtil.FromJson <JobAgentResult>(resultOfAgent.Value);

                                //异常数据 认为成功
                                if (resultData == null)
                                {
                                    tran.SetJobState(jobId, new SucceededState(jobId, latency, latency));
                                    tran.RemoveFromSet(keyPrefix, jobId);
                                    tran.RemoveHash(hashKey);
                                    tran.Commit();
                                    continue;
                                }

                                //jobagent实际上运行的时长
                                long.TryParse(resultOfAgent.Key, out var realTotalMilliseconds);
                                if (realTotalMilliseconds < 1)
                                {
                                    realTotalMilliseconds = latency;
                                }
                                var isSuccess = resultData.R == "ok";
                                tran.RemoveFromSet(keyPrefix, jobId);
                                tran.RemoveHash(hashKey);

                                // latency 代表的是 从开始调度 到 实际结束 总共的时长
                                // realTotalMilliseconds 代表的是 jobagent开始执行 到 实际结束的 总共的时长
                                if (isSuccess)
                                {
                                    var currentState = connection.GetStateData(jobId);
                                    if (currentState != null && !string.IsNullOrEmpty(currentState.Name) &&
                                        currentState.Name.Equals("Failed"))
                                    {
                                        tran.AddJobState(jobId, new SucceededState(null, latency, realTotalMilliseconds));
                                    }
                                    else
                                    {
                                        new BackgroundJobClient().ChangeState(jobId, new SucceededState(null, latency, realTotalMilliseconds));
                                    }
                                }
                                else
                                {
                                    var jobItem = jobData.Job.Args.FirstOrDefault() as HttpJobItem;
                                    var ex      = new AgentJobException(jobItem.AgentClass, resultData.E);
                                    new BackgroundJobClient().ChangeState(jobId, new FailedState(ex));
                                    HttpJob.SendFail(jobId, jobItem, "AgentJobFail", ex);
                                }

                                //如果是stop上报过来的时候 记录这个job最后的执行id
                                if (!string.IsNullOrEmpty(resultData.Action) && resultData.Action.Equals("stop") && !string.IsNullOrEmpty(resultData.RunId))
                                {
                                    var jobItem    = jobData.Job.Args.FirstOrDefault() as HttpJobItem;
                                    var jobKeyName =
                                        $"recurring-job:{(!string.IsNullOrEmpty(jobItem.RecurringJobIdentifier) ? jobItem.RecurringJobIdentifier : jobItem.JobName)}";
                                    tran.SetRangeInHash(jobKeyName, new List <KeyValuePair <string, string> > {
                                        new KeyValuePair <string, string>("LastJobId", resultData.RunId)
                                    });
                                }

                                //出错的话 需要走通用的出错流程
                                tran.Commit();
                            }
                        }
                    }
            }
            catch (Exception e)
            {
                Logger.ErrorException("agent reporter fail", e);
            }
            finally
            {
                mDetectionTimer.Change(1000 * 2, 1000 * 2);
            }
        }