你如何在Flask中安排时间事件? [英] How do you schedule timed events in Flask?

查看:211
本文介绍了你如何在Flask中安排时间事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一些代码:

  from flask import Flask,请求
导入时间,线程

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()) .bart()
return request.args [string] +存储10秒

@ application.route(/ get)
def get() :
返回application.string
$ b $如果__name__ ==__main__:
application.debug = True
application.run()

我的期望/目标是,如果您访问端点 / set?string = foo 然后在接下来的10秒内,当你访问 / get ,然后再返回hello,直到再次点击 / set 端点。



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

解决方案

以下是不正确的:

<$ p $ (10,application.reset())。start()



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

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

你可能想要做的是下面的代码。 。
$ b $ pre $ threading.Timer(10,application.reset).start()
这就是说,我会犹豫不决用这个解决方案,而不是一个玩具项目:根据你的Flask应用程序的部署方式,你可能会实际上有多个Flask进程同时运行。在这种情况下,这个解决方案只会改变你正在访问的进程。此外,在每个请求中产生一个新的线程可能会导致相当多的开销,这取决于您的负载。



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

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


Here's some code:

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()

My expectation/goal is that if you visit the endpoint /set?string=foo then for the next 10 seconds the app will return "foo" any time you visit /get, and from then on it will return "hello" until you hit the /set endpoint again.

Instead, if I hit /set?string=foo and then immediately '/get', the app returns "hello" and I see "TypeError: 'NoneType' object is not callable" in the console. Can anyone help?

解决方案

The following is incorrect:

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

The second argument to Timer needs to be a function, but you're actually calling the reset() function and thus passing the result of that method call to Timer. It's as if you've done the following...

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

What you probably want to do instead is the following...

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

That being said, I would be very hesitant to use this solution for anything more than a toy project: depending on how your Flask application is deployed, you might actually have multiple Flask processes running at the same time. In that case, this solution will only change the process you are currently accessing. Additionally, spawning a new thread in each request could cause quite a bit of overhead depending on your load.

A better approach might be to save this data into the user's session (a cookie), or into a database. You could use a system like Celery or another message queue to run asynchronous code.

If you need data to "expire" after a certain amount of time, also consider setting the date that the data should expire, and then introducing code which checks for the expiration. Thus, your "set" method could synchronously set an expiration time, and the "get" endpoint could check if the expiration time has elapsed and choose which value to return based on that. Now you don't need an asynchronous call to be made.

这篇关于你如何在Flask中安排时间事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