你如何在Flask安排定时活动?

时间:2015-10-21 20:06:19

标签: python timer flask

以下是一些代码:

from flask import Flask, request
import time, threading

class MyServer(Flask):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.reset()

    def reset(self):
        self.string = "hello"

application = MyServer(__name__)

@application.route("/set")
def set():
    application.string = request.args["string"]
    threading.Timer(10, application.reset()).start()
    return request.args["string"] + " stored for 10 seconds"

@application.route("/get")
def get():
    return application.string

if __name__ == "__main__":
    application.debug = True
    application.run()

我的期望/目标是,如果您访问端点/set?string=foo,那么在接下来的10秒内,只要您访问/get,应用就会返回“foo”,之后就会返回“你好,“直到你再次点击/set端点。

相反,如果我点击/set?string=foo然后立即'/ get',应用程序返回“hello”,我在控制台中看到“TypeError:'NoneType'对象不可调用”。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:4)

以下内容不正确:

threading.Timer(10, application.reset()).start()

Timer的第二个参数需要是一个函数,但实际上你正在调用reset()函数,从而将该方法调用的结果传递给Timer。这就像你做了以下......

result = application.reset()
threading.Timer(10, result).start()

你可能想要做的是以下......

threading.Timer(10, application.reset).start()

话虽这么说,我会非常犹豫是否将此解决方案用于玩具项目以外的任何事情:根据Flask应用程序的部署方式,您实际上可能同时运行多个Flask进程。在这种情况下,此解决方案只会更改您当前正在访问的进程。此外,在每个请求中生成一个新线程可能会导致相当大的开销,具体取决于您的负载。

更好的方法可能是将此数据保存到用户的会话(cookie)或数据库中。您可以使用像Celery或其他消息队列这样的系统来运行异步代码。

如果您需要在一定时间后“过期”数据,还应考虑设置数据过期的日期,然后引入检查过期的代码。因此,您的“set”方法可以同步设置到期时间,“get”端点可以检查过期时间是否已过,并根据该值选择要返回的值。现在您不需要进行异步调用。