python-APScheduler-API总结

之前比较泛泛的介绍了 APScheduler 库,但是其中有一些模块的接口需要额外注意一下,本篇文章比较干,真正开发的时候,可以当成工具用

event

event 主要是 APScheduler 中触发的事件类,我们可以通过 add_listener() 为调度程序绑定监听函数,在收到指定事件后做一些自定义的操作

事件对应枚举值描述归属类
EVENT_SCHEDULER_STARTED1调度程序启动SchedulerEvent
EVENT_SCHEDULER_SHUTDOWN2调度程序关闭SchedulerEvent
EVENT_SCHEDULER_PAUSED4调度程序中任务处理暂停SchedulerEvent
EVENT_SCHEDULER_RESUMED8调度程序中任务处理恢复SchedulerEvent
EVENT_EXECUTOR_ADDED16将执行器添加到调度程序中SchedulerEvent
EVENT_EXECUTOR_REMOVED32执行器从调度程序中删除SchedulerEvent
EVENT_JOBSTORE_ADDED64将任务存储添加到调度程序中SchedulerEvent
EVENT_JOBSTORE_REMOVED128任务存储从调度程序中删除SchedulerEvent
EVENT_ALL_JOBS_REMOVED256所有任务从所有任务存储中删除或从一个特定的任务存储中删除SchedulerEvent
EVENT_JOB_ADDED512任务添加到任务存储中JobEvent
EVENT_JOB_REMOVED1024从任务存储中删除了任务JobEvent
EVENT_JOB_MODIFIED2048从调度程序外部修改了任务JobEvent
EVENT_JOB_EXECUTED4096任务被成功执行JobExecutionEvent
EVENT_JOB_ERROR8192任务在执行期间引发异常JobExecutionEvent
EVENT_JOB_MISSED16384错过了任务执行JobExecutionEvent
EVENT_JOB_SUBMITTED32768任务已经提交到执行器中执行JobSubmissionEvent
EVENT_JOB_MAX_INSTANCES65536任务因为达到最大并发执行时,触发的事件JobSubmissionEvent
EVENT_ALL包含以上的所有事件

不同事件因为基于不同的类,因此可以获取到的信息是不一致的
event 中有一个公共的字段 code (枚举值), 所以可以通过 code 来识别出具体是哪一种事件,然后在获取具体的一些字段信息

主要分为4个类,主要看一下4个类下独有的字段:

SchedulerEvent

  • alias 添加或删除的任务存储或执行程序的别名(如果有)

JobEvent

  • job_id 任务的标识ID
  • jobstore 包含相关任务的任务存储的别名

JobSubmissionEvent

  • job_id 任务的标识ID
  • jobstore 包含相关任务的任务存储的别名
  • scheduled_run_times 计划运行任务的时间列表

JobExecutionEvent

  • job_id 任务的标识ID
  • jobstore 包含相关任务的任务存储的别名
  • scheduled_run_time 计划运行任务的时间
  • retval 成功执行的任务的返回值
  • exception 任务运行引起的异常
  • traceback 任务出错的位置

Job

Job 包含了很多设置,它包含了 triggers(触发器), executor(执行器) 的信息,还有一些调度相关配置信息,例如允许运行的最多实例数,允许延迟执行的最长时间,是否合并等等,难点主要在创建,但是官方是不希望用户直接通过这个类来实例化 Job, 而是通过调度程序 scheduler 中的 add_job() 来实现,这里简单了解一些 Job 保存一些信息,和关于操作 Job 的接口,方便我们之后阅读它的源码

Job(scheduler, id=None, **kwargs)

实例化任务

  • scheduler 需要绑定的调度程序
  • id(str) 任务的唯一标识符
  • name(str) 任务的名称
  • func 任务实际执行的函数
  • args(tuple|list) 函数可能需要的传入参数
  • kwargs(dist) 一些其他的可调用的关键字参数,比如描述触发器的相关字段等等
  • coalesce(bool) 是否在多个运行时间到期时仅运行一次任务
  • trigger 触发器对象
  • executor(str) 执行器名称
  • misfire_grace_time(int) 允许此任务延迟执行的最大时间(单位秒)
  • max_instances(int) 该任务允许的并发执行的最大实例数量
  • next_run_time(datetime.datetime) 此任务下一次计划运行的时间

