示例#1
0
        /// <summary>
        /// 添加后台作业
        /// </summary>
        /// <param name="jobItem"></param>
        /// <returns></returns>
        public string AddHttpbackgroundjob(HttpJobItem jobItem)
        {
            try
            {
                var queueName = !string.IsNullOrEmpty(jobItem.AgentClass) ? "JobAgent" : jobItem.QueueName;
                if (string.IsNullOrEmpty(queueName))
                {
                    queueName = EnqueuedState.DefaultQueue;
                }

                if (!string.IsNullOrEmpty(jobItem.RunAt))
                {
                    //如果设置了 指定的运行时间 先parse一下
                    if (DateTimeOffset.TryParse(jobItem.RunAt, out var runAtTime))
                    {
                        return(BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), runAtTime));
                    }
                }

                if (jobItem.DelayFromMinutes <= 0)
                {
                    return(BackgroundJob.Enqueue(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null)));
                }

                return(BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null),
                                              TimeSpan.FromMinutes(jobItem.DelayFromMinutes)));
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.AddHttpbackgroundjob", ex);
                return(null);
            }
        }
示例#2
0
        /// <summary>
        /// 添加周期性作业
        /// </summary>
        /// <param name="jobItem"></param>
        /// <param name="timeZone">job 时区信息</param>
        /// <returns></returns>
        public bool AddHttprecurringjob(HttpJobItem jobItem)
        {
            if (string.IsNullOrEmpty(jobItem.QueueName))
            {
                jobItem.QueueName = EnqueuedState.DefaultQueue;
            }
            else
            {
                //get queues from server
                // ReSharper disable once ReplaceWithSingleCallToFirstOrDefault
                var server = JobStorage.Current.GetMonitoringApi().Servers().Where(p => p.Queues.Count > 0).FirstOrDefault();
                // ReSharper disable once PossibleNullReferenceException
                var queues = server.Queues.ToList();
                if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0)
                {
                    Logger.Warn($"HttpJobDispatcher.AddHttprecurringjob Error => HttpJobItem.QueueName:`{jobItem.QueueName}` not exist, Use DEFAULT extend!");
                }
            }

            var queueName = !string.IsNullOrEmpty(jobItem.AgentClass) ? "JobAgent" : jobItem.QueueName;

            if (string.IsNullOrEmpty(queueName))
            {
                queueName = EnqueuedState.DefaultQueue;
            }


            try
            {
                // 先用每个job配置的 如果没有就用系统配置的 在没有就用Local
                TimeZoneInfo timeZone = null;
                if (!string.IsNullOrEmpty(jobItem.TimeZone))
                {
                    timeZone = TimeZoneInfoHelper.OlsonTimeZoneToTimeZoneInfo(jobItem.TimeZone);
                }

                if (timeZone == null)
                {
                    timeZone = CodingUtil.HangfireHttpJobOptions.RecurringJobTimeZone ?? TimeZoneInfo.Local;
                }
                if (string.IsNullOrEmpty(jobItem.Cron))
                {
                    //支持添加一个 只能手动出发的
                    RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), Cron.Never,
                                             timeZone, jobItem.QueueName.ToLower());
                    return(true);
                }

                RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), jobItem.Cron,
                                         timeZone, jobItem.QueueName.ToLower());
                return(true);
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex);
                return(false);
            }
        }
示例#3
0
 /// <summary>
 /// 添加后台作业
 /// </summary>
 /// <param name="jobItem"></param>
 /// <returns></returns>
 public bool AddHttpbackgroundjob(HttpJobItem jobItem)
 {
     try
     {
         BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName, jobItem.QueueName, jobItem.IsRetry, null), TimeSpan.FromMinutes(jobItem.DelayFromMinutes));
         return(true);
     }
     catch (Exception ex)
     {
         Logger.ErrorException("HttpJobDispatcher.AddHttpbackgroundjob", ex);
         return(false);
     }
 }
