Example #1
0
        public void OnPerforming(PerformingContext filterContext)
        {
            //设置新的分布式锁,分布式锁会阻止两个相同的任务并发执行,用方法名称和JobName
            var jobresource = $"{filterContext.BackgroundJob.Job.Method.Name}.{filterContext.BackgroundJob.Job.Args[1]}";
            var locktimeout = TimeSpan.FromSeconds(_timeoutInSeconds);

            try
            {
                var jobItem = filterContext.BackgroundJob.Job.Args.FirstOrDefault();
                var job     = jobItem as HttpJobItem;
                var jobKey  = string.Empty;
                if (job != null)
                {
                    var isCronJob = !string.IsNullOrEmpty(job.Cron);
                    jobKey = isCronJob ? job.JobName : filterContext.BackgroundJob.Id;
                    var conts = filterContext.Connection.GetAllItemsFromSet($"JobPauseOf:{jobKey}");
                    if (conts.Contains("true"))
                    {
                        filterContext.Canceled = true;//任务被暂停不执行直接跳过
                        return;
                    }

                    if (!string.IsNullOrEmpty(job.JobName))
                    {
                        filterContext.BackgroundJob.Id.AddTags(job.JobName);
                    }
                }

                //设置运行时被设置的参数
                try
                {
                    var hashKey        = CodingUtil.MD5(jobKey + ".runtime");
                    var excuteDataList = filterContext.Connection.GetAllEntriesFromHash(hashKey);
                    if (excuteDataList != null && excuteDataList.Any())
                    {
                        filterContext.Items.Add("runtimeKey", hashKey);
                        //一次性的数据
                        filterContext.Items.Add("runtimeKey_dic", excuteDataList);
                        foreach (var keyvalue in excuteDataList)
                        {
                            filterContext.Items.Add(keyvalue.Key, keyvalue.Value);
                        }
                    }
                }
                catch (Exception)
                {
                    //ignore
                }


                //申请分布式锁
                var distributedLock = filterContext.Connection.AcquireDistributedLock(jobresource, locktimeout);
                filterContext.Items["DistributedLock"] = distributedLock;
            }
            catch (Exception ec)
            {
                filterContext.Canceled = true;
                logger.Info($"[OnPerforming] BackgroundJob.Job.JObName:{filterContext.BackgroundJob.Job.Args[1]} AcquireDistributedLock Timeout,BackgroundJob.Id:{filterContext.BackgroundJob.Id},Exception:{ec}");
            }
        }
Example #2
0
        public void OnPerforming(PerformingContext filterContext)
        {
            var jobItem = filterContext.BackgroundJob.Job.Args.FirstOrDefault();
            var job     = jobItem as HttpJobItem;

            if (job == null)
            {
                return;
            }
            var jobKey = ((!string.IsNullOrEmpty(job.RecurringJobIdentifier) ? job.RecurringJobIdentifier : job.JobName));
            //设置新的分布式锁,分布式锁会阻止两个相同的任务并发执行,用方法名称和JobName
            var jobresource = $"{CurrentProcessId}.{jobKey}";
            var locktimeout = TimeSpan.FromSeconds(_timeoutInSeconds);

            try
            {
                if (!string.IsNullOrEmpty(job.JobName) && (TagsServiceStorage.Current != null))
                {
                    filterContext.BackgroundJob.Id.AddTags(job.JobName);

                    filterContext.BackgroundJob.Id.AddTags(job.GetUrlHost());

                    if (!string.IsNullOrEmpty(job.RecurringJobIdentifier) &&
                        !job.RecurringJobIdentifier.Equals(job.JobName))
                    {
                        filterContext.BackgroundJob.Id.AddTags(job.RecurringJobIdentifier);
                    }
                }

                //设置运行时被设置的参数
                try
                {
                    var hashKey        = CodingUtil.MD5(jobKey + ".runtime");
                    var excuteDataList = filterContext.Connection.GetAllEntriesFromHash(hashKey);
                    if (excuteDataList != null && excuteDataList.Any())
                    {
                        filterContext.Items.Add("runtimeKey", hashKey);
                        //一次性的数据
                        filterContext.Items.Add("runtimeKey_dic", excuteDataList);
                        foreach (var keyvalue in excuteDataList)
                        {
                            filterContext.Items.Add(keyvalue.Key, keyvalue.Value);
                        }
                    }
                }
                catch (Exception)
                {
                    //ignore
                }

                //申请分布式锁
                var distributedLock = filterContext.Connection.AcquireDistributedLock(jobresource, locktimeout);
                filterContext.Items["DistributedLock"] = distributedLock;
            }
            catch (Exception ec)
            {
                filterContext.Canceled = true;
                logger.Warn($"[OnPerforming] BackgroundJob.Job.JObName:{filterContext.BackgroundJob.Job.Args[1]} AcquireDistributedLock Timeout,BackgroundJob.Id:{filterContext.BackgroundJob.Id},Exception:{ec}");
            }
        }
