烧瓶结束响应并继续处理

烧瓶结束响应并继续处理,第1张

烧瓶结束响应并继续处理

可悲的是,将响应返回给客户端后,拆卸回调不执行:

import flaskimport timeapp = flask.Flask("after_response")@app.teardown_requestdef teardown(request):    time.sleep(2)    print("teardown_request")@app.route("/")def home():    return "Success!n"if __name__ == "__main__":    app.run()

卷曲时,您会注意到在显示响应之前有2s的延迟,而不是卷曲立即结束,然后在2s之后记录。日志进一步确认了这一点:

teardown_request127.0.0.1 - - [25/Jun/2018 15:41:51] "GET / HTTP/1.1" 200 -

返回响应后执行的正确方法是使用WSGI中间件,该中间件向响应迭代器的close方法添加了一个钩子。这不像

teardown_request
装饰器那么简单,但是仍然很简单:

import tracebackfrom werkzeug.wsgi import ClosingIteratorclass AfterResponse:    def __init__(self, app=None):        self.callbacks = []        if app: self.init_app(app)    def __call__(self, callback):        self.callbacks.append(callback)        return callback    def init_app(self, app):        # install extension        app.after_response = self        # install middleware        app.wsgi_app = AfterResponseMiddleware(app.wsgi_app, self)    def flush(self): for fn in self.callbacks: try:     fn() except Exception:     traceback.print_exc()class AfterResponseMiddleware:    def __init__(self, application, after_response_ext):        self.application = application        self.after_response_ext = after_response_ext    def __call__(self, environ, start_response):        iterator = self.application(environ, start_response)        try: return ClosingIterator(iterator, [self.after_response_ext.flush])        except Exception: traceback.print_exc() return iterator

然后可以这样使用:

@app.after_responsedef after():    time.sleep(2)    print("after_response")

从外壳程序中,您将看到响应立即返回,然后2秒钟后

after_response
它将返回日志:

127.0.0.1 - - [25/Jun/2018 15:41:51] "GET / HTTP/1.1" 200 -after_response

这是此处提供的先前答案的摘要。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5630173.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存