首页 > 其他分享 >Flask-ApScheduler 任务未执行问题

Flask-ApScheduler 任务未执行问题

时间:2022-11-09 18:33:26浏览次数:44  
标签:fcntl 启动 Flask app ApScheduler 任务 scheduler flask

Flask-ApScheduler 任务未执行问题

在使用flask run启动 flask 时,任务没有按计划执行

ApScheduler 任务配置

Config = {
    JOBS = [
        {
            'id': 'ims_info',  # 标识
            'func': 'task_1:main',  # 运行函数
            'trigger': 'interval',  # 定时任务的类型
            'seconds': 900  # 运行的间隔时间
        }
    ]
    SCHEDULER_API_ENABLED = True
    SCHEDULER_TIMEZONE = 'Asia/Shanghai'
    SCHEDULER_LOCK_FILE = 'scheduler.lock'
}

ApScheduler 初始化

为了防止使用 gunicorn 启动 flask 时,重复启动任务,在创建 Apscheduler 对象时增加文件锁

import fcntl
import atexit
import flask
from flask import Flask, request, g, make_response
from flask_apscheduler import APScheduler
from apscheduler.schedulers.background import BackgroundScheduler


def create_apscheduler(flask_app):
    """创建 Apscheduler 对象,使用文件锁防止用 gunicorn 启动 flask 时,重复启动多个任务"""
    f = open(Config.SCHEDULER_LOCK_FILE, 'wb')
    try:
        fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
        scheduler = APScheduler(BackgroundScheduler())  # 创建 Apscheduler 对象
        scheduler.init_app(flask_app)
        scheduler.start()  # 启动任务列表
    except Exception as _:
        pass

    def unlock():
        fcntl.flock(f, fcntl.LOCK_UN)
        f.close()

    atexit.register(unlock)


app = Flask(__name__)
app.config.from_object(Config)
create_apscheduler(app)

问题原因

flask 使用 debug 模式启动时,会创建一个子分支,Flask-ApScheduler 为了防止启动两次任务,只在子进程中启动任务。

# Flask-ApScheduler 启动源码
def start(self, paused=False):
    """
    Start the scheduler.
    :param bool paused: if True, don't start job processing until resume is called.
    """

    # Flask in debug mode spawns a child process so that it can restart the process each time your code changes,
    # the new child process initializes and starts a new APScheduler causing the jobs to run twice.
    if flask.helpers.get_debug_flag() and not werkzeug.serving.is_running_from_reloader():
        return

    if self.host_name not in self.allowed_hosts and '*' not in self.allowed_hosts:
        LOGGER.debug('Host name %s is not allowed to start the APScheduler. Servers allowed: %s' %
                        (self.host_name, ','.join(self.allowed_hosts)))
        return

    self._scheduler.start(paused=paused)

这与前面防止 gunicorn 启动多次任务的文件锁机制冲突,最后导致任务一次也没有启动:

  • 文件锁保证只在第一个进程中执行 Flask-ApScheduler 初始化及启动,也就是 debug 时的主进程;
  • Flask-ApScheduler 的 start 方法中只会在子进程启动时启动任务;

问题解决

在文件锁前增加 debug 模式判断,当 debug 模式时,不使用文件锁:

def create_apscheduler(flask_app):
    """创建 Apscheduler 对象,使用文件锁防止用 gunicorn 启动 flask 时,重复启动多个任务"""
    if flask.helpers.get_debug_flag():
        scheduler = APScheduler(BackgroundScheduler())  # 创建 Apscheduler 对象
        scheduler.init_app(flask_app)
        scheduler.start()  # 启动任务列表
    else:
        f = open(Config.SCHEDULER_LOCK_FILE, 'wb')
        try:
            fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
            scheduler = APScheduler(BackgroundScheduler())  # 创建 Apscheduler 对象
            scheduler.init_app(flask_app)
            scheduler.start()  # 启动任务列表
        except Exception as _:
            pass

        def unlock():
            fcntl.flock(f, fcntl.LOCK_UN)
            f.close()

        atexit.register(unlock)

标签:fcntl,启动,Flask,app,ApScheduler,任务,scheduler,flask
From: https://www.cnblogs.com/shouwangrenjian/p/16874760.html

相关文章

  • VS2010中的任务并行
        VS2010提供了任务并行库TPL增强了应用程序的并发性,在客户端系统中,并发任务的操作是不可缺少的一项功能,这样可以加强用户体验,在VS2010中有了全新的操作方式。......
  • 贡献者任务第五期,炫酷登场!
    夏天夏天悄悄过去,留下小惊喜。虽然夏天的火热已经远去,但是OpenMLDB鼓励开发者参与贡献的火热活动从未停止。开源机器学习数据库OpenMLDB,邀请你参与第五期贡献者任务。......
  • Flask配置https访问协议
    在工作中总有会遇到不得不使用https服务的时候,如我在工作中就遇到了苹果ipa安装包请求地址必须使用https协议不然会提示证书错误.接下来就简单描述下flask怎么启动http......
  • 实验1/任务2
    请阅读北航陈彦吉同学的这篇博客中的各参考资料,并回答如下问题:(1)回顾你过去将近3年的学习经历问:当初你报考的时候,是真正喜欢软件工程这个专业吗?答:当初报考的时候并不......
  • SAP 后台任务定时job
    定时任务的事务码sm36:创建定时任务sm37:查看定时任务JDBG:后台任务debug,在对应的sm37中对应的job页面t-code输入创建定时任务SM36名称可以随便起一般都是按自己公......
  • Python|使用Flask进行Web开发
    基础知识Flask是一个用Python编写的Web应用程序框架。它由ArminRonacher开发,他领导一个名为Pocco的国际Python爱好者团队。Flask基于WerkzeugWSGI工具包和Jinja2模......
  • Ubuntu 配置任务执行计划
    Linux定时任务调度定时执行Linux命令个人任务调度$crontab-e第一次输入后会让你选择编译器,在Ubuntu系统中nano编译器是比较好用的,然后会打开一个文件更改配置......
  • win10系统下鼠标点击任务栏,导致托盘输入法图标(qq拼音、搜狗拼音)闪动的解决方案
    之前找了很多解决方案,可能是场景不一样,一直没解决。后来偶然间发现一种很简单的处理方式。有类似情况的可以试试。问题场景还原   如上图可见,鼠标切换到任......
  • 任务卡_05-数据库_数据库基础
    目录​​一,数据库训练任务​​​​1,任务概述​​​​2,参考代码​​​​2.1建表及插入数据​​​​2.2 检索​​​​3,参考资料​​​​MySQL数据库中int,bigint,smallint和......
  • 实验一———个人项目:任务2
    一、回顾你过去将近三年的经历1、当初报考的时候,是真正喜欢计算机这个专业吗?我本人从初中开始就很喜欢计算机专业,一是我姐就是计算机专业的,二是我觉得敲代码真的很帅,以至......