Example #3
0
        /// <summary>
        /// 获取job的执行url页面可以查看日志等
        /// </summary>
        /// <param name="jobId"></param>
        /// <returns></returns>
        public static string GetCurrentJobDetailUrl(string jobId)
        {
            //优先使用全局配置里面的参数
            CodingUtil.GetGlobalAppsettings().TryGetValue("CurrentDomain", out var currentDomain);

            var logDetail = currentDomain != null && !string.IsNullOrEmpty(currentDomain.ToString()) ? $"{currentDomain}/jobs/details/{jobId}" : string.IsNullOrEmpty(CodingUtil.HangfireHttpJobOptions.CurrentDomain) ? $"JobId:{jobId}" : $"{CodingUtil.HangfireHttpJobOptions.CurrentDomain}/jobs/details/{jobId}";

            return(logDetail);
        }
        /// <inheritdoc />
        public void OnStateElection(ElectStateContext context)
        {
            var jobdta = context.BackgroundJob.Job.Args.FirstOrDefault();

            if (jobdta == null)
            {
                return;
            }
            var httpjob = jobdta as HttpJobItem;

            if (httpjob != null && !httpjob.EnableRetry)
            {
                return;
            }
            var failedState = context.CandidateState as FailedState;

            if (failedState == null)
            {
                // This filter accepts only failed job state.
                return;
            }
            //var job = context.BackgroundJob.Job.Args.FirstOrDefault();
            var retryAttempt = context.GetJobParameter <int>("RetryCount") + 1;

            if (retryAttempt <= Attempts)
            {
                ScheduleAgainLater(context, retryAttempt, failedState);
                return;
            }

            try
            {
                //删除Runtime数据 代表的是需要重试 但是已经重试到最大次数了
                var hashKey = CodingUtil.MD5(context.BackgroundJob.Id + ".runtime");
                context.Transaction.RemoveHash(hashKey);
            }
            catch (Exception)
            {
                //ignore
            }

            if (retryAttempt > Attempts && OnAttemptsExceeded == AttemptsExceededAction.Delete)
            {
                TransitionToDeleted(context, failedState);
            }
            else
            {
                if (LogEvents)
                {
                    _logger.ErrorException(
                        $"Failed to process the job '{context.BackgroundJob.Id}': an exception occurred.",
                        failedState.Exception);
                }
            }
        }
