2012-03-29 6 views
36

Sto provando ad avviare una nuova discussione in Python all'interno di un'applicazione Flask. Sto facendo il lavoro in background che viene attivato dalla richiesta, ma non ho bisogno di aspettare che il lavoro sia fatto per rispondere alla richiesta.Fiasco lanciare "lavorare fuori dal contesto della richiesta" all'avvio della sottofodera

È possibile impostare la richiesta del pallone in questa sotto minaccia alla richiesta? Essendo la ragione, il nostro ACL sulle nostre query al nostro DB (mongoengine di fronte a mongoDB) si basa sull'utente della richiesta (lo afferra dall'oggetto di richiesta del flask) per vedere se hanno accesso agli oggetti, e la sua esplosione perché la richiesta è non disponibile nel sottoprocesso.

Ogni pensiero sarebbe molto apprezzato.

Ecco lo pseudo codice di come lo sto gestendo ora, ma non funziona.

@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

Se avete solo bisogno che l'utente allora perché non basta passare l'utente nel sub-thread? Il pallone –

+0

fornisce l'accesso alla richiesta in qualsiasi momento, quindi la mia classe Document base ha un gestore di set di query che cattura l'utente dalla richiesta. Il lavoro che sto svolgendo è molto elevato rispetto al set manager di query, quindi non posso semplicemente usare l'utente da solo – MattoTodd

+0

La richiesta è un thread/contesto locale quindi non è disponibile * qualsiasi * volta altrimenti non avresti questo problema . Continuo a pensare che dovresti cercare di rifattorizzare la dipendenza dall'oggetto richiesta. –

risposta

44

Avvolgete il vostro codice di discussione in un test_request_context in modo da avere accesso 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" 

Edit: vale la pena di sottolineare che il filo avrà un contesto diverso da quello della richiesta originale. È necessario estrarre qualsiasi dato di richiesta interessante, come l'ID utente, prima di generare il thread. È quindi possibile afferrare un oggetto utente (diverso) nel sottoprocesso utilizzando l'ID.

+2

Si potrebbe anche voler esaminare in astratto questo - http://celeryproject.org/ Io lo uso per operazioni di blocco come l'invio di e-mail. La cosa buona è che puoi usare mongoDB come back-end, quindi non devi aggiungere nulla al tuo stack. – Ross

4

è possibile copiare le informazioni desiderato e passarlo

@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

non è a portata di mano. devo copiare tutti i dati sull'app. – jamlee

Problemi correlati