我正在尝试访问衍生的Greenlet中的flask请求对象。这是代码:
import gevent
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/async')
def async():
gevent.spawn(do_async)
return 'OK'
def do_async():
html = render_template('async.html', args=request.args)
print html
当我点击服务器时,do_async()中的第一行会抛出此错误:
RuntimeError: working outside of request context
如何允许do_sync()“在请求上下文之外工作”?
我尝试过的事情:
在不同地方使用with app.app_context():
创建一个新的请求对象,并使用
将其作为参数传递给do_async()
req = app.request_context(request.environ)
这会引发错误
AttributeError: 'RequestContext' object has no attribute 'args'
。
使用copy_current_request_context
装饰器复制请求对象。这有效
但它变得阻塞了。在do_async完成后,才会发送响应
虽然它在一个gevent线程中。
软件版本:
修改
这是我在试图“解锁”copy_current_request_context
装饰器时注意到的。这是代码:
import gevent
from flask import Flask, request, render_template
from flask import copy_current_request_context
app = Flask(__name__)
@app.route('/async')
def async():
@copy_current_request_context
def wrap_do_async():
do_async()
gevent.spawn(wrap_do_async)
return 'OK'
def do_async():
gevent.sleep(0.001) # Added to 'unblock' copy_current_request_context
html = render_template('async.html', args=request.args)
print html
在do_async()中没有gevent.sleep(0.001)
行,该函数可以工作,但是块(在我正在模拟的“真正的”do_async()代码中,它会阻塞大约8秒)。使用该行,该函数不会阻塞,但请求现在为空。