VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • [Flask Tips]Flask-APScheduler用法总结

在应用中需要使用调度框架来做一些统计的功能,可惜在Windows上可用的不多,最后选择了APScheduler这个调度器。
用法不多介绍,只总结一下在使用中遇到的坑。

app_context 问题

凡是在APScheduler中调用的function,只要用到初始化跟app相关的对象(如db,mail),都是需要app上下文的,正常情况下都需要push app_context的。
否则将会报"No application found. Either work inside a view function or push an application context."的错误。
因为Flask-APScheduler在运行的时候是单独的一个进程,在这个进程中app是没有实例化的。使用之前要先实例化app对象。
以下代码可以解决这个问题:


#此创建app实例
def get_app():
    flask_app=create_app('production')
    return flask_app

def job1():
    with get_app().app_context():
        #需要做的操作

重复运行问题

在create_app时同时创建APScheduler对象,并且init然后start,会出现一个重复运行的问题。
那是因为FastCGI进程管理器在Web Server启动时,会自动创建若干个进程等待客户端的连接。如果访问量比较大,FastCGI会创建更多的进程以响应客户端的连接。
而每启动一个进程都会在后台创建一个APScheduler对象,所以会出现重复运行的情况。
在Linux上可以通过Python的fcntl包获得一个文件的排他锁,以达到只启动一个APScheduler对象的功能。但是在Windows上没有相应的包。
试过很多种获得文件排他锁的方法,终于找到一个第三方的包:portalocker,果断安装。
使用方法如下:


scheduler=APScheduler()

def create_app(config_name):
    app=Flask(__name__)
    app.jinja_env.trim_blocks=True
    app.config.from_object(config[config_name])
    config[config_name].init_app(app)

    scheduler_init(app)

    return app


def scheduler_init(app):
    try:
        lockfile=open('scheduler.lock','w')
        portalocker.lock(lockfile,portalocker.LOCK_EX | portalocker.LOCK_NB)
        lockfile.write(str(datetime.datetime.now()))
        scheduler.init_app(app)
        scheduler.start()
    except:
        pass

    def _unlock_file():
        try:
            portalocker.unlock(lockfile)
        except:
            pass

    atexit.register(_unlock_file)

获得锁的进程,在解释器被销毁时会调用_unlock_file释放锁,新创建的进程又会得到锁,所以APScheduler会一直运行。
如果要想获得准确调度,可以使用APScheduler另外启动一个进程,而不要使用Flask-APScheduler。
不过Flask-APScheduler对我的应用来说够用了。


相关教程