modify(**changes)

  • Return type Job 的实例

对该任务的配置进行修改,并将其保存在关联的任务存储中,可接受的关键字参数与创建此类的参数相同

pasue()

  • Return type Job 的实例

暂停该任务的执行

remove()

取消任务,并将其从其关联的任务存储中删除

reschedule(trigger, **trigger_args)

  • Return type Job 的实例

在此任务上切换触发器

resume()

  • Return type Job 的实例

如果之前已暂停,恢复该任务的计划

property pending

如果引用的任务仍在等待添加到其指定的任务存储中,则返回True。

triggers

触发器是值得比较详细介绍的,主要是触发方式有 4

  • date 指定时间运行的一次性任务
  • inteval 间隔时间运行的循环任务
  • cron 定时任务
  • combining 组合任务

date

date 是执行一次性任务,所有它的配置简单

  • run_date 任务执行的时间
  • timezone 时间的时区
from datetime import date
from apscheduler.schedulers.blocking import BlockingScheduler

sched = BlockingScheduler()

def my_job(text):
    print(text)

#您可以指定应运行任务的确切时间:
sched.add_job(my_job, 'date', run_date=datetime(2020, 12, 16, 16, 30, 5), args=['text'])

# 运行日期也可以作为文本给出
sched.add_job(my_job, 'date', run_date='2020-12-16 16:30:05', args=['text'])

# 要添加要立即运行的任务
sched.add_job(my_job, args=['text'])
sched.start()

inteval

inteval 是配置间隔时间运行的循环执行的任务,它可以通过以下时间来控制

  • days(int) 等待天数
  • weeks(int) 等待多少周
  • hours(int) 等待小时数
  • minutes(int) 等待的分钟数
  • seconds(int) 等待的秒数
  • start_date(datetime|str) 触发的开始日期/时间(包含)
  • end_date(datetime|str) 可能触发的最晚日期/时间(包含)
  • timezone(datetime.tzinfo|str) 用于日期/时间计算的时区(默认为调度程序的时区)
  • jitter(int|None) 提前或延迟执行任务的最大随机时间(单位秒)

一般比如任务每隔20分钟执行一次,就可以写成

from apscheduler.schedulers.blocking import BlockingScheduler

def interval_task(text):
    print(text)

scheduler = BlockingScheduler()
scheduler.add_job(func=interval_task, trigger='interval', minutes=20, args=['text'])
scheduler.start()

一般写个简单的监控程序,监控内存网络等等,inteval 是一个很简单的选择

cron

corn 可以说是最强大的,能实现的计划也是最全面的,主要对以下参数进行配置

  • year(int|str) 4位数的年份
  • month(int|str) month (1-12 或者 ‘jan’, ‘feb’, ‘mar’, ‘apr’, ‘may’, ‘jun’, ‘jul’, ‘aug’, ‘sep’, ‘oct’, ‘nov’, ‘dec’)
  • day(int|str) (1-31) 天
  • week(int|str) ISO 周 (1-53)
  • day_of_week(int|str) 工作日的编号或名称 (0-6 or mon,tue,wed,thu,fri,sat,sun)
  • hour(int|str) 小时(0-23)
  • minute(int|str) 分钟(0-59)
  • second(int|str) 秒(0-59)
  • start_date(datetime|str) 触发的开始日期/时间(包含)
  • end_date(datetime|str) 可能触发的最晚日期/时间(包含)
  • timezone(datetime.tzinfo|str) 用于日期/时间计算的时区(默认为调度程序的时区)
  • jitter(int|None) 提前或延迟执行任务的最大随机时间(单位秒)

其中 year, month, day, week, day_of_week, hour, minute, second 这些字段是支持表达式配置的

而现在默认支持的表达式格式如下:

表达式描述
*所有值
*/a从 a 值开始,触发每个 a 值
a-b对 a-b 范围内的任何值进行触发(a必须小于b)
a-b/c在 a-b 范围内触发每个 c 值
xth y在一个月中第 x 个 周 y 触发 ( x 支持的参数 1st, 2nd, 3rd, 4th, 5th, last)
last x在一个月中最后一个 周 x 触发
last在一个月的最后一天触发
x,y,z可以用逗号隔开多个表达式

看描述就知道这些表达式,并不是满足上面提到的所有字段,这里先不展开了,之后会有一篇关于源码的总结,会介绍这方面的知识

