2012-03-29 9 views
36

Estoy tratando de iniciar un nuevo subproceso en Python dentro de una aplicación Flask. Estoy haciendo un trabajo de fondo que se desencadena con la solicitud, pero no necesito esperar a que se realice el trabajo para responder a la solicitud.Frasco que arroja 'trabajo fuera del contexto de solicitud' al iniciar el subproceso

¿Es posible establecer la solicitud del matraz en esta sub-amenaza a la solicitud que entró? Por lo que respecta a la razón, nuestra ACL en nuestras consultas a nuestro DB (mongoengine frente a mongoDB) depende del usuario de la solicitud (lo agarra del objeto de solicitud del matraz) para ver si tienen acceso a los objetos, y explota porque la solicitud es no disponible en el sub thread

Cualquier idea sería muy apreciada.

Aquí hay un pseudo código de cómo lo estoy manejando ahora, pero no está funcionando.

@app.route('/my_endpoint', methods=['POST']) 
def my_endpoint_handler(): 
    #do tracking in sub-thread so we don't hold up the page 
    def handle_sub_view(req): 
     from flask import request 
     request = req 
     # Do Expensive work 
    thread.start_new_thread(handle_sub_view, (request)) 
    return "Thanks" 
+1

Si sólo necesita el usuario entonces por qué no sólo tiene que pasar el usuario en el sub-hilo? El matraz –

+0

proporciona acceso a la solicitud en cualquier momento, por lo que mi clase base de documento tiene un administrador de conjunto de consultas que capta al usuario de la solicitud. El trabajo que estoy haciendo es mucho más alto que el administrador del conjunto de consultas, así que no puedo usar el usuario solo – MattoTodd

+0

La solicitud es un subproceso/contexto local por lo que no está disponible * any * time; de ​​lo contrario, no tendrías este problema . Sigo pensando que debería intentar refactorizar la dependencia del objeto de solicitud. –

Respuesta

44

Envuelve el código de hilo en una test_request_context para que tenga acceso a context locals:

@app.route('/my_endpoint', methods=['POST']) 
def my_endpoint_handler(): 
    #do tracking in sub-thread so we don't hold up the page 
    def handle_sub_view(req): 
     with app.test_request_context(): 
      from flask import request 
      request = req 
      # Do Expensive work 
    thread.start_new_thread(handle_sub_view, (request)) 
    return "Thanks" 

Editar: vale la pena señalar que el hilo tendrá un contexto diferente al de la solicitud original. Debe extraer datos de solicitud interesantes, como la ID de usuario, antes de generar el hilo. A continuación, puede tomar un objeto de usuario (diferente) en el sub thread utilizando la ID.

+2

Es posible que también desee analizar esto: http://celeryproject.org/ Lo uso para operaciones de bloqueo, como enviar correos electrónicos. Lo bueno es que puedes usar mongoDB como un backend, por lo que no tendrás que agregar nada a tu stack. – Ross

4

puede copiar la información deseada y pasarlo

@app.route('/my_endpoint', methods=['POST']) 
def my_endpoint_handler(): 
    #do tracking in sub-thread so we don't hold up the page 
    def handle_sub_view(data): 
     # Use the data in subprocess 
    data = request.get_json() # copy the data 
    thread.start_new_thread(handle_sub_view, data) 
    return "Thanks" 
+0

no es útil. Debo copiar todos los datos sobre la aplicación. – jamlee

Cuestiones relacionadas