目前团队使用 flask+flask_apsheduler 作为异步任务来跑自动化,前几天本地调试的时候,发现 sheduler 服务一直启动不成功,部分代码如下:

本地启动 flask 之后:

启动代码:

但是之前一直都是这么用的没有问题
继续查看 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)
def get_debug_flag() -> bool:
    """Get whether debug mode should be enabled for the app, indicated
    by the :envvar:`FLASK_DEBUG` environment variable. The default is
    ``True`` if :func:`.get_env` returns ``'development'``, or ``False``
    otherwise.
    """
    val = os.environ.get("FLASK_DEBUG")

    if not val:
        return get_env() == "development"

    return val.lower() not in ("0", "false", "no")

大致的意思就是判断当前 flask 如果配置了环境变量 FLASK_ENV 为 development 同时启动 flask 是 use_reload 为 False,就直接 return 不会继续执行后续的启动 scheduler 动作
看了下我本地的配置,刚好配置了环境变量 FLASK_ENV 为 development,并且启动 app 时 use_reload 为 False

解决方式就是 app 在启动的时候把 use_reload 改为 True 或者把环境变量 FLASK_ENV 改成除了 development 之外的其他值
但是之前为什么没有问题呢?
让同事本地跑了一下也确实没问题,scheduler 可以正常启动,怀疑的 flask_apscheduler 版本的问题,因为之前我本地升级过一波第三方库,对比了一下,同事的版本是 1.12.0,而我的是 1.12.4,1.12.0 版本的 start 方法里面确实没有上面那一段判断逻辑:

这个问题引发的思考:

没事插件不要乱升级!!!


↙↙↙阅读原文可查看相关链接,并与作者交流