Python定时任务框架:APScheduler源码剖析(二)

前言

在上一篇文章中,简单的捋了一遍使用BackgroundScheduler调度器做定时任务的流程,本篇接着上一篇文章,分析一下_real_add_job方法和_main_loop方法。

虽然APScheduler有多种不同的调度器以及多种不同的使用方式,但其核心都是类似的,一通百通。

对了,文中分析的APScheduler是当前最新版3.6.1。

剖析_real_add_job

回顾一下上篇文章添加任务对象的大致逻辑。

实例化BackgroundScheduler --> 调用add_job方法 --> 最终调用_real_add_job

_real_add_job源码如下,其代码的大致逻辑以给出相应的注释。

# apscheduler/schedulers/base.py/BaseScheduler

    def _real_add_job(self, job, jobstore_alias, replace_existing):
        """
        将任务对象添加到指定的存储后端中(默认就是内存中-->dict)
        """
        
        # 使用默认值填写未定义的值
        replacements = {
   }
        for key, value in self._job_defaults.items():
            if not hasattr(job, key):
                replacements[key] = value

        # 如果未定义下次运行时间,则计算下次运行时间
        if not hasattr(job, 'next_run_time'):
            now = datetime.now(self.timezone)
            replacements['next_run_time'] = job.trigger.get_next_fire_time(None, now)

        # 应用任何替换
        job._modify(**replacements)

        # 将作业添加到给定的作业库
        store = self._lookup_jobstore(jobstore_alias)
        try:
            store.add_job(job)
        except ConflictingIdError:
            if replace_existing:
                store.update_job(job)
            else:
                raise

        # 将任务对象标记为非待定
        job._jobstore_alias = jobstore_alias

        # 通知监听器已添加新任务
        event = JobEvent(EVENT_JOB_ADDED, job.id, jobstore_alias)
        self._dispatch_event(event)

        self._logger.info('Added job "%s" to job store "%s"', job.name, jobstore_alias)

        # 通知调度程序有关新工作的信息
        if self.state == STATE_RUNNING:
            self.wakeup()

代码中已有大致的注释,这里再简单分析一下。

一开始定义replacements字典,然后循环处理_job_defaults字典,判断该字典中的key是否是job任务对象的属性,如果是,则添加到replacements字典中。

接着同样的方式,判断job任务对象是否存在next_run_time属性,如果不存在,则需要调用当前任务对象中触发器(trigger)的get_next_fire_time方法计算出当前任务对象下一次要运行的时间。

随后调用job任务对象_modify方法,该方法的作用就是修改job任务对象的属性。

怎么实现属性的修改?没想象的那样使用了什么高深的技巧,看该方法的源码,就定义了approved字典,然后将replacements字典中的值获取并判断是否替换,替换就放到approved字典中,最后遍历approved字典,利用setattr方法将该字典中的值设置为job对象的属性,实现job对象属性的修改。

接着调用_lookup_jobstore方法找到用于存储当前任务对象的job stores(任务存储器),jobstore_alias是_real_add_job方法的参数,该方法是add_job方法调用的,往回看,可知jobstore_alias默认为default字符串,则选择内存作为job stores,然后调用job sotres的add_job方法将任务对象加入其中。

为啥说job stores为default就是使用内存作为job store呢?

看到BaseScheduler类的start方法,该方法部分逻辑如下。

# apscheduler/scheduleers/base.py/BaseScheduler

 with self._jobstores_lock:
            # Create a default job store if nothing else is configured
            if 'default' not in self._jobstores:
                self.add_jobstore(self._create_default_jobstore(), 'default')

其调用了_create_default_jobstore方法创建默认jobstore,该方法代码如下。

# apscheduler/scheduleers/base.py/BaseScheduler

def _create_default_jobstore(self):
        """Creates a default job store, specific to the particular scheduler type."""
        return<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值