combining

这个触发器主要是以不同的方式结合其他触发器的行为,生成比任何单个触发器更复杂的计划

  • AndTrigger 始终返回所有给定触发器可以达成一致 最早的下一次触发时间。当任何给定触发器完成其计划时,触发器被视为已完成。
  • OrTrigger 始终返回由任何给定触发器 产生的最早的下一次触发时间。当所有给定触发器都已完成其计划时,触发器将被视为已完成。

它们的参数都是一样的

  • triggers(list) 需要组合的触发器们
  • jitter (int|None) 一个随机数

每 2 小时运行一次,但仅在周六和周日运行:job_function

from apscheduler.triggers.combining import AndTrigger
from apscheduler.triggers.interval import IntervalTrigger
from apscheduler.triggers.cron import CronTrigger

trigger = AndTrigger([IntervalTrigger(hours=2),
                      CronTrigger(day_of_week='sat,sun')])
scheduler.add_job(job_function, trigger)

每周一凌晨 2 点运行,每周二下午 3 点运行:job_function

trigger = OrTrigger([CronTrigger(day_of_week='mon', hour=2),
                     CronTrigger(day_of_week='tue', hour=15)])
scheduler.add_job(job_function, trigger)

BaseJobStore

任务存储主要就是存储任务的库, 而 BaseJobStore 是以下几个类的基类,除了初始化存在一点差异,提供的接口基本是一致的,这里主要就介绍基类了

  • MemoryJobStore
  • MongoDBJobStore
  • RedisJobStore
  • RethinkDBJobStore
  • SQLAlchemyJobStore
  • ZooKeeperJobStore

add_job(job)

  • job(Job) 需要添加的任务
  • 异常 ConflictingIdError 任务的标识符 job_id 存在相同的时候抛出异常

添加一个任务到任务存储中

get_all_jobs()

  • Return type list[Job]

返回此任务存储中所有任务的列表,返回的任务列表按下一次运行时间(升序)排序。暂停的任务(next_run_time == None)排在最后

get_due_jobs(now)

  • now (datetime.datetime) 当前的日期时间
  • Return type list[Job]

返回早于或等于 next_run_time 的任务列表,返回的任务必须按下一个运行时间(升序)排序

get_next_run_time()

  • Return type datetime.datetime

返回存储在此任务存储中的所有任务的最早运行时间或者 None(如果没有活动的任务)

lookup_job(job_id)

  • job_id(str|unicode) 任务的标识符
  • Return type Job

返回特定的任务,或者 None (找不到)

remove_all_jobs()

从该任务存储中删除所有的任务

remove_job(job_id)

  • job_id(str|unicode) 任务的标识符
  • 异常 JobLookupError 如果任务不存在

从该任务存储中删除指定的任务

shutdown()

释放该任务存储上的所有资源

start(scheduler,alias)

  • scheduler 管理这个任务存储的调度程序
  • alias 此任务存储的别名

update_job(job)

  • job 要更新的任务
  • 异常 JobLookupError 如果任务不存在

用给定的较新的版本替换任务存储中的任务

BaseExecutor

执行器在我们写代码过程中基本不会直接用到,因为我们将执行器参数在配置 schedulers 的时候,就传入了,接下来任务需要执行的时候,schedulers 会根据配置安排执行器执行

BaseExecutor 是以下几个类的基类,而接口主要都在这个基类中定义了,子类负责自己的实现而已

  • AsyncIOExecutor
  • DebugExecutor
  • GeventExecutor
  • ThreadPoolExecutor
  • ProcessPoolExecutor
  • TwistedExecutor

shutdown(wait=True)

  • wait(bool) 设置成 True 则等待执行器中所有正在执行的任务结束在停止

停止这个执行器

start(scheduler, alias)

  • scheduler(apscheduler.schedulers.base.BaseScheduler) 管理这个执行器的调度程序
  • alias(str|unicode) 此执行器的别名

当调度程序正在启动或正在将执行器添加到已在运行的调度程序时。

简单点说就在 schedulers 已经启动后,如果我们需要添加新的执行器,需要手动调用 start 来初始化执行器

submit_job(job, run_times)

  • job(Job) 要执行的工作
  • run_times(list[datetime]) 指定应在何时运行任务的日期时间列表
  • 异常 MaxInstancesReachedError 如果达到了这个任务能同时运行的最大实例数时抛出的异常

