Пример #1
0
        /// <summary>
        /// 恢复job
        /// </summary>
        /// <param name="jobInfo"></param>
        public bool Resume(JobInfo jobInfo)
        {
            //TODO:这里有两种可能

            /*
             * 1.调度服务正常状态时恢复
             * 2.调度服务挂了,重启之后,恢复job.这种情况,job池是没有job的.但是jobDetail和trigger是有的,因为我们采用的是持久化调度器,因此要特殊处理.很重要
             *
             */

            lock (Locker)
            {
                //这是第2种情况,job池没有job,属于暂停后,宕机
                JobRuntimeInfo jobRuntimeInfo = null;
                if (!JobPool.ContainsKey(jobInfo.Id))
                {
                    //如果调度任务中没有该jobDetail,那么直接返回
                    IJobDetail jobDetail = GetJobDetail(jobInfo, out JobKey jobKey);
                    if (jobDetail == null)
                    {
                        return(false);
                    }

                    jobRuntimeInfo = CreateJobRuntimeInfo(jobInfo);
                    //如果该job实例添加失败,卸载appdomain,然后返回.
                    if (!JobPool.TryAdd(jobInfo.Id, jobRuntimeInfo))
                    {
                        AppDomainLoader.UnLoad(jobRuntimeInfo.AppDomain);
                        return(false);
                    }
                    else
                    {
                        //添加成功后,和下面那种情况一起操作了.
                    }
                }

                //job池有job,这属于正常恢复,走下面的逻辑.
                //如果调度任务中没有该jobDetail 的 trigger,那么直接返回
                ITrigger trigger = GetTrigger(jobInfo, out TriggerKey triKey);
                if (trigger == null)
                {
                    return(false);
                }

                Scheduler.ResumeTrigger(triKey).Wait();
                return(true);

                //TODO:记录日志
            }
        }
Пример #2
0
 /// <summary>
 /// 创建新的应用程序域,返回运行时的Job数据
 /// </summary>
 /// <param name="jobInfo"></param>
 internal JobRuntimeInfo CreateJobRuntimeInfo(JobInfo jobInfo)
 {
     lock (Locker)
     {
         //JobRuntimeInfo jobRuntimeInfo = null;
         //if (JobPool.ContainsKey(jobInfo.Id))
         //{
         //    jobRuntimeInfo = GetJobFromPool(jobInfo.Id);
         //    return jobRuntimeInfo;
         //}
         AppDomain       app            = Thread.GetDomain();
         BaseJob.BaseJob job            = AppDomainLoader.Load(jobInfo.AssemblyPath, jobInfo.ClassType, out app);
         JobRuntimeInfo  jobRuntimeInfo = new JobRuntimeInfo
         {
             JobInfo   = jobInfo,
             Job       = job,
             AppDomain = app,
         };
         //TODO:日志记录
         return(jobRuntimeInfo);
     }
 }
Пример #3
0
        /// <summary>
        /// 线程池有job,但是该job的应用程序域已经卸载(一般都是宕机),替换job池中的jobRuntimeInfo,并重新调度该job
        /// </summary>
        /// <param name="jobRuntimeInfo"></param>
        /// <returns></returns>
        internal bool ReplaceJobRuntimeInfo(JobRuntimeInfo jobRuntimeInfo)
        {
            //TODO:有BUG,没有地方还原 _flag 的值
            //if (_flag)
            //{
            //    return true;
            //}

            lock (Locker)
            {
                //if (_flag)
                //{
                //    return true;
                //}
                AppDomain app = Thread.GetDomain();
                jobRuntimeInfo.Job                 = AppDomainLoader.Load(jobRuntimeInfo.JobInfo.AssemblyPath, jobRuntimeInfo.JobInfo.ClassType, out app);
                jobRuntimeInfo.AppDomain           = app;
                JobPool[jobRuntimeInfo.JobInfo.Id] = jobRuntimeInfo;
                //_flag = true;
                return(true);
            }
        }
Пример #4
0
        /// <summary>
        /// 从job池中移除某个job,同时卸载该job所在的AppDomain
        /// </summary>
        /// <param name="jobInfo"></param>
        /// <returns></returns>
        public bool Remove(JobInfo jobInfo)
        {
            lock (Locker)
            {
                ITrigger trigger = GetTrigger(jobInfo, out TriggerKey triKey);
                if (trigger == null)
                {
                    return(true);
                }
                Scheduler.PauseTrigger(triKey);
                Scheduler.UnscheduleJob(triKey);
                Scheduler.DeleteJob(GetJobKey(jobInfo));

                if (JobPool.ContainsKey(jobInfo.Id))
                {
                    JobPool.TryRemove(jobInfo.Id, out JobRuntimeInfo jobRuntimeInfo);
                    AppDomainLoader.UnLoad(jobRuntimeInfo.AppDomain);
                }
                return(true);
                //TODO:记录日志
            }
        }
Пример #5
0
        /// <summary>
        /// 添加job到job池,同时加入到调度任务中.
        /// </summary>
        /// <param name="jobRuntimeInfo"></param>
        /// <returns></returns>
        internal bool Add(JobRuntimeInfo jobRuntimeInfo)
        {
            lock (Locker)
            {
                try
                {
                    //如果该job实例添加失败,卸载该job的appdomain,然后返回.
                    if (!JobPool.TryAdd(jobRuntimeInfo.JobInfo.Id, jobRuntimeInfo))
                    {
                        AppDomainLoader.UnLoad(jobRuntimeInfo.AppDomain);
                        return(false);
                    }

                    //如果调度任务中已经有该jobDetail,则直接删掉
                    IJobDetail jobDetail = GetJobDetail(jobRuntimeInfo.JobInfo, out JobKey jobKey);
                    if (jobDetail != null)
                    {
                        Scheduler.DeleteJob(jobKey).Wait();
                    }

                    jobDetail = CreateJobDetail(jobRuntimeInfo.JobInfo);
                    ITrigger trigger = CreateTrigger(jobRuntimeInfo.JobInfo);
                    Scheduler.ScheduleJob(jobDetail, trigger).Wait();
                    //TODO:记录日志
                    return(true);
                }
                catch (Exception ex)
                {
                    //异常了,直接从job池移除该job,不再考虑移除失败的情况.考虑不到那么多了
                    if (JobPool.TryRemove(jobRuntimeInfo.JobInfo.Id, out JobRuntimeInfo jri))
                    {
                        //成功移除后,再卸载掉应用程序域,失败则不移除,保留.
                        AppDomainLoader.UnLoad(jobRuntimeInfo.AppDomain);
                    }
                    throw ex;
                }
            }
        }