示例#4
0
 /// <summary>
 /// 添加周期性作业
 /// </summary>
 /// <param name="jobItem"></param>
 /// <returns></returns>
 public bool AddHttprecurringjob(HttpJobItem jobItem)
 {
     try
     {
         RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, null), jobItem.Corn, TimeZoneInfo.Local);
         return(true);
     }
     catch (Exception ex)
     {
         Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex);
         return(false);
     }
 }
示例#5
0
        /// <summary>
        /// 添加后台作业
        /// </summary>
        /// <param name="jobItem"></param>
        /// <returns></returns>
        public string AddHttpbackgroundjob(HttpJobItem jobItem)
        {
            try
            {
                if (string.IsNullOrEmpty(jobItem.QueueName))
                {
                    jobItem.QueueName = EnqueuedState.DefaultQueue;
                }
                else
                {
                    //get queues from server
                    // ReSharper disable once ReplaceWithSingleCallToFirstOrDefault
                    var server = JobStorage.Current.GetMonitoringApi().Servers().Where(p => p.Queues.Count > 0).FirstOrDefault();
                    // ReSharper disable once PossibleNullReferenceException
                    if (server == null)
                    {
                        return("active server not exist!");
                    }
                    var queues = server.Queues.Select(m => m.ToLower()).ToList();
                    if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0)
                    {
                        Logger.Warn($"HttpJobDispatcher.AddHttpbackgroundjob Error => HttpJobItem.QueueName:`{jobItem.QueueName}` not exist, Use DEFAULT extend!");
                        jobItem.QueueName = EnqueuedState.DefaultQueue;
                    }
                }

                if (!string.IsNullOrEmpty(jobItem.RunAt))
                {
                    //如果设置了 指定的运行时间 先parse一下
                    if (DateTimeOffset.TryParse(jobItem.RunAt, out var runAtTime))
                    {
                        return(BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, null, null, false, null), runAtTime));
                    }
                }

                if (jobItem.DelayFromMinutes <= 0)
                {
                    return(BackgroundJob.Enqueue(() => HttpJob.Excute(jobItem, null, null, false, null)));
                }

                return(BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, null, null, false, null),
                                              TimeSpan.FromMinutes(jobItem.DelayFromMinutes)));
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.AddHttpbackgroundjob", ex);
                return(null);
            }
        }
        /// <summary>
        /// 添加周期性作业
        /// </summary>
        /// <param name="jobItem"></param>
        /// <returns></returns>
        public bool AddHttprecurringjob(HttpJobItem jobItem)
        {
            if (string.IsNullOrEmpty(jobItem.QueueName))
            {
                jobItem.QueueName = "DEFAULT";
            }
            else
            {
                //get queues from server
                // ReSharper disable once ReplaceWithSingleCallToFirstOrDefault
                var server = JobStorage.Current.GetMonitoringApi().Servers().Where(p => p.Queues.Count > 0).FirstOrDefault();
                // ReSharper disable once PossibleNullReferenceException
                var queues = server.Queues.ToList();
                if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0)
                {
                    Logger.Warn("HttpJobDispatcher.AddHttprecurringjob Error => HttpJobItem.QueueName not exist, Use DEFAULT extend!");
                }
            }

            var queueName = !string.IsNullOrEmpty(jobItem.AgentClass) ? "JobAgent" : jobItem.QueueName;

            if (string.IsNullOrEmpty(queueName))
            {
                queueName = "DEFAULT";
            }


            try
            {
                //支持添加一个 只能手动出发的
                if (string.IsNullOrEmpty(jobItem.Cron))
                {
                    RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), Cron.Never, TimeZoneInfo.Local, jobItem.QueueName.ToLower());
                    return(true);
                }

                RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), jobItem.Cron, TimeZoneInfo.Local, jobItem.QueueName.ToLower());
                return(true);
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex);
                return(false);
            }
        }
        public bool AddHttpbackgroundjob(HttpJobItem jobItem)
        {
            try
            {
                // 普通作业
                // 单纯的httpjob 有设置延迟
                // 单纯的httpjob 没有设置延迟  但是不可以不设置延迟 所以就设置一个非常大的延迟 比如100年后
                // 以agent模式开发的job 有设置延迟
                // 以agent模式开发的job 没有设置延迟
                // 没有设置延迟 代表的只可以自己触发
                var queueName = !string.IsNullOrEmpty(jobItem.AgentClass) ? "JobAgent" : jobItem.QueueName;
                if (string.IsNullOrEmpty(queueName))
                {
                    queueName = "DEFAULT";
                }
                if (jobItem.DelayFromMinutes == -1) //约定
                {
                    //代表设置的是智能自己触发的延迟job
                    var jobId = BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName + (!string.IsNullOrEmpty(jobItem.AgentClass) ? "| JobAgent |" : ""), "multiple", jobItem.EnableRetry, null), DateTimeOffset.Now.AddYears(100));

                    //自己触发完成后再把自己添加一遍
                    BackgroundJob.ContinueJobWith(jobId, () => AddHttpbackgroundjob(jobItem), JobContinuationOptions.OnAnyFinishedState);
                    return(true);
                }

                if (jobItem.DelayFromMinutes == 0)
                {
                    BackgroundJob.Enqueue(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null));
                    return(true);
                }

                BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), TimeSpan.FromMinutes(jobItem.DelayFromMinutes));
                return(true);
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.AddHttpbackgroundjob", ex);
                return(false);
            }
        }
