• apscheduler模块


    https://zhuanlan.zhihu.com/p/95563033

    1 概念

    名词

    job 最小执行单位,创建一个Job,然后指定要执行的函数

    trigger 触发器,根据时间规则,计算得到下次执行时间。

    executer

    next_run_time  触发规则有trigger的时间,或者这个定时执行

    func job的执行函数

    args job执行函数的参数

    kwargs 执行函数的关键字参数

    trigger

    Trigger有多种种类,指定时间的DateTrigger,指定间隔时间的IntervalTrigger,像Linux的crontab一样的CronTrigger

    Executor 

    Executor在scheduler中初始化,另外也可通过scheduler的add_executor动态添加Executor。
    每个executor都会绑定一个alias,这个作为唯一标识绑定到Job,在实际执行时会根据Job绑定的executor
    找到实际的执行器对象,然后根据执行器对象执行Job

    Executor的种类会根据不同的调度来选择,如果选择AsyncIO作为调度的库,那么选择AsyncIOExecutor,如果
    选择tornado作为调度的库,选择TornadoExecutor,如果选择启动进程作为调度,
    选择ThreadPoolExecutor或者ProcessPoolExecutor都可以

    Executor的选择需要根据实际的scheduler来选择不同的执行器

    Jobstore 

    Jobstore在scheduler中初始化,另外也可通过scheduler的add_jobstore动态添加Jobstore。每个jobstore
    都会绑定一个alias,scheduler在Add Job时,根据指定的jobstore在scheduler中找到相应的jobstore,并
    将job添加到jobstore中。

    Jobstore主要是通过pickle库的loads和dumps【实现核心是通过python的__getstate__和__setstate__重写
    实现】,每次变更时将Job动态保存到存储中,使用时再动态的加载出来,作为存储的可以是redis,也可以
    是数据库【通过sqlarchemy这个库集成多种数据库】,也可以是mongodb等

    Event 

    Event是APScheduler在进行某些操作时触发相应的事件,用户可以自定义一些函数来监听这些事件,
    当触发某些Event时,做一些具体的操作

    常见的比如。Job执行异常事件 EVENT_JOB_ERROR。Job执行时间错过事件 EVENT_JOB_MISSED。

    Listener 

    Listener表示用户自定义监听的一些Event,当Job触发了EVENT_JOB_MISSED事件时
    可以根据需求做一些其他处理。

    Scheduler 

    Scheduler是APScheduler的核心,所有相关组件通过其定义。scheduler启动之后,将开始按照配置的任务进行调度。
    除了依据所有定义Job的trigger生成的将要调度时间唤醒调度之外。当发生Job信息变更时也会触发调度。

    scheduler可根据自身的需求选择不同的组件,如果是使用AsyncIO则选择AsyncIOScheduler,使用tornado则
    选择TornadoScheduler。

    tornado案例

    from datetime import datetime
    from tornado.ioloop import IOLoop, PeriodicCallback
    from tornado.web import RequestHandler, Application
    from apscheduler.schedulers.tornado import TornadoScheduler
    import json
    
    scheduler = TornadoScheduler()
    
    
    def init_scheduler():
        global scheduler
        url = "mysql+pymysql://root:123@192.168.1.2/codo_cron?charset=utf8"
        scheduler.add_jobstore(jobstore="sqlalchemy", url=url, tablename='api_job')     # 持久化存储配置,表会自动创建
        scheduler.start()
        print('[Scheduler Init]APScheduler has been started')
    
    
    # 要执行的定时任务在这里
    def task1():
        print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    def task2():
        print(datetime.now().strftime('%Y/%m/%d %H:%M:%S'))
    
    
    class SchedulerHandler(RequestHandler):
        def post(self):
            data = json.loads(self.request.body.decode("utf-8"))
    
            # 判断定时器格式
            cron = data.get('cron').strip().split(' ')
            if len(cron) != 6:
                return self.write(dict(code=-1, msg='添加失败,格式错误'))
    
            cmd = data.get('cmd', None)
            job_id = data.get('job_id', None)
    
            if job_id:
                try:
                    cron_rel = dict(second=cron[0], minute=cron[1], hour=cron[2], day=cron[3], month=cron[4],
                                    day_of_week=cron[5])
                    scheduler.add_job(func=__name__ + ':' + cmd,  # 可调用的函数,(e.g.  package.module:some.object)
                                      trigger='cron',   # 触发器类型,(e.g. ``date``, ``interval`` or ``cron``)
                                      # kwargs={'cmd': cmd, 'job_id': job_id},   # 调用函数的关键字参数的字典,函数没有参数就不需要
                                      id=job_id,     # job 唯一标识
                                      **cron_rel    # 定时任务格式,
                                                    # (e.g. second=10, minute=*, hour=*, day=*, month=*, day_of_week=*)
                                                    # 代表每分钟的第10秒执行一次
                                      )
    
                    return self.write(dict(code=0, msg='添加成功', job_id=job_id))
                except Exception as e:
                    return self.write(dict(code=-1, msg='添加失败: %s' % e))
    
    
    if __name__ == "__main__":
        routes = [
            (r"/scheduler/?", SchedulerHandler),
        ]
        init_scheduler()
        app = Application(routes, debug=True)
        app.listen(8888)
        IOLoop.current().start()
    

      

  • 相关阅读:
    罗技 M280 无线鼠标 All In One
    How to use macOS to connect to Raspberry Pi without the monitor All In One
    lodashes All In One
    Raspberry Pi 5 All In One
    Vite All In One
    GitHub & All Contributors All In One
    Vite 运行 TypeScript 文件原理剖析 All In One
    VNC Viewer All In One
    python中 把每条FASTA序列分割成特定个数个字母一行的序列
    c 语言中实现数组元素的逆向排列
  • 原文地址:https://www.cnblogs.com/jabbok/p/13691759.html
Copyright © 2020-2023  润新知