Example #5
0
        public void OnPerforming(PerformingContext filterContext)
        {
            var jobItem = filterContext.BackgroundJob.Job.Args.FirstOrDefault();
            var job     = jobItem as HttpJobItem;

            if (job == null)
            {
                return;
            }

            try
            {
                if (!string.IsNullOrEmpty(job.JobName) && (TagsServiceStorage.Current != null))
                {
                    filterContext.BackgroundJob.Id.AddTags(job.JobName);

                    if (!string.IsNullOrEmpty(job.RecurringJobIdentifier) &&
                        !job.RecurringJobIdentifier.Equals(job.JobName))
                    {
                        filterContext.BackgroundJob.Id.AddTags(job.RecurringJobIdentifier);
                    }
                }

                //设置运行时被设置的参数
                try
                {
                    var jobKey         = ((!string.IsNullOrEmpty(job.RecurringJobIdentifier) ? job.RecurringJobIdentifier : job.JobName));
                    var hashKey        = CodingUtil.MD5(jobKey + ".runtime");
                    var excuteDataList = filterContext.Connection.GetAllEntriesFromHash(hashKey);
                    if (excuteDataList != null && excuteDataList.Any())
                    {
                        filterContext.Items.Add("runtimeKey", hashKey);
                        //一次性的数据
                        filterContext.Items.Add("runtimeKey_dic", excuteDataList);
                        foreach (var keyvalue in excuteDataList)
                        {
                            filterContext.Items.Add(keyvalue.Key, keyvalue.Value);
                        }
                    }
                }
                catch (Exception)
                {
                    //ignore
                }
            }
            catch (Exception ec)
            {
                filterContext.Canceled = true;
                logger.Warn($"[OnPerforming] BackgroundJob.Job.JObName:{filterContext.BackgroundJob.Job.Args[1]} AcquireDistributedLock Timeout,BackgroundJob.Id:{filterContext.BackgroundJob.Id},Exception:{ec}");
            }
        }
Example #6
0
 /// <summary>
 /// 钉钉错误内容通知默认用Exception.ToString 如果这个设置为true 那么只会用Exception.Message
 /// </summary>
 /// <returns></returns>
 public static bool DingTalkErrReportSimplify()
 {
     return(CodingUtil.GetGlobalAppsettings().TryGetValue("EnableDingTalkErrReportSimplify", out var value) && value is bool dd && dd);
 }
Example #7
0
 /// <summary>
 /// JobAgent的单例模式 当没有执行完重复执行是否需要视为错误对待
 /// </summary>
 /// <returns></returns>
 public static bool IgnoreJobAgentSingletonMultExcuteError()
 {
     //优先使用全局配置里面的参数
     return(CodingUtil.GetGlobalAppsettings().TryGetValue("IgnoreJobAgentSingletonMultExcuteError", out var value) && value is bool dd && dd);
 }
Example #8
0
        public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
        {
            var globalTimeout = CodingUtil.JobTimeoutDays();

            context.JobExpirationTimeout = TimeSpan.FromDays(globalTimeout);
        }
        /// <inheritdoc />
        public void OnStateElection(ElectStateContext context)
        {
            var jobdta = context.BackgroundJob.Job.Args.FirstOrDefault();

            if (!(jobdta is HttpJobItem httpjob))
            {
                return;
            }

            if (!httpjob.EnableRetry)
            {
                return;
            }

            //如果先执行失败的话 就直接失败
            var failedState = context.CandidateState as FailedState;

            if (failedState == null)
            {
                // This filter accepts only failed job state.
                return;
            }

            var retryTimesLimit = Attempts;
            var retryAttempt    = context.GetJobParameter <int>("RetryCount") + 1;

            if (httpjob.RetryTimes > 0)
            {
                //自定义设置了超时配置
                retryTimesLimit = httpjob.RetryTimes;
            }
            if (retryAttempt <= retryTimesLimit)
            {
                ScheduleAgainLater(context, retryAttempt, retryTimesLimit, failedState);
                return;
            }

            try
            {
                var isCronJob = !string.IsNullOrEmpty(httpjob.Cron);
                var jobKey    = isCronJob ? ((!string.IsNullOrEmpty(httpjob.RecurringJobIdentifier)?httpjob.RecurringJobIdentifier:httpjob.JobName)) : context.BackgroundJob.Id;

                //删除Runtime数据 代表的是需要重试 但是已经重试到最大次数了
                var hashKey = CodingUtil.MD5(jobKey + ".runtime");
                context.Transaction.RemoveHash(hashKey);
            }
            catch (Exception)
            {
                //ignore
            }

            if (retryAttempt > retryTimesLimit && OnAttemptsExceeded == AttemptsExceededAction.Delete)
            {
                TransitionToDeleted(context, failedState);
            }
            else
            {
                if (LogEvents)
                {
                    _logger.ErrorException(
                        $"Failed to process the job '{context.BackgroundJob.Id}': an exception occurred.",
                        failedState.Exception);
                }
            }
        }