示例#8
0
        /// <summary>
        /// 添加周期性作业
        /// </summary>
        /// <param name="jobItem"></param>
        /// <returns></returns>
        public bool AddHttprecurringjob(HttpJobItem jobItem)
        {
            //get queues from server
            var server = JobStorage.Current.GetMonitoringApi().Servers().
                         Where(p => p.Queues.Count > 0).FirstOrDefault();
            var queues = server.Queues.ToList();

            if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0)
            {
                return(false);
            }
            try
            {
                RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, jobItem.QueueName, jobItem.IsRetry, null), jobItem.Corn, TimeZoneInfo.Local, jobItem.QueueName.ToLower());
                return(true);
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex);
                return(false);
            }
        }
示例#9
0
        /// <summary>
        /// 获取jobAgent类型的JobInfo
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private async Task <JobDetailInfo> GetBackGroundJobDetail(DashboardContext context)
        {
            var jobItem = await GetRequestBody <HttpJobItem>(context);

            var result  = new JobDetailInfo();
            var jobName = string.Empty;

            try
            {
                using (var connection = JobStorage.Current.GetConnection())
                {
                    Job job = null;

                    if (string.IsNullOrEmpty(jobItem.Cron))
                    {
                        var jobData = connection.GetJobData(jobItem.JobName);
                        if (jobData == null)
                        {
                            result.Info = "GetJobDetail Error:can not found job by id:" + jobItem.JobName;
                            return(result);
                        }

                        job = jobData.Job;
                    }
                    else
                    {
                        Dictionary <string, string> dictionary = connection.GetAllEntriesFromHash("recurring-job:" + jobItem.JobName);
                        if (dictionary == null || dictionary.Count == 0)
                        {
                            result.Info = "GetJobDetail Error:can not found job by id:" + jobItem.JobName;
                            return(result);
                        }

                        if (!dictionary.TryGetValue(nameof(Job), out var jobDetail))
                        {
                            result.Info = "GetJobDetail Error:can not found job by id:" + jobItem.JobName;
                            return(result);
                        }

                        job = InvocationData.DeserializePayload(jobDetail).DeserializeJob();
                    }
                    var jobItem2    = job.Args.FirstOrDefault();
                    var httpJobItem = jobItem2 as HttpJobItem;
                    if (httpJobItem == null)
                    {
                        result.Info = $"GetJobDetail Error:jobData can not found job by id:" + jobItem.JobName;
                        return(result);
                    }

                    result.JobName = jobName = httpJobItem.JobName;
                    if (string.IsNullOrEmpty(httpJobItem.AgentClass))
                    {
                        result.Info = $"{(!string.IsNullOrEmpty(jobName) ? "【" + jobName + "】" : string.Empty)} Error:is not AgentJob! ";
                        return(result);
                    }

                    var jobInfo = HttpJob.GetAgentJobDetail(httpJobItem);
                    if (string.IsNullOrEmpty(jobInfo))
                    {
                        result.Info = $"{(!string.IsNullOrEmpty(jobName) ? "【" + jobName + "】" : string.Empty)} Error:get null info! ";
                        return(result);
                    }
                    jobInfo     = jobInfo.Replace("\r\n", "<br/>");
                    result.Info = jobInfo;
                    return(result);
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.GetBackGroundJobDetail", ex);
                result.Info = $"{(!string.IsNullOrEmpty(jobName) ? "【" + jobName + "】" : string.Empty)} GetJobDetail Error:" + ex.ToString();
                return(result);
            }
        }
示例#10
0
        /// <summary>
        /// 添加周期性作业
        /// </summary>
        /// <returns></returns>
        public string AddHttprecurringjob(HttpJobItem jobItem, bool addOnly = false)
        {
            if (string.IsNullOrEmpty(jobItem.QueueName))
            {
                jobItem.QueueName = EnqueuedState.DefaultQueue;
            }
            else
            {
                //get queues from server
                // ReSharper disable once ReplaceWithSingleCallToFirstOrDefault
                var server = JobStorage.Current.GetMonitoringApi().Servers().Where(p => p.Queues.Count > 0).FirstOrDefault();
                // ReSharper disable once PossibleNullReferenceException
                if (server == null)
                {
                    return("active server not exist!");
                }
                var queues = server.Queues.Select(m => m.ToLower()).ToList();
                if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0)
                {
                    Logger.Warn($"HttpJobDispatcher.AddHttprecurringjob Error => HttpJobItem.QueueName:`{jobItem.QueueName}` not exist, Use DEFAULT extend!");
                    jobItem.QueueName = EnqueuedState.DefaultQueue;
                }
            }

            try
            {
                // 先用每个job配置的 如果没有就用系统配置的 在没有就用Local
                TimeZoneInfo timeZone = null;
                if (!string.IsNullOrEmpty(jobItem.TimeZone))
                {
                    timeZone = TimeZoneInfoHelper.OlsonTimeZoneToTimeZoneInfo(jobItem.TimeZone);
                }

                //https://github.com/yuzd/Hangfire.HttpJob/issues/78
                var jobidentifier = string.IsNullOrEmpty(jobItem.RecurringJobIdentifier) ? jobItem.JobName : jobItem.RecurringJobIdentifier;
                if (addOnly)
                {
                    using (var connection = JobStorage.Current.GetConnection())
                    {
                        var existItem = connection.GetAllEntriesFromHash("recurring-job:" + jobidentifier);
                        if (existItem != null && existItem.Count > 0)
                        {
                            return(jobidentifier + "is registerd!");
                        }
                    }
                }

                if (timeZone == null)
                {
                    timeZone = TimeZoneInfo.Local;
                }
                if (string.IsNullOrEmpty(jobItem.Cron))
                {
                    //支持添加一个 只能手动出发的
                    RecurringJob.AddOrUpdate(jobidentifier, () => HttpJob.Excute(jobItem, null, null, false, null), Cron.Never,
                                             timeZone, jobItem.QueueName.ToLower());
                    return(string.Empty);
                }

                RecurringJob.AddOrUpdate(jobidentifier, () => HttpJob.Excute(jobItem, null, null, false, null), jobItem.Cron,
                                         timeZone, jobItem.QueueName.ToLower());
                return(string.Empty);
            }
            catch (Exception ex)
            {
                Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex);
                return(ex.Message);
            }
        }
        private static void OnVerify(object state)
        {
            mDetectionTimer.Change(-1, -1);
            try
            {
                using (var connection = JobStorage.Current.GetConnection())
                {
                    //拿到有上报的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)
                            {
                                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
            {
                // ignored
            }
            finally
            {
                mDetectionTimer.Change(1000 * 2, 1000 * 2);
            }
        }