目前团队使用 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 方法里面确实没有上面那一段判断逻辑:
这个问题引发的思考:
没事插件不要乱升级!!!