2017-11-20 15 views
12

Tôi đang sử dụng Flask + gevent và muốn truy cập ứng dụng flask.g toàn cầu bên trong chức năng đích của một greenlet. Tôi đang sử dụng copy_current_request_context trang trí và có một tình huống khá giống với ví dụ được đưa ra trong các tài liệu:Truy cập flask.g bên trong greenlet

import gevent 
from flask import copy_current_request_context, g 

@app.route('/') 
def index(): 
    g.user_data = 'foobar' 
    g.more_user_data = 'baz' 

    @copy_current_request_context 
    def do_some_work(): 
     some_func(g.user_data, g.more_user_data) 
     ... 

    gevent.spawn(do_some_work) 
    return 'Regular response' 

Tuy nhiên, tôi nhận được lỗi sau:

AttributeError: '_AppCtxGlobals' object has no attribute 'user_data' 

Tôi nghĩ rằng một bối cảnh ứng dụng mới là được đẩy khi bối cảnh yêu cầu được sao chép? Tôi đặt một dấu vết trong mã Flask here và có vẻ như vậy. Vì vậy, lỗi không phải là tất cả những gì đáng ngạc nhiên vì đối tượng flask.g là bối cảnh ứng dụng được phạm vi là 0.10 (xem http://flask.pocoo.org/docs/0.12/api/#flask.Flask.app_ctx_globals_class).

Rõ ràng, tôi chỉ có thể vượt qua các dữ liệu người dùng vào chức năng mục tiêu như các đối số:

import gevent 
from flask import g 

@app.route('/') 
def index(): 
    g.user_data = 'foobar' 
    g.more_user_data = 'baz' 

    def do_some_work(user_data, more_user_data): 
     some_func(user_data, more_user_data) 
     ... 

    gevent.spawn(do_some_work, g.user_data, g.more_user_data) 
    return 'Regular response' 

Và điều này chỉ hoạt động tốt, nhưng tôi đã hy vọng để sử dụng flask.g nếu có thể.

+0

Khi sử dụng gevent, bạn có vá khỉ trực tiếp sau lần nhập đầu tiên không? –

+0

Yea, có vẻ như tôi đã bỏ nó ra khỏi ví dụ của mình. Nhưng có, tôi đang gọi 'patch_all' từ' gevent.monkey' ngay trong mã thực của tôi. – jamesdarabi

+1

Để bắt đầu, tại sao bạn muốn lưu trữ 'user_data' và' more_user_data' trong đối tượng 'flask.g'? Nếu bạn cần sự kiên trì của dữ liệu khôn ngoan của người dùng, thì có đối tượng 'flask.session'. Và nếu bạn cần sự kiên trì toàn cầu, thì bạn có thể sử dụng bất kỳ 'module.attribute' nào để lưu trữ chúng. –

Trả lời

6

flask.gbound with the app context, không theo yêu cầu bối cảnh, as the doc says:

Starting with Flask 0.10 this is stored on the application context and no longer on the request context ...

copy_current_request_context() chỉ sao chép yêu cầu bối cảnh, nhưng cung cấp cho bạn một bối cảnh ứng dụng mới. Bạn có thể tạo một ứng dụng để chuyển ngữ cảnh ứng dụng hiện tại bằng cách đóng:

def copy_current_app_context(f): 
    from flask.globals import _app_ctx_stack 
    appctx = _app_ctx_stack.top 
    def _(*args, **kwargs): 
     with appctx: 
      return f(*args, **kwargs) 
    return _ 

Tuy nhiên, tôi muốn chuyển dữ liệu vào greenlet một cách rõ ràng thông qua đối số, sạch hơn.

Các vấn đề liên quan