提交任务以执行

BaseScheduler

调度程序统筹了任务存储,任务的触发器和执行器,而 BaseScheduler 是以下几个类的基类,所有这里主要就是介绍基类提供的接口函数

  • BackgroundScheduler
  • BlockingScheduler
  • AsyncIOScheduler
  • GeventScheduler
  • TornadoScheduler
  • TwistedScheduler

BaseScheduler(gconfig={}, **options)

初始化调度程序,其中涉及到很多配置参数

  • logger (str|logging.Logger) 日志输出
  • timezone (str|datetime.tzinfo) 默认时区(默认为本地时区)
  • jobstore_retry_interval (int|float)jobstores 中取任务失败后,重试的间隔
  • job_defaults (dict)
    • max_instances : 同一个任务同时允许运行的最大实例,默认为 1, 比如一个耗时10分钟任务,但是5分钟执行一次,如果使用默认值为1, 0分钟的时候启动1个实例,那么5分钟的时候就不会在启动新的实例了,因为已经有1个实例在执行了
    • coalesce : 当同一个任务因为某些原因导致同时触发时,是否将任务合并成一个任务,默认 False
    • misfire_grace_time : 当真正执行任务的时间与计划执行时间的误差,也就是在设置的误差范围内,任务被调用到,该任务还是会被执行,反之则改任务状态就会为 EVENTJOBMISSED,不执行
  • jobstores (dict) 设置任务商店信息,默认存储为 MemoryJobStore
  • executors (dict) 设置执行器信息,默认使用 ThreadPoolExecutor, 也就是线程池的方式,线程池线程数 10

控制调度程序

方法描述异常
configure对给定的调度程序重新设置配置SchedulerAlreadyRunningError –如果调度程序已经在运行
start启动已配置的执行程序和任务存储,并开始处理计划的任务。SchedulerAlreadyRunningError –如果调度程序已经在运行 RuntimeError –如果在禁用线程的uWSGI下运行
shutdown关闭调度程序及其执行程序和任务存储。SchedulerNotRunningError –如果尚未启动调度程序
pause暂停调度程序中的任务处理。
resume在调度程序中恢复任务处理。
wakeup通知调度程序可能有任务需要执行。

控制执行器

方法描述异常
add_executor将执行程序添加到此调度程序。ValueError –如果已有给定别名的执行程序
remove_executor从此调度程序中删除具有给定别名的执行程序。

控制任务存储

方法描述异常
add_jobstore将任务存储添加到此调度程序。ValueError –如果已经存在给定别名的任务存储
remove_jobstore从此调度程序中通过给定别名删除任务存储。

控制事件侦听器

方法描述
add_listener添加调度程序事件的侦听器。
remove_listener删除以前添加的事件侦听器。

控制任务

Job 的配置参数和前面 Job 里介绍的差不多, BaseScheduler 只是将 Job 的接口重新封装了
但是也实现了很多任务是如何添加到任务存储,任务是如何分配给执行器等等实现,所以在 Job 那一部分提到,官方是不希望由用户自己实例化 Job

方法描述异常
add_job将给定的任务添加到任务列表中,如果调度程序已经在运行,则将其唤醒。
scheduled_job使用 scheduled_job 装饰器来动态装饰 Job的实际函数
modify_job修改单个任务的属性。
reschedule_job为任务构造一个新触发器,并更新其下一个运行时间。
pause_job使给定任务在明确恢复之前不执行。
resume_job恢复给定任务的计划,如果计划已完成,则将其删除。
get_jobs从特定的任务存储或所有任务中返回挂起的任务
get_job返回与给定 job_id 匹配的 Job
remove_job删除任务,使其无法再运行。JobLookupError – 如果没有找到任务
remove_all_jobs从指定的任务存储中删除所有任务,或者如果没有给出任何任务,则删除所有任务存储。
print_jobs打印出当前计划在所有任务存储库或仅特定任务存储库上的所有任务的文本列表。

以上部分函数涉及到的形参合返回值我这里就不列出来了,主要是要对每个类大概提供的接口有个印象即可,真正用的时候在查阅官方文档即可,难度不大

https://apscheduler.readthedocs.io/en/stable/py-modindex.html

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会偷懒的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值